Merge branch 'develop' into feature/batch-agent-v2
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
"""Initial schema: users, refresh_tokens, subscriptions, storage_records,
|
||||
backup_metadata, plugins, plugin_installations, plugin_reviews, revenue_events.
|
||||
"""Initial schema: users, refresh_tokens, subscriptions.
|
||||
|
||||
Revision ID: 001
|
||||
Revises:
|
||||
@@ -28,18 +27,6 @@ def upgrade() -> None:
|
||||
EXCEPTION WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
""")
|
||||
op.execute("""
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE plugin_status AS ENUM ('pending_review', 'approved', 'rejected');
|
||||
EXCEPTION WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
""")
|
||||
op.execute("""
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE review_decision AS ENUM ('approved', 'rejected');
|
||||
EXCEPTION WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
# ── users ─────────────────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
@@ -88,122 +75,10 @@ def upgrade() -> None:
|
||||
op.create_index("ix_subscriptions_user_id", "subscriptions", ["user_id"])
|
||||
op.create_index("ix_subscriptions_stripe_id", "subscriptions", ["stripe_subscription_id"])
|
||||
|
||||
# ── storage_records ───────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"storage_records",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("user_id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("table_name", sa.String(100), nullable=False),
|
||||
sa.Column("s3_key", sa.String(500), nullable=False),
|
||||
sa.Column("checksum", sa.String(64), nullable=False),
|
||||
sa.Column("size_bytes", sa.Integer, nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
|
||||
)
|
||||
op.create_index("ix_storage_records_user_id", "storage_records", ["user_id"])
|
||||
|
||||
# ── backup_metadata ───────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"backup_metadata",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("user_id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("s3_key", sa.String(500), nullable=False),
|
||||
sa.Column("version", sa.Integer, nullable=False),
|
||||
sa.Column("timestamp", sa.BigInteger, nullable=False),
|
||||
sa.Column("checksum", sa.String(64), nullable=False),
|
||||
sa.Column("size_bytes", sa.Integer, nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
|
||||
)
|
||||
op.create_index("ix_backup_metadata_user_id", "backup_metadata", ["user_id"])
|
||||
|
||||
# ── plugins ───────────────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"plugins",
|
||||
sa.Column("id", sa.String(255), nullable=False),
|
||||
sa.Column("name", sa.String(255), nullable=False),
|
||||
sa.Column("description", sa.Text, nullable=False, server_default=""),
|
||||
sa.Column("version", sa.String(50), nullable=False, server_default="1.0.0"),
|
||||
sa.Column("author_id", postgresql.UUID(as_uuid=False), nullable=True),
|
||||
sa.Column("author_name", sa.String(255), nullable=False, server_default=""),
|
||||
sa.Column("category", sa.String(100), nullable=False, server_default=""),
|
||||
sa.Column("price_cents", sa.Integer, nullable=False, server_default="0"),
|
||||
sa.Column("permissions", sa.Text, nullable=False, server_default="[]"),
|
||||
sa.Column("status", postgresql.ENUM("pending_review", "approved", "rejected", name="plugin_status", create_type=False), nullable=False, server_default="pending_review"),
|
||||
sa.Column("s3_package_key", sa.String(500), nullable=True),
|
||||
sa.Column("install_count", sa.Integer, nullable=False, server_default="0"),
|
||||
sa.Column("avg_rating", sa.Float, nullable=False, server_default="0.0"),
|
||||
sa.Column("rejection_reason", sa.Text, nullable=True),
|
||||
sa.Column("submitted_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["author_id"], ["users.id"], ondelete="SET NULL"),
|
||||
)
|
||||
|
||||
# ── plugin_installations ──────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"plugin_installations",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("plugin_id", sa.String(255), nullable=False),
|
||||
sa.Column("user_id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("installed_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["plugin_id"], ["plugins.id"], ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
|
||||
sa.UniqueConstraint("plugin_id", "user_id", name="uq_plugin_user"),
|
||||
)
|
||||
op.create_index("ix_plugin_installations_plugin_id", "plugin_installations", ["plugin_id"])
|
||||
op.create_index("ix_plugin_installations_user_id", "plugin_installations", ["user_id"])
|
||||
|
||||
# ── plugin_reviews ────────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"plugin_reviews",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("plugin_id", sa.String(255), nullable=False),
|
||||
sa.Column("reviewer_id", postgresql.UUID(as_uuid=False), nullable=True),
|
||||
sa.Column("decision", postgresql.ENUM("approved", "rejected", name="review_decision", create_type=False), nullable=False),
|
||||
sa.Column("notes", sa.Text, nullable=True),
|
||||
sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["plugin_id"], ["plugins.id"], ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["reviewer_id"], ["users.id"], ondelete="SET NULL"),
|
||||
)
|
||||
op.create_index("ix_plugin_reviews_plugin_id", "plugin_reviews", ["plugin_id"])
|
||||
|
||||
# ── revenue_events ────────────────────────────────────────────────────
|
||||
op.create_table(
|
||||
"revenue_events",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("plugin_id", sa.String(255), nullable=False),
|
||||
sa.Column("user_id", postgresql.UUID(as_uuid=False), nullable=False),
|
||||
sa.Column("amount_cents", sa.Integer, nullable=False, server_default="0"),
|
||||
sa.Column("developer_share_cents", sa.Integer, nullable=False, server_default="0"),
|
||||
sa.Column("stripe_transfer_id", sa.String(255), nullable=True),
|
||||
sa.Column("paid_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.ForeignKeyConstraint(["plugin_id"], ["plugins.id"], ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
|
||||
)
|
||||
op.create_index("ix_revenue_events_plugin_id", "revenue_events", ["plugin_id"])
|
||||
op.create_index("ix_revenue_events_user_id", "revenue_events", ["user_id"])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("revenue_events")
|
||||
op.drop_table("plugin_reviews")
|
||||
op.drop_table("plugin_installations")
|
||||
op.drop_table("plugins")
|
||||
op.drop_table("backup_metadata")
|
||||
op.drop_table("storage_records")
|
||||
op.drop_table("subscriptions")
|
||||
op.drop_table("refresh_tokens")
|
||||
op.drop_table("users")
|
||||
|
||||
op.execute("DROP TYPE IF EXISTS review_decision")
|
||||
op.execute("DROP TYPE IF EXISTS plugin_status")
|
||||
op.execute("DROP TYPE IF EXISTS billing_tier")
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
"""Seed approved plugins: GitHub Sync, Slack Notifier, Time Tracker.
|
||||
|
||||
Revision ID: 002
|
||||
Revises: 001
|
||||
Create Date: 2026-03-03
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "002"
|
||||
down_revision: Union[str, None] = "001"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
_SEED_PLUGINS = [
|
||||
{
|
||||
"id": "plugin-github-sync",
|
||||
"name": "GitHub Sync",
|
||||
"description": "Sync tasks with GitHub Issues and pull requests.",
|
||||
"version": "1.0.0",
|
||||
"author_name": "Adiuva",
|
||||
"category": "productivity",
|
||||
"price_cents": 0,
|
||||
"permissions": json.dumps(["read:tasks", "write:tasks"]),
|
||||
"status": "approved",
|
||||
"s3_package_key": "plugins/plugin-github-sync/1.0.0/package.zip",
|
||||
"install_count": 0,
|
||||
"avg_rating": 0.0,
|
||||
},
|
||||
{
|
||||
"id": "plugin-slack-notify",
|
||||
"name": "Slack Notifier",
|
||||
"description": "Post task and timeline updates to Slack channels.",
|
||||
"version": "1.2.0",
|
||||
"author_name": "Adiuva",
|
||||
"category": "communication",
|
||||
"price_cents": 499,
|
||||
"permissions": json.dumps(["read:tasks", "read:timelines"]),
|
||||
"status": "approved",
|
||||
"s3_package_key": "plugins/plugin-slack-notify/1.2.0/package.zip",
|
||||
"install_count": 0,
|
||||
"avg_rating": 0.0,
|
||||
},
|
||||
{
|
||||
"id": "plugin-time-tracker",
|
||||
"name": "Time Tracker",
|
||||
"description": "Track time spent on tasks with automatic reporting.",
|
||||
"version": "0.9.1",
|
||||
"author_name": "Third Party",
|
||||
"category": "productivity",
|
||||
"price_cents": 999,
|
||||
"permissions": json.dumps(["read:tasks", "write:tasks"]),
|
||||
"status": "approved",
|
||||
"s3_package_key": "plugins/plugin-time-tracker/0.9.1/package.zip",
|
||||
"install_count": 0,
|
||||
"avg_rating": 0.0,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
plugins = sa.table(
|
||||
"plugins",
|
||||
sa.column("id", sa.String),
|
||||
sa.column("name", sa.String),
|
||||
sa.column("description", sa.Text),
|
||||
sa.column("version", sa.String),
|
||||
sa.column("author_name", sa.String),
|
||||
sa.column("category", sa.String),
|
||||
sa.column("price_cents", sa.Integer),
|
||||
sa.column("permissions", sa.Text),
|
||||
sa.column("status", sa.Enum("pending_review", "approved", "rejected", name="plugin_status")),
|
||||
sa.column("s3_package_key", sa.String),
|
||||
sa.column("install_count", sa.Integer),
|
||||
sa.column("avg_rating", sa.Float),
|
||||
)
|
||||
op.bulk_insert(plugins, _SEED_PLUGINS)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute(
|
||||
"DELETE FROM plugins WHERE id IN ("
|
||||
"'plugin-github-sync', 'plugin-slack-notify', 'plugin-time-tracker'"
|
||||
")"
|
||||
)
|
||||
Reference in New Issue
Block a user