Files
pgames-manager/backend/migrations/versions/0002_publishing.py
T
mrleo1nidandClaude Opus 5.5 ac164d1782 Localization stages 2-3: drafts, publishing, translation editor
- games.main_version_id, version visibility (draft/published) and kind
  (original/translation/mod), version_history; migration 0002
- permissions translations.edit and versions.publish
- "Translate" creates a translation draft; publishing merges the changed
  languages into the main version in place (players keep their saves), the
  previous manifest goes to the history and can be restored
- translation API: overview with per-state stats, entries with filters,
  search and scene context, save, glossary, locale font, PO/CSV export/import
- translation editor page: languages and progress, lines and strings,
  filters, autosave, approve/outdated/fuzzy actions, glossary highlighting,
  "play from here" with the scene restored
- player: ?lang= and ?at= from the editor, per-locale font

(models.py and permissions.py for this landed earlier in 9ee3e1f)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 03:56:19 +03:00

56 lines
2.3 KiB
Python

"""main version, drafts, version kinds and history
Revision ID: 0002
Revises: 0001
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
revision = "0002"
down_revision = "0001"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.add_column("game_versions", sa.Column("visibility", sa.String(16), nullable=False,
server_default="published"))
op.add_column("game_versions", sa.Column("kind", sa.String(16), nullable=False,
server_default="original"))
op.execute("UPDATE game_versions SET kind = 'mod' WHERE parent_id IS NOT NULL")
op.add_column("games", sa.Column("main_version_id", sa.Integer,
sa.ForeignKey("game_versions.id", ondelete="SET NULL")))
# existing games: the oldest ready original becomes the main version
op.execute("""
UPDATE games g SET main_version_id = (
SELECT v.id FROM game_versions v
WHERE v.game_id = g.id AND v.status = 'ready' AND v.parent_id IS NULL
ORDER BY v.created_at LIMIT 1)
""")
op.create_table(
"version_history",
sa.Column("id", sa.Integer, primary_key=True),
sa.Column("version_id", sa.Integer, sa.ForeignKey("game_versions.id", ondelete="CASCADE"),
nullable=False, index=True),
sa.Column("user_id", sa.Integer, sa.ForeignKey("users.id", ondelete="SET NULL")),
sa.Column("note", sa.String(255), nullable=False, server_default=""),
sa.Column("manifest", postgresql.JSONB, nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(),
nullable=False),
)
# the stock moderator role gets the new permissions
op.execute("""
UPDATE roles SET permissions = array_cat(permissions,
ARRAY['translations.edit', 'versions.publish']::varchar[])
WHERE name = 'moderator' AND is_system
AND NOT permissions @> ARRAY['translations.edit']::varchar[]
""")
def downgrade() -> None:
op.drop_table("version_history")
op.drop_column("games", "main_version_id")
op.drop_column("game_versions", "kind")
op.drop_column("game_versions", "visibility")