feat: Phase 0 — monorepo 骨架 + 全表迁移 + FastAPI/Next 骨架 + CI
- uv(workspace) + pnpm monorepo;docker-compose(pg+api+web) - SQLAlchemy 16 MVP 表 + Alembic 初版迁移(无漂移,users stub) - FastAPI 骨架:统一错误信封(带 request_id) + structlog + /jobs/:id + OpenAPI - Next.js 骨架:纸感主题 token + OpenAPI→TS 客户端代码生成(gen:api) - CI(ruff/mypy/pytest + pg service + alembic 漂移校验) - 四份设计规格(PRODUCT/UX/ARCHITECTURE/DEV_PLAN) + CLAUDE.md
This commit is contained in:
55
apps/api/ww_api/main.py
Normal file
55
apps/api/ww_api/main.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""FastAPI 应用入口(ARCH §7)。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from ww_db import get_sessionmaker
|
||||
from ww_shared import AppError, ErrorBody, ErrorEnvelope
|
||||
|
||||
from ww_api.logging_config import configure_logging, get_logger
|
||||
from ww_api.middleware import request_id_middleware
|
||||
from ww_api.routers import health, jobs, projects, settings_providers
|
||||
from ww_api.services.project_deps import seed_stub_user
|
||||
|
||||
configure_logging()
|
||||
log = get_logger("ww.api")
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
||||
# 幂等 seed 单用户 stub——所有 owner_id FK 依赖它(见 memory/gotchas)。
|
||||
async with get_sessionmaker()() as session:
|
||||
await seed_stub_user(session)
|
||||
yield
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
app = FastAPI(title="网文创作工作流 API", version="0.0.0", lifespan=_lifespan)
|
||||
app.middleware("http")(request_id_middleware)
|
||||
|
||||
@app.exception_handler(AppError)
|
||||
async def _app_error_handler(request: Request, exc: AppError) -> JSONResponse:
|
||||
request_id = getattr(request.state, "request_id", None)
|
||||
log.warning("app_error", code=exc.code, message=exc.message)
|
||||
envelope = ErrorEnvelope(
|
||||
error=ErrorBody(
|
||||
code=exc.code,
|
||||
message=exc.message,
|
||||
details=exc.details,
|
||||
request_id=request_id,
|
||||
)
|
||||
)
|
||||
return JSONResponse(status_code=exc.http_status, content=envelope.model_dump())
|
||||
|
||||
app.include_router(health.router)
|
||||
app.include_router(jobs.router)
|
||||
app.include_router(projects.router)
|
||||
app.include_router(settings_providers.router)
|
||||
return app
|
||||
|
||||
|
||||
app = create_app()
|
||||
Reference in New Issue
Block a user