114 lines
4.3 KiB
Python
114 lines
4.3 KiB
Python
"""辰正时态 API(设计 §10)。
|
|
|
|
挂载于 /api/v1/time。事件不走 REST(走 EventStore 订阅)。路由薄层:参数校验 → 调
|
|
service → 转响应;session 由 service 自管(deps.py 惯例)。
|
|
"""
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
|
|
from app.api.v1.deps import get_current_user, get_event_store
|
|
from app.core.config import settings
|
|
from app.schemas.auth import CurrentUser
|
|
from app.schemas.time import (
|
|
AcquaintanceResponse,
|
|
AnniversaryCreateRequest,
|
|
AnniversaryResponse,
|
|
AnniversaryUpdateRequest,
|
|
SnapshotResponse,
|
|
TimeConfigResponse,
|
|
)
|
|
from app.services.time_sense import (
|
|
create_anniversary_for_active,
|
|
delete_anniversary_or_404,
|
|
get_acquaintance_for_active,
|
|
get_anniversary_or_404,
|
|
get_live_snapshot,
|
|
list_anniversaries_for_active,
|
|
update_anniversary_or_404,
|
|
)
|
|
|
|
router = APIRouter(prefix="/time", tags=["time"])
|
|
|
|
|
|
@router.get("/snapshot", response_model=SnapshotResponse)
|
|
async def get_snapshot(
|
|
request: Request, current_user: CurrentUser = Depends(get_current_user)
|
|
) -> SnapshotResponse:
|
|
"""当前 TemporalSnapshot + ModulationFactors + context_text。"""
|
|
result = await get_live_snapshot(get_event_store(request), owner_scope=current_user.owner_scope)
|
|
return SnapshotResponse(
|
|
snapshot=result.snapshot,
|
|
factors=result.factors,
|
|
context_text=result.context_text,
|
|
)
|
|
|
|
|
|
@router.get("/anniversaries", response_model=list[AnniversaryResponse])
|
|
async def list_anniversaries_api(
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> list[AnniversaryResponse]:
|
|
items = await list_anniversaries_for_active(owner_scope=current_user.owner_scope)
|
|
return [AnniversaryResponse.model_validate(a) for a in items]
|
|
|
|
|
|
@router.post("/anniversaries", response_model=AnniversaryResponse, status_code=201)
|
|
async def create_anniversary_api(
|
|
payload: AnniversaryCreateRequest, current_user: CurrentUser = Depends(get_current_user)
|
|
) -> AnniversaryResponse:
|
|
created = await create_anniversary_for_active(payload, owner_scope=current_user.owner_scope)
|
|
return AnniversaryResponse.model_validate(created)
|
|
|
|
|
|
@router.get("/anniversaries/{anniv_id}", response_model=AnniversaryResponse)
|
|
async def get_anniversary_api(
|
|
anniv_id: str, current_user: CurrentUser = Depends(get_current_user)
|
|
) -> AnniversaryResponse:
|
|
return AnniversaryResponse.model_validate(
|
|
await get_anniversary_or_404(anniv_id, owner_scope=current_user.owner_scope)
|
|
)
|
|
|
|
|
|
@router.patch("/anniversaries/{anniv_id}", response_model=AnniversaryResponse)
|
|
async def update_anniversary_api(
|
|
anniv_id: str,
|
|
payload: AnniversaryUpdateRequest,
|
|
current_user: CurrentUser = Depends(get_current_user),
|
|
) -> AnniversaryResponse:
|
|
return AnniversaryResponse.model_validate(
|
|
await update_anniversary_or_404(anniv_id, payload, owner_scope=current_user.owner_scope)
|
|
)
|
|
|
|
|
|
@router.delete("/anniversaries/{anniv_id}", status_code=204)
|
|
async def delete_anniversary_api(
|
|
anniv_id: str, current_user: CurrentUser = Depends(get_current_user)
|
|
) -> None:
|
|
await delete_anniversary_or_404(anniv_id, owner_scope=current_user.owner_scope)
|
|
|
|
|
|
@router.get("/acquaintance", response_model=AcquaintanceResponse)
|
|
async def get_acquaintance_api(
|
|
request: Request, current_user: CurrentUser = Depends(get_current_user)
|
|
) -> AcquaintanceResponse:
|
|
acq = await get_acquaintance_for_active(
|
|
get_event_store(request), owner_scope=current_user.owner_scope
|
|
)
|
|
return AcquaintanceResponse(total_days=acq.total_days, natural_language=acq.natural_language)
|
|
|
|
|
|
@router.get("/config", response_model=TimeConfigResponse)
|
|
async def get_time_config_api(
|
|
current_user: CurrentUser = Depends(get_current_user), # noqa: ARG001
|
|
) -> TimeConfigResponse:
|
|
return TimeConfigResponse(
|
|
user_timezone=settings.user_timezone,
|
|
home_timezone=settings.home_timezone,
|
|
default_city=settings.default_city,
|
|
offline_active_minutes=settings.offline_active_minutes,
|
|
offline_short_absence_minutes=settings.offline_short_absence_minutes,
|
|
offline_long_absence_minutes=settings.offline_long_absence_minutes,
|
|
offline_reunion_impact_minutes=settings.offline_reunion_impact_minutes,
|
|
care_enabled=settings.care_enabled,
|
|
jetlag_threshold_minutes=settings.jetlag_threshold_minutes,
|
|
)
|