refactor: derive Permission type from generated OpenAPI schema

Issue #3: The frontend Permission enum was manually duplicated from
the backend. While full generation isn't practical, this change
ties the frontend constants to the generated OpenAPI types for
compile-time validation.

Changes:
- Update ConstantsResponse schema to use actual Permission/InviteStatus
  enums (enables OpenAPI to include enum values)
- Import enums in schemas.py (no circular dependency issue)
- Update auth-context.tsx to derive PermissionType from generated schema
- Update meta route to return enum instances instead of string values
- Permission values are now type-checked against the OpenAPI schema

If a permission is added to the backend but not to the frontend's
Permission object, TypeScript will fail to compile. This provides
a safety net without requiring a complex build-time generation step.
This commit is contained in:
counterweight 2025-12-21 23:55:47 +01:00
parent 21698203fe
commit 09560296aa
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
4 changed files with 34 additions and 13 deletions

View file

@ -12,7 +12,7 @@ router = APIRouter(prefix="/api/meta", tags=["meta"])
async def get_constants() -> ConstantsResponse:
"""Get shared constants for frontend/backend synchronization."""
return ConstantsResponse(
permissions=[p.value for p in Permission],
permissions=list(Permission),
roles=[ROLE_ADMIN, ROLE_REGULAR],
invite_statuses=[s.value for s in InviteStatus],
invite_statuses=list(InviteStatus),
)

View file

@ -5,6 +5,7 @@ from typing import Generic, TypeVar
from pydantic import BaseModel, EmailStr, field_validator
from models import InviteStatus, Permission
from shared_constants import NOTE_MAX_LENGTH
@ -281,8 +282,12 @@ class RandomNumberOutcomeResponse(BaseModel):
class ConstantsResponse(BaseModel):
"""Response model for shared constants."""
"""Response model for shared constants.
permissions: list[str]
Note: Using actual enum types ensures OpenAPI schema includes enum values,
allowing frontend type generation to produce matching TypeScript enums.
"""
permissions: list[Permission]
roles: list[str]
invite_statuses: list[str]
invite_statuses: list[InviteStatus]