Files
server-core/app/main.py
T
Pine 4602c8dac7 feat(hall): 大厅/社区接口 + 任务报名(register)模式
- 新增 rbac_hall.py:/hall/*(overview/任务列表详情/发布任务/报名/接单列表/
  人才列表详情/档案维护/岗位发布详情投递/服务发布列表详情编辑询单)+
  /community/*(Hub/帖子/发帖/点赞/评论/载体列表详情/关注/入驻)
- TaskService.register/register_select:报名即占位状态机(复用 can_accept 资格判定,
  register_quota 限额、去重、选定转 assigned,任务保持 published)
- can_accept 修复 actor 不在 users 表时 full=None 崩溃;写权限按叠加制 capabilities 判定
- 路由挂载 app/main.py(/hall + /community)
2026-08-31 22:20:16 +08:00

110 lines
3.6 KiB
Python

# -*- coding: utf-8 -*-
"""FastAPI 应用入口(接口层组装)。
启动方式(项目根目录):
uv run uvicorn app.main:app --host 127.0.0.1 --port 8090
或使用脚本:``uv run python -m app``
"""
from __future__ import annotations
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app import config
from app.infrastructure.repositories import Database
from app.api.routers import agents as agents_router
from app.api.routers import auth as auth_router
from app.api.routers import bootstrap as bootstrap_router
from app.api.routers import rbac_admin as rbac_admin_router
from app.api.routers import rbac_enterprise as rbac_enterprise_router
from app.api.routers import rbac_hall as rbac_hall_router
from app.api.routers import rbac_opc as rbac_opc_router
from app.api.routers import rbac_operator as rbac_operator_router
from app.api.routers import rbac_org as rbac_org_router
from app.api.routers import rbac_ecosystem as rbac_ecosystem_router
from app.api.routers import rbac_portals as rbac_portals_router
from app.api.routers import templates as templates_router
from app.api.routers import relay as relay_router
from app.pay import routers as pay_router
APP_NAME = "云超服Agents 演示后端"
@asynccontextmanager
async def lifespan(app: FastAPI):
"""启动时初始化数据库(建表 + 幂等种子)。
若 ``app.state.db`` 已由外部注入(如测试夹具),则直接复用,
不重新创建,避免覆盖调用方准备的数据库实例。
"""
db = getattr(app.state, "db", None)
if db is None:
db = Database()
await db.initialize()
app.state.db = db
yield
if db is not None and db._owns_session:
await db.close()
# 释放引擎连接池,避免连接残留导致下次启动 initialize() 被锁挂起/连接泄漏
engine = getattr(db, "_engine", None)
if engine is not None:
try:
await engine.dispose()
except Exception: # noqa: BLE001
pass
app = FastAPI(
title=APP_NAME,
description=(
"云超服核心服务端:身份/平台 API + 培训子应用(/api/*),统一对外 opc.pinesound.cn。"
"异步四层架构(接口/业务/领域/基础设施)。"
),
version="0.1.0",
lifespan=lifespan,
)
# 演示服务允许任意来源(实际生产由主后端网关收敛)。
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth_router.router)
app.include_router(agents_router.router)
app.include_router(templates_router.router)
app.include_router(bootstrap_router.router)
app.include_router(rbac_admin_router.router)
app.include_router(rbac_enterprise_router.router)
app.include_router(rbac_opc_router.router)
app.include_router(rbac_operator_router.router)
app.include_router(rbac_org_router.router)
app.include_router(rbac_portals_router.router)
app.include_router(rbac_ecosystem_router.router)
app.include_router(rbac_hall_router.router)
app.include_router(rbac_hall_router.community_router)
app.include_router(relay_router.router)
app.include_router(pay_router.router)
@app.get("/health", tags=["meta"], summary="健康检查")
async def health():
return {
"status": "ok",
"service": "pineagents-demo-server",
"auth_enabled": config.AUTH_ENABLED,
}
@app.get("/", tags=["meta"], include_in_schema=False)
async def root():
return {
"service": APP_NAME,
"docs": "/docs",
"health": "/health",
}