Spaces:
Runtime error
Runtime error
Download backend/alembic/versions/0009_b2v_resources.py from firebird-technologies/NoteStack-Test: direct link, hf CLI and curl.
- Browser
- Download file 6.06 kB
-
https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/alembic/versions/0009_b2v_resources.py
- Command line
-
hf download hf://spaces/firebird-technologies/NoteStack-Test/backend/alembic/versions/0009_b2v_resources.py
-
curl -L -o 0009_b2v_resources.py https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/alembic/versions/0009_b2v_resources.py
6.06 kB
| """blog2video resources per workspace: templates, custom voices, saved voices, styles, usage counters; | |
| b2v_videos.created_via / template_ref; plans.video_premium / video_limits | |
| Everything made with our blog2video key belongs to one account, so these tables are what keeps each workspace's | |
| templates, voices and styles its own (app/services/b2v_access.py). | |
| Revision ID: 0009_b2v_resources | |
| Revises: 0008_b2v_videos | |
| Create Date: 2026-09-30 | |
| """ | |
| import json | |
| import sqlalchemy as sa | |
| from alembic import op | |
| revision = "0009_b2v_resources" | |
| down_revision = "0008_b2v_videos" | |
| branch_labels = None | |
| depends_on = None | |
| # Same as app/services/plans.py | |
| VIDEO_LIMITS = { | |
| "free": {"ai_edits": 20, "templates": 0, "template_ai_daily": 0, "voice_designs_daily": 0, | |
| "voice_samples_daily": 0, "custom_voices": 0}, | |
| "writer": {"ai_edits": 300, "templates": 2, "template_ai_daily": 3, "voice_designs_daily": 5, | |
| "voice_samples_daily": 20, "custom_voices": 3}, | |
| "studio": {"ai_edits": 1000, "templates": 5, "template_ai_daily": 5, "voice_designs_daily": 10, | |
| "voice_samples_daily": 40, "custom_voices": 10}, | |
| } | |
| def _ws() -> sa.Column: | |
| return sa.Column("workspace_id", sa.Uuid(), sa.ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False, | |
| index=True) | |
| def _times() -> list[sa.Column]: | |
| return [sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), | |
| sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now())] | |
| def upgrade() -> None: | |
| bind = op.get_bind() | |
| inspector = sa.inspect(bind) | |
| # 0001 builds from the live models, so a fresh database may already have all of this. | |
| video_cols = {c["name"] for c in inspector.get_columns("b2v_videos")} | |
| with op.batch_alter_table("b2v_videos") as batch: | |
| if "created_via" not in video_cols: | |
| batch.add_column(sa.Column("created_via", sa.String(10), nullable=False, server_default="v1")) | |
| if "template_ref" not in video_cols: | |
| batch.add_column(sa.Column("template_ref", sa.String(100), nullable=True)) | |
| batch.alter_column("idempotency_key", existing_type=sa.String(100), nullable=True) | |
| if not inspector.has_table("b2v_templates"): | |
| op.create_table("b2v_templates", | |
| sa.Column("b2v_template_id", sa.Integer(), primary_key=True, autoincrement=False), _ws(), | |
| sa.Column("name", sa.String(255), nullable=False), | |
| sa.Column("ready", sa.Boolean(), nullable=False, server_default=sa.false()), *_times()) | |
| if not inspector.has_table("b2v_custom_voices"): | |
| op.create_table("b2v_custom_voices", | |
| sa.Column("b2v_custom_voice_id", sa.Integer(), primary_key=True, autoincrement=False), _ws(), | |
| sa.Column("voice_id", sa.String(100), nullable=False, unique=True), | |
| sa.Column("name", sa.String(255), nullable=False), | |
| sa.Column("source", sa.String(20), nullable=False), | |
| sa.Column("preview_url", sa.String(1000), nullable=True), *_times()) | |
| if not inspector.has_table("user_saved_voices"): | |
| op.create_table("user_saved_voices", | |
| sa.Column("workspace_id", sa.Uuid(), sa.ForeignKey("workspaces.id", ondelete="CASCADE"), | |
| primary_key=True), | |
| sa.Column("voice_id", sa.String(100), primary_key=True), | |
| sa.Column("name", sa.String(255), nullable=False), | |
| sa.Column("preview_url", sa.String(1000), nullable=True), | |
| sa.Column("gender", sa.String(20), nullable=True), | |
| sa.Column("accent", sa.String(50), nullable=True), | |
| sa.Column("premium", sa.Boolean(), nullable=False, server_default=sa.false()), | |
| sa.Column("is_custom", sa.Boolean(), nullable=False, server_default=sa.false()), *_times()) | |
| if not inspector.has_table("b2v_styles"): | |
| op.create_table("b2v_styles", | |
| sa.Column("b2v_style_id", sa.Integer(), primary_key=True, autoincrement=False), _ws(), | |
| sa.Column("name", sa.String(80), nullable=False), *_times()) | |
| if not inspector.has_table("usage_counters"): | |
| op.create_table("usage_counters", | |
| sa.Column("workspace_id", sa.Uuid(), sa.ForeignKey("workspaces.id", ondelete="CASCADE"), | |
| primary_key=True), | |
| sa.Column("period", sa.String(10), primary_key=True), | |
| sa.Column("metric", sa.String(30), primary_key=True), | |
| sa.Column("used", sa.Integer(), nullable=False, server_default="0")) | |
| plan_cols = {c["name"] for c in inspector.get_columns("plans")} | |
| with op.batch_alter_table("plans") as batch: | |
| if "video_premium" not in plan_cols: | |
| batch.add_column(sa.Column("video_premium", sa.Boolean(), nullable=False, server_default=sa.false())) | |
| if "video_limits" not in plan_cols: | |
| batch.add_column(sa.Column("video_limits", sa.JSON(), nullable=True)) | |
| plans = sa.table("plans", sa.column("id", sa.String), sa.column("video_premium", sa.Boolean), | |
| sa.column("video_limits", sa.JSON)) | |
| for plan_id, limits in VIDEO_LIMITS.items(): | |
| op.execute(plans.update().where(plans.c.id == plan_id) | |
| .values(video_premium=plan_id != "free", video_limits=json.loads(json.dumps(limits)))) | |
| def downgrade() -> None: | |
| with op.batch_alter_table("plans") as batch: | |
| batch.drop_column("video_limits") | |
| batch.drop_column("video_premium") | |
| for table in ("usage_counters", "b2v_styles", "user_saved_voices", "b2v_custom_voices", "b2v_templates"): | |
| op.drop_table(table) | |
| with op.batch_alter_table("b2v_videos") as batch: | |
| batch.drop_column("template_ref") | |
| batch.drop_column("created_via") | |