Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling. Co-authored-by: Cursor <cursoragent@cursor.com>
208 lines
7.3 KiB
Python
208 lines
7.3 KiB
Python
"""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)
|