All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m5s
Combines shared, blog, market, cart, events, federation, and account into a single repository. Eliminates submodule sync, sibling model copying at build time, and per-app CI orchestration. Changes: - Remove per-app .git, .gitmodules, .gitea, submodule shared/ dirs - Remove stale sibling model copies from each app - Update all 6 Dockerfiles for monorepo build context (root = .) - Add build directives to docker-compose.yml - Add single .gitea/workflows/ci.yml with change detection - Add .dockerignore for monorepo build context - Create __init__.py for federation and account (cross-app imports)
99 lines
4.4 KiB
Python
99 lines
4.4 KiB
Python
"""add glue layer tables (container_relations + menu_nodes)
|
|
|
|
Revision ID: i9g7d3e5f6
|
|
Revises: h8f6c2d4e5a9
|
|
Create Date: 2026-02-11
|
|
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
revision = 'i9g7d3e5f6'
|
|
down_revision = 'h8f6c2d4e5a9'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# --- container_relations ---
|
|
op.create_table(
|
|
'container_relations',
|
|
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
|
sa.Column('parent_type', sa.String(32), nullable=False),
|
|
sa.Column('parent_id', sa.Integer(), nullable=False),
|
|
sa.Column('child_type', sa.String(32), nullable=False),
|
|
sa.Column('child_id', sa.Integer(), nullable=False),
|
|
sa.Column('sort_order', sa.Integer(), nullable=False, server_default='0'),
|
|
sa.Column('label', sa.String(255), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
|
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.UniqueConstraint(
|
|
'parent_type', 'parent_id', 'child_type', 'child_id',
|
|
name='uq_container_relations_parent_child',
|
|
),
|
|
)
|
|
op.create_index('ix_container_relations_parent', 'container_relations', ['parent_type', 'parent_id'])
|
|
op.create_index('ix_container_relations_child', 'container_relations', ['child_type', 'child_id'])
|
|
|
|
# --- menu_nodes ---
|
|
op.create_table(
|
|
'menu_nodes',
|
|
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
|
sa.Column('container_type', sa.String(32), nullable=False),
|
|
sa.Column('container_id', sa.Integer(), nullable=False),
|
|
sa.Column('parent_id', sa.Integer(), nullable=True),
|
|
sa.Column('sort_order', sa.Integer(), nullable=False, server_default='0'),
|
|
sa.Column('depth', sa.Integer(), nullable=False, server_default='0'),
|
|
sa.Column('label', sa.String(255), nullable=False),
|
|
sa.Column('slug', sa.String(255), nullable=True),
|
|
sa.Column('href', sa.String(1024), nullable=True),
|
|
sa.Column('icon', sa.String(64), nullable=True),
|
|
sa.Column('feature_image', sa.Text(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
|
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['parent_id'], ['menu_nodes.id'], ondelete='SET NULL'),
|
|
)
|
|
op.create_index('ix_menu_nodes_container', 'menu_nodes', ['container_type', 'container_id'])
|
|
op.create_index('ix_menu_nodes_parent_id', 'menu_nodes', ['parent_id'])
|
|
|
|
# --- Backfill container_relations from existing container-pattern tables ---
|
|
op.execute("""
|
|
INSERT INTO container_relations (parent_type, parent_id, child_type, child_id, sort_order)
|
|
SELECT 'page', container_id, 'calendar', id, 0
|
|
FROM calendars
|
|
WHERE deleted_at IS NULL AND container_type = 'page'
|
|
""")
|
|
op.execute("""
|
|
INSERT INTO container_relations (parent_type, parent_id, child_type, child_id, sort_order)
|
|
SELECT 'page', container_id, 'market', id, 0
|
|
FROM market_places
|
|
WHERE deleted_at IS NULL AND container_type = 'page'
|
|
""")
|
|
op.execute("""
|
|
INSERT INTO container_relations (parent_type, parent_id, child_type, child_id, sort_order)
|
|
SELECT 'page', container_id, 'page_config', id, 0
|
|
FROM page_configs
|
|
WHERE deleted_at IS NULL AND container_type = 'page'
|
|
""")
|
|
|
|
# --- Backfill menu_nodes from existing menu_items + posts ---
|
|
op.execute("""
|
|
INSERT INTO menu_nodes (container_type, container_id, label, slug, feature_image, sort_order)
|
|
SELECT 'page', mi.post_id, p.title, p.slug, p.feature_image, mi.sort_order
|
|
FROM menu_items mi
|
|
JOIN posts p ON mi.post_id = p.id
|
|
WHERE mi.deleted_at IS NULL
|
|
""")
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_index('ix_menu_nodes_parent_id', table_name='menu_nodes')
|
|
op.drop_index('ix_menu_nodes_container', table_name='menu_nodes')
|
|
op.drop_table('menu_nodes')
|
|
op.drop_index('ix_container_relations_child', table_name='container_relations')
|
|
op.drop_index('ix_container_relations_parent', table_name='container_relations')
|
|
op.drop_table('container_relations')
|