"""设备档案上报 endpoint(device 表)。 POST /api/v1/device/report — 客户端上报设备当前信息,按 device_id upsert 到 device 表。 软鉴权:带合法 Bearer → 设备关联到该用户;游客态(无 token)也接受,user_id 暂空。 注意与 /api/v1/device/register(app/api/v1/device.py)区分:那个是无障碍存活注册,写 device_liveness 表、硬鉴权;本端点是设备信息档案,写 device 表、软鉴权。 """ from __future__ import annotations import logging from fastapi import APIRouter, Request from app.api.deps import DbSession, OptionalUser from app.repositories import device_profile as device_profile_repo from app.schemas.device_profile import DeviceReportOut, DeviceReportRequest logger = logging.getLogger("shagua.device_profile") router = APIRouter(prefix="/api/v1/device", tags=["device"]) def _client_ip(request: Request) -> str | None: """客户端 IP:生产经 nginx 反代优先 X-Forwarded-For 第一段,否则直连 IP。""" xff = request.headers.get("x-forwarded-for") if xff: return xff.split(",")[0].strip() return request.client.host if request.client else None @router.post("/report", response_model=DeviceReportOut, summary="上报设备信息(设备档案 upsert)") def report_device( req: DeviceReportRequest, request: Request, user: OptionalUser, db: DbSession, ) -> DeviceReportOut: device = device_profile_repo.upsert_device( db, req, user_id=user.id if user else None, last_ip=_client_ip(request), ) logger.info( "device report device_id=%s user_id=%s has_loc=%s", req.device_id, device.user_id, req.latitude is not None, ) return DeviceReportOut()