"""QR Menu & QR Ordering APIs — Phase 12.2.""" from __future__ import annotations from uuid import UUID from fastapi import APIRouter, Depends, status from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_db, get_pagination, require_tenant from app.core.security import get_current_user from app.schemas.qr import ( CartCreate, CartLineCreate, CartLineRead, CartRead, QrCodeCreate, QrCodeRead, QrMenuSessionCreate, QrMenuSessionRead, QrOrderingSessionCreate, QrOrderingSessionRead, ) from app.services.qr import ( CartLineService, CartService, QrCodeService, QrMenuSessionService, QrOrderingSessionService, ) from shared.pagination import PaginationParams from shared.security import CurrentUser qr_codes_router = APIRouter() qr_menu_sessions_router = APIRouter() qr_ordering_sessions_router = APIRouter() carts_router = APIRouter() cart_lines_router = APIRouter() @qr_codes_router.post("", response_model=QrCodeRead, status_code=status.HTTP_201_CREATED) async def create_qr_code( body: QrCodeCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await QrCodeService(db).create(tenant_id, body, actor=user) @qr_codes_router.get("", response_model=list[QrCodeRead]) async def list_qr_codes( tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrCodeService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size) @qr_codes_router.get("/by-token/{token}", response_model=QrCodeRead) async def get_qr_code_by_token( token: str, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrCodeService(db).get_by_token(tenant_id, token) @qr_codes_router.get("/{qr_code_id}", response_model=QrCodeRead) async def get_qr_code( qr_code_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrCodeService(db).get(tenant_id, qr_code_id) @qr_menu_sessions_router.post("", response_model=QrMenuSessionRead, status_code=status.HTTP_201_CREATED) async def create_qr_menu_session( body: QrMenuSessionCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await QrMenuSessionService(db).create(tenant_id, body, actor=user) @qr_menu_sessions_router.get("", response_model=list[QrMenuSessionRead]) async def list_qr_menu_sessions( tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrMenuSessionService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size) @qr_menu_sessions_router.get("/by-token/{token}", response_model=QrMenuSessionRead) async def get_qr_menu_session_by_token( token: str, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrMenuSessionService(db).get_by_token(tenant_id, token) @qr_menu_sessions_router.get("/{session_id}", response_model=QrMenuSessionRead) async def get_qr_menu_session( session_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrMenuSessionService(db).get(tenant_id, session_id) @qr_ordering_sessions_router.post("", response_model=QrOrderingSessionRead, status_code=status.HTTP_201_CREATED) async def create_qr_ordering_session( body: QrOrderingSessionCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await QrOrderingSessionService(db).create(tenant_id, body, actor=user) @qr_ordering_sessions_router.get("", response_model=list[QrOrderingSessionRead]) async def list_qr_ordering_sessions( tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrOrderingSessionService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size) @qr_ordering_sessions_router.get("/{session_id}", response_model=QrOrderingSessionRead) async def get_qr_ordering_session( session_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await QrOrderingSessionService(db).get(tenant_id, session_id) @qr_ordering_sessions_router.post("/{session_id}/submit", response_model=QrOrderingSessionRead) async def submit_qr_ordering_session( session_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await QrOrderingSessionService(db).submit(tenant_id, session_id, actor=user) @carts_router.post("", response_model=CartRead, status_code=status.HTTP_201_CREATED) async def create_cart( body: CartCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await CartService(db).create(tenant_id, body, actor=user) @carts_router.get("", response_model=list[CartRead]) async def list_carts( tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await CartService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size) @carts_router.get("/{cart_id}", response_model=CartRead) async def get_cart( cart_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await CartService(db).get(tenant_id, cart_id) @cart_lines_router.post("", response_model=CartLineRead, status_code=status.HTTP_201_CREATED) async def create_cart_line( body: CartLineCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user), ): return await CartLineService(db).add(tenant_id, body, actor=user) @cart_lines_router.get("", response_model=list[CartLineRead]) async def list_cart_lines( tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user), ): return await CartLineService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)