hku-class/backend/app/main.py
2026-05-01 21:52:27 +08:00

79 lines
2.3 KiB
Python

import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.api import auth, users, classes, directory, timeline, schedule, upload, announcements, resources, notifications, votes, assignments, reading, fund
logging.basicConfig(
level=logging.DEBUG if settings.debug else logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger(__name__)
async def ensure_super_admin():
"""Seed super admin on first run."""
from sqlalchemy import select
from app.db.database import async_session
from app.db.models import User
from app.core.auth import hash_password
async with async_session() as db:
result = await db.execute(select(User).where(User.role == "super_admin"))
if result.scalar_one_or_none() is None:
admin = User(
email=settings.super_admin_email,
password_hash=hash_password(settings.super_admin_password),
name="Super Admin",
role="super_admin",
status="approved",
)
db.add(admin)
await db.commit()
logger.info("Super admin seeded: %s", settings.super_admin_email)
@asynccontextmanager
async def lifespan(app: FastAPI):
await ensure_super_admin()
yield
app = FastAPI(
title="HKU ICB",
description="HKU ICB Graduate Class Resource Platform",
version="1.0.0",
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=[settings.frontend_url, "http://localhost:3001", "http://192.168.31.172:3001"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(classes.router)
app.include_router(directory.router)
app.include_router(timeline.router)
app.include_router(schedule.router)
app.include_router(upload.router)
app.include_router(announcements.router)
app.include_router(resources.router)
app.include_router(notifications.router)
app.include_router(votes.router)
app.include_router(assignments.router)
app.include_router(reading.router)
app.include_router(fund.router)
@app.get("/api/health")
async def health():
return {"status": "ok", "service": "classhub"}