Files
cjfx/backend/app/main.py

108 lines
2.9 KiB
Python
Raw Normal View History

2026-03-20 22:59:54 +08:00
from __future__ import annotations
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi import Query
from fastapi.middleware.cors import CORSMiddleware
from app.models import (
Account,
ClsNewsDocument,
DailyInputDocument,
DailyInputUpsertPayload,
ReportDocument,
ReportListItem,
)
from app.services.domain import (
get_accounts,
get_cls_news,
list_reports,
load_daily_input,
load_report,
normalize_daily_input,
normalize_date,
refresh_cls_news,
save_daily_input,
save_report,
seed_demo_content,
generate_report,
)
from app.services.storage import init_database
@asynccontextmanager
async def lifespan(_app: FastAPI):
init_database()
seed_demo_content()
yield
app = FastAPI(
title="WeChat Finance Daily",
version="0.1.0",
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/api/health")
def health() -> dict[str, str]:
return {"status": "ok"}
@app.get("/api/accounts", response_model=list[Account])
def accounts() -> list[Account]:
return get_accounts()
@app.get("/api/daily-inputs/{date_str}", response_model=DailyInputDocument)
def get_daily_inputs(date_str: str) -> DailyInputDocument:
return load_daily_input(normalize_date(date_str))
@app.put("/api/daily-inputs/{date_str}", response_model=DailyInputDocument)
def put_daily_inputs(date_str: str, payload: DailyInputUpsertPayload) -> DailyInputDocument:
document = normalize_daily_input(normalize_date(date_str), payload)
return save_daily_input(document)
@app.post("/api/reports/{date_str}/generate", response_model=ReportDocument)
def generate_daily_report(date_str: str) -> ReportDocument:
normalized_date = normalize_date(date_str)
input_document = load_daily_input(normalized_date)
report = generate_report(normalized_date, input_document)
return save_report(report)
@app.get("/api/reports", response_model=list[ReportListItem])
def get_report_list() -> list[ReportListItem]:
return list_reports()
@app.get("/api/opinions/{date_str}", response_model=ReportDocument)
def get_opinion_report(date_str: str) -> ReportDocument:
normalized_date = normalize_date(date_str)
existing = load_report(normalized_date)
if existing is not None:
return existing
report = generate_report(normalized_date, load_daily_input(normalized_date))
return save_report(report)
@app.get("/api/cls-news", response_model=ClsNewsDocument)
def get_cls_news_payload(date: str | None = Query(default=None)) -> ClsNewsDocument:
return get_cls_news(date)
@app.post("/api/cls-news/refresh", response_model=ClsNewsDocument)
def refresh_cls_news_payload(date: str | None = Query(default=None)) -> ClsNewsDocument:
return refresh_cls_news(date)