feat: scaffold FastAPI backend and Vue 3 frontend
Backend (backend/):
- FastAPI app with layered app/{api,core,crud,db,models,schemas} structure
- TiDB connection via SQLAlchemy. The URL is built with URL.create rather
than string formatting: the password contains '@', which would otherwise be
parsed as the user/host separator and silently truncate the credential.
- Alembic environment wired to Base.metadata and the app settings, so
backend/.env stays the single source of truth for credentials
- /api/health endpoint reporting database reachability
- models/ and crud/ are intentionally empty: no model classes are defined and
no tables are created, at import time or otherwise
Frontend (frontend/):
- Vue 3 + Vite + TypeScript scaffold (create-vue, --bare)
- axios instance with a normalized error shape
- vue-router with a home route and a catch-all 404
- pinia + pinia-plugin-persistedstate; the app store persists selected keys
- Element Plus with its icons registered globally
- dev proxy forwards /api to the FastAPI service on port 8000
The database paper_doc was created in TiDB out of band; no table exists yet.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Route modules, one per resource. Each exposes ``router``."""
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Health endpoint — also the smoke test for database connectivity."""
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.db.session import get_db
|
||||
from app.schemas.health import HealthResponse
|
||||
|
||||
router = APIRouter(tags=["health"])
|
||||
|
||||
|
||||
@router.get("/health", response_model=HealthResponse, summary="Liveness and database probe")
|
||||
def health(db: Session = Depends(get_db)) -> HealthResponse:
|
||||
"""Report process liveness and whether TiDB answered a trivial query.
|
||||
|
||||
A database failure is reported in the body instead of raising, so that the
|
||||
endpoint stays useful for diagnosing an unreachable database.
|
||||
"""
|
||||
settings = get_settings()
|
||||
try:
|
||||
db.execute(text("SELECT 1"))
|
||||
database = "ok"
|
||||
except Exception: # noqa: BLE001 - the failure mode is the payload
|
||||
database = "unavailable"
|
||||
|
||||
return HealthResponse(
|
||||
status="ok" if database == "ok" else "degraded",
|
||||
app=settings.app_name,
|
||||
database=database,
|
||||
database_target=settings.safe_database_url,
|
||||
)
|
||||
Reference in New Issue
Block a user