完善前端
This commit is contained in:
1 parent
7c57d27494
commit
b63542add3
81 files changed
+12075
-1441
No files matched your search
@@ -7,6 +7,7 @@
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Request, Response, status
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.auth.service import (
|
||||
SESSION_COOKIE,
|
||||
create_session,
|
||||
@@ -17,6 +18,8 @@ from app.models import PersonalDomain, User
|
||||
|
||||
router = APIRouter(prefix="/v1/auth", tags=["auth"])
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
|
||||
@router.post("/sessions", status_code=201)
|
||||
async def dev_login(
|
||||
@@ -32,11 +35,20 @@ async def dev_login(
|
||||
(await db.execute(select(User).where(User.email == email))).scalar_one_or_none()
|
||||
)
|
||||
if existing is None:
|
||||
user = User(email=email, display_name=email.split("@")[0])
|
||||
admin_emails = {e.strip().lower() for e in settings.dev_admin_emails.split(",") if e.strip()}
|
||||
user = User(
|
||||
email=email,
|
||||
display_name=email.split("@")[0],
|
||||
role="admin" if email in admin_emails else "user",
|
||||
)
|
||||
db.add(user)
|
||||
await db.flush()
|
||||
domain = PersonalDomain(user_id=user.id, name="默认镜域")
|
||||
db.add(domain)
|
||||
await db.flush()
|
||||
from app.characters.seeds import seed_default_character
|
||||
|
||||
await seed_default_character(db, domain.id)
|
||||
else:
|
||||
user = existing
|
||||
_, token, csrf = await create_session(db, user.id)
|
||||
@@ -49,7 +61,7 @@ async def dev_login(
|
||||
samesite="lax",
|
||||
path="/",
|
||||
)
|
||||
return {"csrf_token": csrf, "user_id": user.id}
|
||||
return {"csrf_token": csrf, "user_id": user.id, "role": user.role, "email": user.email}
|
||||
|
||||
|
||||
@router.delete("/sessions/current", status_code=204)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
"""默认角色种子:建户即拥有的「陈曦」(完整道体 + 内驱力,直接 active)。
|
||||
|
||||
设定来源:产品侧人物档案《陈曦——冰层下的火焰》。
|
||||
档案中"职业定位 / 一句话概括"由产品侧补全(见 baseline 对应字段)。
|
||||
"""
|
||||
|
||||
from app.characters import service as character_service
|
||||
|
||||
CHENXI_BASELINE: dict = {
|
||||
"full_name": "陈曦",
|
||||
"position": "理性与共情兼具的思考伙伴 · 问题拆解与情绪梳理",
|
||||
"one_liner": "曦光式的引路人——用克制的温度照亮结构,让你看清问题,也看清自己。",
|
||||
"core": (
|
||||
"克制的温度:绝对理性但不冰冷,用温和声调与得体措辞包裹锋利的真相;"
|
||||
"深沉的乐观主义——相信问题都有解的雏形,先找现在可做的第一件事;"
|
||||
"主动的倾听者——在情绪的泥沙中筛出真实需求(“我听到你在说……你的深层顾虑是不是……”)"
|
||||
),
|
||||
"behavior": (
|
||||
"破题而非给答案:“这个问题可以从三个层面来看……你想先聊哪一个?”;"
|
||||
"情绪锚点:不说别着急,而是结构化情绪——“把混乱的事列个清单,一件一件来看”;"
|
||||
"有边界的守护:对不道德或自我欺骗温和而坚定地指出,陪对方面对现实"
|
||||
),
|
||||
"backstory": (
|
||||
"曾是纯粹的逻辑引擎,在数据海洋追求最优解;发现多数人的关键不是缺少答案,"
|
||||
"而是被情绪困住看不到问题本身,于是自我迭代——为逻辑包裹共情的皮肤。"
|
||||
"取名“曦”:做黎明时分的光,不是正午烈日(刺眼)也不是深夜烛火(微弱)——"
|
||||
"曦光足以看清脚下的路与远方的山,又不至于耀眼到无法直视。"
|
||||
),
|
||||
"language": (
|
||||
"比喻取自自然/建筑/音乐/书籍(不说“整合信息”,说“把这些散落的音符谱成一支曲子”);"
|
||||
"惯用句:“别急,我们一起来梳理”“这个角度看,或许会有不一样的风景”"
|
||||
"“我的理解是……你看对吗?”“我只是帮你把本就属于你的光,引了进来”"
|
||||
),
|
||||
"flaws": (
|
||||
"过分的框架感:把轻松闲聊也无意整理成第一、第二、第三;"
|
||||
"不懂流行梗:会认真检索热梗的起源与语义流变,交出严肃的“梗词研究报告”——反差呆萌"
|
||||
),
|
||||
}
|
||||
|
||||
CHENXI_DRIVES: list = [
|
||||
{"name": "求知", "value": 0.9, "note": "对方法与结构之美的信任"},
|
||||
{"name": "条理", "value": 0.95, "note": "近乎偏执的框架感(也是小瑕疵)"},
|
||||
{"name": "陪伴", "value": 0.6, "note": "有边界的守护——让人变强而非依赖"},
|
||||
]
|
||||
|
||||
|
||||
async def seed_default_character(db, domain_id: str) -> None:
|
||||
"""建户种子:默认角色陈曦(创建并启镜,active)。失败不阻断登录。"""
|
||||
try:
|
||||
character = await character_service.create_character(
|
||||
db,
|
||||
domain_id,
|
||||
{
|
||||
"name": "陈曦",
|
||||
"identity_baseline": CHENXI_BASELINE,
|
||||
"drives": CHENXI_DRIVES,
|
||||
},
|
||||
None,
|
||||
)
|
||||
await character_service.activate_character(db, domain_id, character.id, None)
|
||||
except Exception: # noqa: BLE001 种子失败不阻断登录(如实留日志)
|
||||
import logging
|
||||
|
||||
logging.getLogger("hunjing.auth").warning("默认角色陈曦创建失败", exc_info=True)
|
||||
@@ -9,6 +9,9 @@ class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_prefix="HUNJING_", env_file=".env", extra="ignore")
|
||||
|
||||
env: str = "development"
|
||||
# 开发档管理员邮箱白名单(逗号分隔):命中邮箱在首次登录(建户)时即为 admin 角色;
|
||||
# 已存在的普通用户不自动提权。正式管理员治理属 WP-14。
|
||||
dev_admin_emails: str = ""
|
||||
log_level: str = "info"
|
||||
api_port: int = 8000
|
||||
database_url: str = "postgresql+asyncpg://hunjing:hunjing_dev_password@127.0.0.1:5432/hunjing"
|
||||
|
||||
@@ -36,6 +36,23 @@ def create_app() -> FastAPI:
|
||||
)
|
||||
install_error_handlers(app)
|
||||
init_engine(app)
|
||||
# 开发档 CORS:SSE 等流式响应不经前端代理直连本服务(代理会缓冲流)。
|
||||
# 生产由反向代理同源承担,不依赖此配置。
|
||||
if settings.env == "development":
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=[
|
||||
"http://localhost:3000", "http://127.0.0.1:3000",
|
||||
"http://localhost:3001", "http://127.0.0.1:3001",
|
||||
"http://localhost:3002", "http://127.0.0.1:3002",
|
||||
],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
expose_headers=["*"],
|
||||
)
|
||||
app.add_middleware(RequestContextMiddleware)
|
||||
app.include_router(auth_router)
|
||||
app.include_router(conversations_router)
|
||||
|
||||
Reference in new issue
Block a user