Files
pgames-manager/backend/app/schemas.py
T
mrleo1nidandClaude Sonnet 5.5 a1f5ef8e2d
CI / frontend (push) Failing after 20s
CI / backend (push) Successful in 51s
feat: language dropdowns on versions and on the game page
- Each ready version gets a "Languages" dropdown next to Play: the original language
  first, then translations with their completion; picking one starts the version in
  that language
- The game header gets the same dropdown, aggregated over published, ready versions.
  Each language points at the version that has it best (most complete, the main
  version on a tie); an original language counts as complete
- The old row of language tags linking to the translation editor is replaced
- Backend: versions carry source_name (the name of the original language)
- pages/languages.ts holds the aggregation logic with tests; LanguageMenu closes on
  outside click and Escape

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 18:41:26 +03:00

156 lines
2.9 KiB
Python

from datetime import datetime
from typing import Any
from pydantic import BaseModel, ConfigDict, Field
class ORM(BaseModel):
model_config = ConfigDict(from_attributes=True)
class LoginIn(BaseModel):
username: str
password: str
class ChangeCredentialsIn(BaseModel):
current_password: str
new_password: str
new_username: str | None = None
class RoleOut(ORM):
id: int
name: str
permissions: list[str]
is_system: bool
class RoleIn(BaseModel):
name: str = Field(min_length=1, max_length=64)
permissions: list[str]
class UserOut(ORM):
id: int
username: str
role: RoleOut
is_active: bool
must_change_password: bool
must_change_username: bool
created_at: datetime
class MeOut(UserOut):
permissions: list[str]
class UserCreateIn(BaseModel):
username: str
role_id: int
class UserUpdateIn(BaseModel):
role_id: int | None = None
is_active: bool | None = None
class UserWithPasswordOut(BaseModel):
user: UserOut
password: str
class OwnerOut(ORM):
id: int
username: str
class VersionOut(ORM):
revision_id: str | None = None
base_revision_id: str | None = None
id: int
game_id: int
parent_id: int | None
owner: OwnerOut | None
name: str
description: str
status: str
progress: str
size_bytes: int
created_at: datetime
visibility: str = "published"
kind: str = "original"
# from the version's game.json (filled by the game detail endpoint)
source_lang: str | None = None
source_name: str | None = None
languages: list[dict[str, Any]] = []
class VersionDetailOut(VersionOut):
report: dict[str, Any] | None
class GameOut(ORM):
id: int
title: str
description: str
tags: list[str]
engine: str
cover_hash: str | None
created_at: datetime
main_version_id: int | None = None
# version counts visible to the requesting user (filled by the list endpoint)
ready_versions: int = 0
pending_versions: int = 0
failed_versions: int = 0
class GameDetailOut(GameOut):
versions: list[VersionOut]
class GameIn(BaseModel):
title: str = Field(min_length=1, max_length=255)
description: str = ""
tags: list[str] = []
class GameUpdateIn(BaseModel):
title: str | None = Field(default=None, min_length=1, max_length=255)
description: str | None = None
tags: list[str] | None = None
class VersionIn(BaseModel):
name: str = Field(min_length=1, max_length=255)
description: str = ""
class ForkIn(VersionIn):
kind: str = Field(default="mod", pattern="^(mod|translation)$")
class PublishIn(BaseModel):
make_main: bool = False
class HistoryOut(ORM):
id: int
note: str
created_at: datetime
class SaveIn(BaseModel):
title: str = ""
data: dict[str, Any]
class SaveOut(ORM):
slot: str
title: str
updated_at: datetime
class SaveDetailOut(SaveOut):
data: dict[str, Any]