"""Development-only token issuance. **This is not the V1 auth design.** FR-ACC-01/04/05 require 华为账号登录、手机号 验证码、双令牌与服务端可撤销的 refresh token. This endpoint exists so the vertical slice can be exercised end to end, and it refuses to run unless ``DEV_AUTH_ENABLED`` is true and the environment is local/dev. """ from __future__ import annotations from fastapi import APIRouter from apps.api.deps import IdentityServiceDep, SettingsDep from apps.api.schemas import DevTokenRequest, DevTokenResponse from packages.identity.service import DEV_PROVIDER from packages.shared.errors import AppError, ErrorCode from packages.shared.response import ok from packages.shared.security import create_access_token router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/dev-token", summary="[dev only] Issue an access token for testing") async def dev_token( payload: DevTokenRequest, settings: SettingsDep, identity: IdentityServiceDep, ) -> dict[str, object]: if not (settings.dev_auth_enabled and settings.is_local): raise AppError(ErrorCode.NOT_FOUND) user = await identity.get_or_create_by_external_identity( provider=DEV_PROVIDER, union_id=payload.device_key, register_source="dev", ) token = create_access_token( user_id=user.user_id, secret=settings.jwt_secret, algorithm=settings.jwt_algorithm, ttl_seconds=settings.jwt_access_ttl_seconds, issuer=settings.jwt_issuer, ) return ok( DevTokenResponse( access_token=token, expires_in=settings.jwt_access_ttl_seconds, user_id=str(user.user_id), ).model_dump() )