refactor: improve db ops visibility and split runtime helpers
This commit is contained in:
110
backend/app/ledger_runtime.py
Normal file
110
backend/app/ledger_runtime.py
Normal file
@@ -0,0 +1,110 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import HTTPException
|
||||
from fastapi.responses import FileResponse, Response
|
||||
|
||||
|
||||
BUSINESS_LEDGER_DEFAULT_SOURCE_KEY = "business_ledger_default"
|
||||
|
||||
|
||||
def sync_default_business_ledger_source(cur, incoming_files_dir: Path, served_dir: Path) -> None:
|
||||
cur.execute("SELECT to_regclass('public.integration_binary_sources') IS NOT NULL AS table_exists")
|
||||
row = cur.fetchone()
|
||||
table_exists = bool(row["table_exists"]) if row is not None else False
|
||||
if not table_exists:
|
||||
return
|
||||
|
||||
business_dashboard_dir = incoming_files_dir / "사업관리대장"
|
||||
business_ledger_served_dir = served_dir / "ledger"
|
||||
candidates = [
|
||||
business_ledger_served_dir / "사업관리대장-1.xlsx",
|
||||
business_dashboard_dir / "사업관리대장-1.xlsx",
|
||||
business_dashboard_dir / "사업관리 대장-1.xlsx",
|
||||
business_dashboard_dir / "사업관리대장.xlsx",
|
||||
business_dashboard_dir / "사업관리 대장.xlsx",
|
||||
]
|
||||
source_path = next((candidate for candidate in candidates if candidate.exists()), None)
|
||||
if source_path is None:
|
||||
return
|
||||
|
||||
content = source_path.read_bytes()
|
||||
content_sha256 = hashlib.sha256(content).hexdigest()
|
||||
meta_json = {
|
||||
"byte_size": len(content),
|
||||
"source_path": str(source_path),
|
||||
"synced_from": "startup",
|
||||
}
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO integration_binary_sources (
|
||||
source_key, source_name, filename, mime_type, content, content_sha256, meta_json, imported_at
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s::jsonb, NOW())
|
||||
ON CONFLICT (source_key) DO UPDATE
|
||||
SET source_name = EXCLUDED.source_name,
|
||||
filename = EXCLUDED.filename,
|
||||
mime_type = EXCLUDED.mime_type,
|
||||
content = EXCLUDED.content,
|
||||
content_sha256 = EXCLUDED.content_sha256,
|
||||
meta_json = EXCLUDED.meta_json,
|
||||
imported_at = NOW()
|
||||
WHERE integration_binary_sources.content_sha256 IS DISTINCT FROM EXCLUDED.content_sha256
|
||||
OR integration_binary_sources.filename IS DISTINCT FROM EXCLUDED.filename
|
||||
OR integration_binary_sources.mime_type IS DISTINCT FROM EXCLUDED.mime_type
|
||||
OR integration_binary_sources.meta_json IS DISTINCT FROM EXCLUDED.meta_json
|
||||
""",
|
||||
(
|
||||
BUSINESS_LEDGER_DEFAULT_SOURCE_KEY,
|
||||
"사업관리대장 기본 원본",
|
||||
source_path.name,
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
content,
|
||||
content_sha256,
|
||||
json.dumps(meta_json, ensure_ascii=False),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def build_business_ledger_default_response(cur) -> Response:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT filename, mime_type, content
|
||||
FROM integration_binary_sources
|
||||
WHERE source_key = %s
|
||||
ORDER BY imported_at DESC
|
||||
LIMIT 1
|
||||
""",
|
||||
(BUSINESS_LEDGER_DEFAULT_SOURCE_KEY,),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
if not row:
|
||||
raise HTTPException(status_code=404, detail="Business ledger default source not found.")
|
||||
|
||||
filename = str(row["filename"] or "사업관리대장-1.xlsx")
|
||||
headers = {
|
||||
"Content-Disposition": 'inline; filename="business-ledger-default.xlsx"',
|
||||
"X-Source-Filename": "business-ledger-default.xlsx",
|
||||
"X-Original-Filename": filename,
|
||||
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
|
||||
"Pragma": "no-cache",
|
||||
}
|
||||
return Response(
|
||||
content=bytes(row["content"]),
|
||||
media_type=str(
|
||||
row["mime_type"] or "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
),
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
|
||||
def build_ledger_index_response(ledger_index_path: Path) -> FileResponse:
|
||||
if not ledger_index_path.exists():
|
||||
raise HTTPException(status_code=404, detail="Business ledger integration file not found.")
|
||||
response = FileResponse(ledger_index_path)
|
||||
response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
|
||||
response.headers["Pragma"] = "no-cache"
|
||||
return response
|
||||
Reference in New Issue
Block a user