From 36f466ba11e2c6d8751b54a554256ea03ad3b3de Mon Sep 17 00:00:00 2001 From: youbin Date: Fri, 31 Jul 2026 14:21:43 +0800 Subject: [PATCH] Release v1.0.0 --- .dockerignore | 14 + .env.example | 95 + .env.production.example | 108 + .github/workflows/ci.yml | 176 + .gitignore | 12 + Dockerfile.server | 48 + Dockerfile.web | 23 + README.md | 37 + deploy/alertmanager.yml.template | 22 + deploy/alerts.yml | 156 + deploy/nginx/default.conf.template | 83 + deploy/prometheus.yml | 32 + deploy/systemd/frameflow-backup.env.example | 9 + deploy/systemd/frameflow-backup.service | 35 + deploy/systemd/frameflow-backup.timer | 12 + .../frameflow-restore-rehearsal.service | 36 + .../systemd/frameflow-restore-rehearsal.timer | 12 + docker-compose.prod.yml | 324 + docker-compose.yml | 69 + docs/deployment.md | 350 + index.html | 14 + package-lock.json | 6502 +++++++++++++++++ package.json | 45 + public/assets/character-linyao.jpg | Bin 0 -> 167945 bytes public/assets/character-lucheng.jpg | Bin 0 -> 407744 bytes public/assets/character-suyue.jpg | Bin 0 -> 461890 bytes public/assets/scene-city.jpg | Bin 0 -> 596141 bytes public/assets/scene-rooftop.jpg | Bin 0 -> 361864 bytes public/assets/scene-studio.jpg | Bin 0 -> 237643 bytes scripts/alertmanager-smoke.mjs | 310 + scripts/backup.sh | 103 + scripts/rehearse-restore.sh | 360 + scripts/scheduled-maintenance.sh | 76 + scripts/smoke-test.mjs | 927 +++ scripts/stripe-smoke.mjs | 305 + scripts/verify-backup.sh | 98 + server/drizzle.config.ts | 12 + server/drizzle/0000_last_spectrum.sql | 356 + server/drizzle/0001_perfect_gravity.sql | 1 + .../drizzle/0002_yielding_spencer_smythe.sql | 1 + server/drizzle/0003_hard_norrin_radd.sql | 1 + server/drizzle/0004_goofy_karnak.sql | 1 + server/drizzle/0005_brave_betty_ross.sql | 21 + server/drizzle/0006_wooden_texas_twister.sql | 24 + .../drizzle/0007_sudden_roland_deschain.sql | 15 + server/drizzle/0008_red_trish_tilby.sql | 4 + server/drizzle/0009_chilly_mockingbird.sql | 34 + server/drizzle/0010_sharp_odin.sql | 3 + server/drizzle/0011_futuristic_stature.sql | 25 + server/drizzle/0012_warm_old_lace.sql | 62 + server/drizzle/0013_lethal_giant_man.sql | 3 + server/drizzle/0014_heavy_retro_girl.sql | 3 + .../0015_reflective_true_believers.sql | 3 + server/drizzle/0016_amused_longshot.sql | 20 + server/drizzle/meta/0000_snapshot.json | 2980 ++++++++ server/drizzle/meta/0001_snapshot.json | 2981 ++++++++ server/drizzle/meta/0002_snapshot.json | 2982 ++++++++ server/drizzle/meta/0003_snapshot.json | 2983 ++++++++ server/drizzle/meta/0004_snapshot.json | 2990 ++++++++ server/drizzle/meta/0005_snapshot.json | 3178 ++++++++ server/drizzle/meta/0006_snapshot.json | 3406 +++++++++ server/drizzle/meta/0007_snapshot.json | 3538 +++++++++ server/drizzle/meta/0008_snapshot.json | 3573 +++++++++ server/drizzle/meta/0009_snapshot.json | 3854 ++++++++++ server/drizzle/meta/0010_snapshot.json | 3872 ++++++++++ server/drizzle/meta/0011_snapshot.json | 4110 +++++++++++ server/drizzle/meta/0012_snapshot.json | 4646 ++++++++++++ server/drizzle/meta/0013_snapshot.json | 4686 ++++++++++++ server/drizzle/meta/0014_snapshot.json | 4686 ++++++++++++ server/drizzle/meta/0015_snapshot.json | 4686 ++++++++++++ server/drizzle/meta/0016_snapshot.json | 4852 ++++++++++++ server/drizzle/meta/_journal.json | 125 + server/package.json | 52 + server/src/app.ts | 168 + server/src/config-check.ts | 22 + server/src/config.test.ts | 113 + server/src/config.ts | 279 + server/src/db/client.ts | 17 + server/src/db/migrate.ts | 9 + server/src/db/schema.ts | 566 ++ server/src/db/seed.ts | 269 + server/src/index.ts | 23 + server/src/lib/account-tokens.ts | 40 + server/src/lib/audit.ts | 27 + server/src/lib/auth.ts | 100 + server/src/lib/billing-plans.ts | 18 + server/src/lib/billing.ts | 131 + server/src/lib/character-consistency.test.ts | 68 + server/src/lib/character-consistency.ts | 116 + server/src/lib/credential-vault.test.ts | 39 + server/src/lib/credential-vault.ts | 51 + server/src/lib/errors.ts | 24 + server/src/lib/http.ts | 20 + server/src/lib/mailer.test.ts | 63 + server/src/lib/mailer.ts | 128 + server/src/lib/metrics.ts | 62 + server/src/lib/notifications.test.ts | 35 + server/src/lib/notifications.ts | 240 + server/src/lib/permissions.ts | 51 + server/src/lib/realtime.ts | 90 + server/src/lib/remote-media.test.ts | 112 + server/src/lib/remote-media.ts | 130 + server/src/lib/slug.ts | 11 + server/src/lib/stripe-billing.test.ts | 69 + server/src/lib/stripe-billing.ts | 194 + server/src/media/ffmpeg.test.ts | 117 + server/src/media/ffmpeg.ts | 322 + server/src/media/timeline.test.ts | 49 + server/src/providers/agnes.contract.test.ts | 318 + server/src/providers/agnes.ts | 467 ++ server/src/providers/index.ts | 34 + .../openai-compatible.contract.test.ts | 184 + server/src/providers/openai-compatible.ts | 432 ++ server/src/providers/openai.contract.test.ts | 337 + server/src/providers/openai.ts | 381 + server/src/providers/readiness.test.ts | 96 + server/src/providers/readiness.ts | 280 + .../src/providers/replicate.contract.test.ts | 254 + server/src/providers/replicate.ts | 251 + server/src/providers/types.ts | 154 + server/src/providers/verification.test.ts | 190 + server/src/providers/verification.ts | 283 + server/src/publishing/connector.test.ts | 63 + server/src/publishing/connector.ts | 164 + server/src/publishing/types.ts | 71 + server/src/queue/client.ts | 132 + server/src/queue/connection.ts | 17 + server/src/queue/heartbeat.test.ts | 34 + server/src/queue/heartbeat.ts | 56 + server/src/queue/processors.ts | 1004 +++ server/src/queue/production-plan.test.ts | 86 + server/src/queue/production-plan.ts | 109 + .../render-processor.integration.test.ts | 202 + server/src/queue/types.ts | 34 + .../account-recovery.integration.test.ts | 203 + server/src/routes/assets.integration.test.ts | 219 + server/src/routes/assets.ts | 213 + server/src/routes/audit.integration.test.ts | 129 + server/src/routes/audit.ts | 68 + .../routes/auth-security.integration.test.ts | 214 + server/src/routes/auth.ts | 448 ++ server/src/routes/billing.integration.test.ts | 355 + server/src/routes/billing.ts | 320 + server/src/routes/episodes.ts | 142 + server/src/routes/jobs.integration.test.ts | 138 + server/src/routes/jobs.ts | 142 + .../routes/notifications.integration.test.ts | 153 + server/src/routes/notifications.ts | 146 + .../production-runs.integration.test.ts | 155 + .../src/routes/production.integration.test.ts | 356 + server/src/routes/production.ts | 805 ++ .../project-management.integration.test.ts | 147 + server/src/routes/projects.ts | 82 + .../src/routes/publishing.integration.test.ts | 301 + server/src/routes/publishing.ts | 392 + .../src/routes/readiness.integration.test.ts | 292 + server/src/routes/readiness.ts | 193 + server/src/routes/reviews.ts | 312 + server/src/routes/shots.ts | 308 + server/src/routes/uploads.ts | 68 + .../routes/version-review.integration.test.ts | 219 + .../workspace-invitations.integration.test.ts | 227 + .../workspace-members.integration.test.ts | 141 + server/src/routes/workspaces.ts | 327 + server/src/storage/client.test.ts | 14 + server/src/storage/client.ts | 105 + server/src/types/fastify.d.ts | 18 + server/src/worker.ts | 251 + server/tsconfig.json | 22 + src/App.jsx | 4234 +++++++++++ src/aiCapabilities.js | 84 + src/aiCapabilities.test.js | 88 + src/alertmanagerSmoke.test.js | 151 + src/api.js | 248 + src/api.test.js | 193 + src/backupVerification.test.js | 108 + src/main.jsx | 10 + src/projectHealth.js | 84 + src/projectHealth.test.js | 70 + src/restoreRehearsal.test.js | 264 + src/scheduledMaintenance.test.js | 163 + src/smokeTest.test.js | 187 + src/stripeSmoke.test.js | 181 + src/styles.css | 497 ++ src/timeline.test.ts | 82 + src/timeline.ts | 60 + vitest.config.js | 10 + 187 files changed, 98907 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .env.production.example create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 Dockerfile.server create mode 100644 Dockerfile.web create mode 100644 README.md create mode 100644 deploy/alertmanager.yml.template create mode 100644 deploy/alerts.yml create mode 100644 deploy/nginx/default.conf.template create mode 100644 deploy/prometheus.yml create mode 100644 deploy/systemd/frameflow-backup.env.example create mode 100644 deploy/systemd/frameflow-backup.service create mode 100644 deploy/systemd/frameflow-backup.timer create mode 100644 deploy/systemd/frameflow-restore-rehearsal.service create mode 100644 deploy/systemd/frameflow-restore-rehearsal.timer create mode 100644 docker-compose.prod.yml create mode 100644 docker-compose.yml create mode 100644 docs/deployment.md create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/assets/character-linyao.jpg create mode 100644 public/assets/character-lucheng.jpg create mode 100644 public/assets/character-suyue.jpg create mode 100644 public/assets/scene-city.jpg create mode 100644 public/assets/scene-rooftop.jpg create mode 100644 public/assets/scene-studio.jpg create mode 100755 scripts/alertmanager-smoke.mjs create mode 100755 scripts/backup.sh create mode 100755 scripts/rehearse-restore.sh create mode 100755 scripts/scheduled-maintenance.sh create mode 100755 scripts/smoke-test.mjs create mode 100755 scripts/stripe-smoke.mjs create mode 100755 scripts/verify-backup.sh create mode 100644 server/drizzle.config.ts create mode 100644 server/drizzle/0000_last_spectrum.sql create mode 100644 server/drizzle/0001_perfect_gravity.sql create mode 100644 server/drizzle/0002_yielding_spencer_smythe.sql create mode 100644 server/drizzle/0003_hard_norrin_radd.sql create mode 100644 server/drizzle/0004_goofy_karnak.sql create mode 100644 server/drizzle/0005_brave_betty_ross.sql create mode 100644 server/drizzle/0006_wooden_texas_twister.sql create mode 100644 server/drizzle/0007_sudden_roland_deschain.sql create mode 100644 server/drizzle/0008_red_trish_tilby.sql create mode 100644 server/drizzle/0009_chilly_mockingbird.sql create mode 100644 server/drizzle/0010_sharp_odin.sql create mode 100644 server/drizzle/0011_futuristic_stature.sql create mode 100644 server/drizzle/0012_warm_old_lace.sql create mode 100644 server/drizzle/0013_lethal_giant_man.sql create mode 100644 server/drizzle/0014_heavy_retro_girl.sql create mode 100644 server/drizzle/0015_reflective_true_believers.sql create mode 100644 server/drizzle/0016_amused_longshot.sql create mode 100644 server/drizzle/meta/0000_snapshot.json create mode 100644 server/drizzle/meta/0001_snapshot.json create mode 100644 server/drizzle/meta/0002_snapshot.json create mode 100644 server/drizzle/meta/0003_snapshot.json create mode 100644 server/drizzle/meta/0004_snapshot.json create mode 100644 server/drizzle/meta/0005_snapshot.json create mode 100644 server/drizzle/meta/0006_snapshot.json create mode 100644 server/drizzle/meta/0007_snapshot.json create mode 100644 server/drizzle/meta/0008_snapshot.json create mode 100644 server/drizzle/meta/0009_snapshot.json create mode 100644 server/drizzle/meta/0010_snapshot.json create mode 100644 server/drizzle/meta/0011_snapshot.json create mode 100644 server/drizzle/meta/0012_snapshot.json create mode 100644 server/drizzle/meta/0013_snapshot.json create mode 100644 server/drizzle/meta/0014_snapshot.json create mode 100644 server/drizzle/meta/0015_snapshot.json create mode 100644 server/drizzle/meta/0016_snapshot.json create mode 100644 server/drizzle/meta/_journal.json create mode 100644 server/package.json create mode 100644 server/src/app.ts create mode 100644 server/src/config-check.ts create mode 100644 server/src/config.test.ts create mode 100644 server/src/config.ts create mode 100644 server/src/db/client.ts create mode 100644 server/src/db/migrate.ts create mode 100644 server/src/db/schema.ts create mode 100644 server/src/db/seed.ts create mode 100644 server/src/index.ts create mode 100644 server/src/lib/account-tokens.ts create mode 100644 server/src/lib/audit.ts create mode 100644 server/src/lib/auth.ts create mode 100644 server/src/lib/billing-plans.ts create mode 100644 server/src/lib/billing.ts create mode 100644 server/src/lib/character-consistency.test.ts create mode 100644 server/src/lib/character-consistency.ts create mode 100644 server/src/lib/credential-vault.test.ts create mode 100644 server/src/lib/credential-vault.ts create mode 100644 server/src/lib/errors.ts create mode 100644 server/src/lib/http.ts create mode 100644 server/src/lib/mailer.test.ts create mode 100644 server/src/lib/mailer.ts create mode 100644 server/src/lib/metrics.ts create mode 100644 server/src/lib/notifications.test.ts create mode 100644 server/src/lib/notifications.ts create mode 100644 server/src/lib/permissions.ts create mode 100644 server/src/lib/realtime.ts create mode 100644 server/src/lib/remote-media.test.ts create mode 100644 server/src/lib/remote-media.ts create mode 100644 server/src/lib/slug.ts create mode 100644 server/src/lib/stripe-billing.test.ts create mode 100644 server/src/lib/stripe-billing.ts create mode 100644 server/src/media/ffmpeg.test.ts create mode 100644 server/src/media/ffmpeg.ts create mode 100644 server/src/media/timeline.test.ts create mode 100644 server/src/providers/agnes.contract.test.ts create mode 100644 server/src/providers/agnes.ts create mode 100644 server/src/providers/index.ts create mode 100644 server/src/providers/openai-compatible.contract.test.ts create mode 100644 server/src/providers/openai-compatible.ts create mode 100644 server/src/providers/openai.contract.test.ts create mode 100644 server/src/providers/openai.ts create mode 100644 server/src/providers/readiness.test.ts create mode 100644 server/src/providers/readiness.ts create mode 100644 server/src/providers/replicate.contract.test.ts create mode 100644 server/src/providers/replicate.ts create mode 100644 server/src/providers/types.ts create mode 100644 server/src/providers/verification.test.ts create mode 100644 server/src/providers/verification.ts create mode 100644 server/src/publishing/connector.test.ts create mode 100644 server/src/publishing/connector.ts create mode 100644 server/src/publishing/types.ts create mode 100644 server/src/queue/client.ts create mode 100644 server/src/queue/connection.ts create mode 100644 server/src/queue/heartbeat.test.ts create mode 100644 server/src/queue/heartbeat.ts create mode 100644 server/src/queue/processors.ts create mode 100644 server/src/queue/production-plan.test.ts create mode 100644 server/src/queue/production-plan.ts create mode 100644 server/src/queue/render-processor.integration.test.ts create mode 100644 server/src/queue/types.ts create mode 100644 server/src/routes/account-recovery.integration.test.ts create mode 100644 server/src/routes/assets.integration.test.ts create mode 100644 server/src/routes/assets.ts create mode 100644 server/src/routes/audit.integration.test.ts create mode 100644 server/src/routes/audit.ts create mode 100644 server/src/routes/auth-security.integration.test.ts create mode 100644 server/src/routes/auth.ts create mode 100644 server/src/routes/billing.integration.test.ts create mode 100644 server/src/routes/billing.ts create mode 100644 server/src/routes/episodes.ts create mode 100644 server/src/routes/jobs.integration.test.ts create mode 100644 server/src/routes/jobs.ts create mode 100644 server/src/routes/notifications.integration.test.ts create mode 100644 server/src/routes/notifications.ts create mode 100644 server/src/routes/production-runs.integration.test.ts create mode 100644 server/src/routes/production.integration.test.ts create mode 100644 server/src/routes/production.ts create mode 100644 server/src/routes/project-management.integration.test.ts create mode 100644 server/src/routes/projects.ts create mode 100644 server/src/routes/publishing.integration.test.ts create mode 100644 server/src/routes/publishing.ts create mode 100644 server/src/routes/readiness.integration.test.ts create mode 100644 server/src/routes/readiness.ts create mode 100644 server/src/routes/reviews.ts create mode 100644 server/src/routes/shots.ts create mode 100644 server/src/routes/uploads.ts create mode 100644 server/src/routes/version-review.integration.test.ts create mode 100644 server/src/routes/workspace-invitations.integration.test.ts create mode 100644 server/src/routes/workspace-members.integration.test.ts create mode 100644 server/src/routes/workspaces.ts create mode 100644 server/src/storage/client.test.ts create mode 100644 server/src/storage/client.ts create mode 100644 server/src/types/fastify.d.ts create mode 100644 server/src/worker.ts create mode 100644 server/tsconfig.json create mode 100644 src/App.jsx create mode 100644 src/aiCapabilities.js create mode 100644 src/aiCapabilities.test.js create mode 100644 src/alertmanagerSmoke.test.js create mode 100644 src/api.js create mode 100644 src/api.test.js create mode 100644 src/backupVerification.test.js create mode 100644 src/main.jsx create mode 100644 src/projectHealth.js create mode 100644 src/projectHealth.test.js create mode 100644 src/restoreRehearsal.test.js create mode 100644 src/scheduledMaintenance.test.js create mode 100644 src/smokeTest.test.js create mode 100644 src/stripeSmoke.test.js create mode 100644 src/styles.css create mode 100644 src/timeline.test.ts create mode 100644 src/timeline.ts create mode 100644 vitest.config.js diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bdb785d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.git +.env +.env.* +!.env.example +!.env.production.example +node_modules +server/node_modules +dist +server/dist +coverage +backups +tmp +*.log +.DS_Store diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1e4e432 --- /dev/null +++ b/.env.example @@ -0,0 +1,95 @@ +# Application +NODE_ENV=development +API_HOST=127.0.0.1 +API_PORT=8787 +API_PUBLIC_ORIGIN=http://127.0.0.1:8787 +WEB_ORIGIN=http://127.0.0.1:4173 +LOG_LEVEL=info +METRICS_HOST=127.0.0.1 +WORKER_METRICS_PORT=9092 +WORKER_HEARTBEAT_KEY=frameflow:worker:heartbeat +WORKER_HEARTBEAT_INTERVAL_MS=5000 +WORKER_HEARTBEAT_TTL_SECONDS=20 +METRICS_TOKEN= + +# Security - replace every secret outside local development +JWT_ACCESS_SECRET=replace-with-at-least-32-characters +JWT_REFRESH_SECRET=replace-with-another-32-character-secret +CREDENTIAL_ENCRYPTION_KEY=replace-with-an-independent-32-character-secret +ACCESS_TOKEN_TTL=15m +REFRESH_TOKEN_TTL_DAYS=30 +EMAIL_VERIFICATION_REQUIRED=false +EMAIL_VERIFICATION_TTL_HOURS=24 +PASSWORD_RESET_TTL_MINUTES=30 +# Verification, password-reset, and workspace-invitation email delivery. +RESEND_API_KEY= +EMAIL_FROM=FrameFlow + +# PostgreSQL / Redis +DATABASE_URL=postgresql://frameflow:frameflow@127.0.0.1:54329/frameflow +REDIS_URL=redis://127.0.0.1:63799 + +# S3-compatible object storage +S3_ENDPOINT=http://127.0.0.1:9000 +# Optional browser/provider-facing endpoint. Defaults to S3_ENDPOINT locally. +S3_PUBLIC_ENDPOINT=http://127.0.0.1:9000 +S3_REGION=us-east-1 +S3_BUCKET=frameflow +S3_ACCESS_KEY=frameflow +S3_SECRET_KEY=frameflow-local-secret +S3_FORCE_PATH_STYLE=true + +# AI providers (optional until configured) +OPENAI_API_KEY= +OPENAI_TEXT_MODEL=gpt-5.6-sol +OPENAI_IMAGE_MODEL=gpt-image-2 +OPENAI_TTS_MODEL=gpt-4o-mini-tts +OPENAI_TTS_VOICE=alloy +# Agnes OpenAI-compatible gateway (text, image and video) +AGNES_API_KEY= +AGNES_TEXT_MODEL=agnes-2.5-flash +AGNES_IMAGE_MODEL=agnes-image-2.1-flash +AGNES_VIDEO_MODEL=agnes-video-v2.0 +AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS=900 +AGNES_VIDEO_POLL_INTERVAL_MS=4000 +# Generic OpenAI-compatible providers. Each capability is configured independently. +# BASE_URL is the API root including its version path, for example https://api.vendor.com/v1. +GENERIC_TEXT_API_KEY= +GENERIC_TEXT_BASE_URL= +GENERIC_TEXT_MODEL= +GENERIC_IMAGE_API_KEY= +GENERIC_IMAGE_BASE_URL= +GENERIC_IMAGE_MODEL= +GENERIC_VIDEO_API_KEY= +GENERIC_VIDEO_BASE_URL= +GENERIC_VIDEO_MODEL= +GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS=900 +GENERIC_VIDEO_POLL_INTERVAL_MS=4000 +REPLICATE_API_TOKEN= +REPLICATE_IMAGE_VERSION= +REPLICATE_VIDEO_VERSION= +REPLICATE_LIPSYNC_VERSION= +# Replicate cancels predictions that have not finished within this deadline. +REPLICATE_PREDICTION_DEADLINE_SECONDS=900 + +# Stripe subscriptions (optional; the UI reports missing configuration) +STRIPE_SECRET_KEY= +STRIPE_WEBHOOK_SECRET= +STRIPE_PRO_PRICE_ID= +STRIPE_STUDIO_PRICE_ID= +STRIPE_PORTAL_CONFIGURATION_ID= +BILLING_SUCCESS_URL= +BILLING_CANCEL_URL= + +# External publishing connector. Leave both empty until a connector is deployed. +PUBLISHING_CONNECTOR_URL= +PUBLISHING_CONNECTOR_SECRET= +PUBLISHING_CONNECTOR_TIMEOUT_MS=30000 + +# Media worker +FFMPEG_PATH=ffmpeg +FFPROBE_PATH=ffprobe +WORKER_CONCURRENCY=2 +MAX_UPLOAD_BYTES=104857600 +PROVIDER_DOWNLOAD_TIMEOUT_MS=180000 +PROVIDER_DOWNLOAD_MAX_REDIRECTS=3 diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..2eb0232 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,108 @@ +# Public routing. Terminate TLS in front of HTTP_PORT and preserve the Host header. +APP_HOST=studio.example.com +MEDIA_HOST=media.example.com +WEB_ORIGIN=https://studio.example.com +API_PUBLIC_ORIGIN=https://studio.example.com +S3_PUBLIC_ENDPOINT=https://media.example.com +HTTP_BIND=0.0.0.0 +HTTP_PORT=8080 +MAX_UPLOAD_SIZE=100m + +# Image/version naming and local-only operator ports. +COMPOSE_PROJECT_NAME=frameflow-prod +FRAMEFLOW_VERSION=latest +MINIO_CONSOLE_BIND=127.0.0.1 +MINIO_CONSOLE_PORT=9001 +PROMETHEUS_BIND=127.0.0.1 +PROMETHEUS_PORT=9090 +PROMETHEUS_RETENTION=30d +# Host directory shared by backup.sh and Node Exporter's textfile collector. +FRAMEFLOW_BACKUP_METRICS_DIR=/var/lib/frameflow/metrics +ALERTMANAGER_BIND=127.0.0.1 +ALERTMANAGER_PORT=9093 +# Replace with the operator endpoint that receives firing and resolved alerts. +ALERTMANAGER_WEBHOOK_URL=https://alerts.example.com/frameflow-webhook + +# Replace every value below before deployment. Keep URL passwords URL-safe. +POSTGRES_DB=frameflow +POSTGRES_USER=frameflow +POSTGRES_PASSWORD=replace_with_strong_postgres_password +DATABASE_URL=postgresql://frameflow:replace_with_strong_postgres_password@postgres:5432/frameflow +REDIS_PASSWORD=replace_with_strong_redis_password +REDIS_URL=redis://default:replace_with_strong_redis_password@redis:6379 +JWT_ACCESS_SECRET=replace_with_at_least_32_random_characters_access +JWT_REFRESH_SECRET=replace_with_at_least_32_random_characters_refresh +CREDENTIAL_ENCRYPTION_KEY=replace_with_independent_credential_encryption_key +S3_BUCKET=frameflow +S3_REGION=us-east-1 +S3_ACCESS_KEY=replace_with_minio_access_key +S3_SECRET_KEY=replace_with_minio_secret_key + +# Metrics stay on the private Compose network. Set a token only when the +# Prometheus scrape configuration is updated to send the same token. +METRICS_TOKEN= +LOG_LEVEL=info +ACCESS_TOKEN_TTL=15m +REFRESH_TOKEN_TTL_DAYS=30 +EMAIL_VERIFICATION_REQUIRED=true +EMAIL_VERIFICATION_TTL_HOURS=24 +PASSWORD_RESET_TTL_MINUTES=30 +# Used for verification, password-reset, and workspace-invitation emails. +RESEND_API_KEY=replace_with_resend_api_key +EMAIL_FROM=FrameFlow + +# AI providers. Missing values fail jobs explicitly and never create fake media. +OPENAI_API_KEY= +OPENAI_TEXT_MODEL=gpt-5.6-sol +OPENAI_IMAGE_MODEL=gpt-image-2 +OPENAI_TTS_MODEL=gpt-4o-mini-tts +OPENAI_TTS_VOICE=alloy +# Agnes OpenAI-compatible gateway (text, image and video) +AGNES_API_KEY= +AGNES_TEXT_MODEL=agnes-2.5-flash +AGNES_IMAGE_MODEL=agnes-image-2.1-flash +AGNES_VIDEO_MODEL=agnes-video-v2.0 +AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS=900 +AGNES_VIDEO_POLL_INTERVAL_MS=4000 +# Generic OpenAI-compatible providers. Configure each capability as a complete triple. +# BASE_URL is the API root including its version path, for example https://api.vendor.com/v1. +GENERIC_TEXT_API_KEY= +GENERIC_TEXT_BASE_URL= +GENERIC_TEXT_MODEL= +GENERIC_IMAGE_API_KEY= +GENERIC_IMAGE_BASE_URL= +GENERIC_IMAGE_MODEL= +GENERIC_VIDEO_API_KEY= +GENERIC_VIDEO_BASE_URL= +GENERIC_VIDEO_MODEL= +GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS=900 +GENERIC_VIDEO_POLL_INTERVAL_MS=4000 +REPLICATE_API_TOKEN= +REPLICATE_IMAGE_VERSION= +REPLICATE_VIDEO_VERSION= +REPLICATE_LIPSYNC_VERSION= +# Sent to Replicate as Cancel-After; valid range is 5 seconds to 24 hours. +REPLICATE_PREDICTION_DEADLINE_SECONDS=900 + +# Stripe subscriptions. Leave all values empty to keep billing read-only. +STRIPE_SECRET_KEY= +STRIPE_WEBHOOK_SECRET= +STRIPE_PRO_PRICE_ID= +STRIPE_STUDIO_PRICE_ID= +STRIPE_PORTAL_CONFIGURATION_ID= +BILLING_SUCCESS_URL=https://studio.example.com +BILLING_CANCEL_URL=https://studio.example.com + +# Optional platform connector for Douyin, Kuaishou, Bilibili, and Xiaohongshu. +# Configure both values together. The connector must expose the documented /v1 endpoints. +PUBLISHING_CONNECTOR_URL= +PUBLISHING_CONNECTOR_SECRET= +PUBLISHING_CONNECTOR_TIMEOUT_MS=30000 + +WORKER_CONCURRENCY=2 +WORKER_HEARTBEAT_KEY=frameflow:worker:heartbeat +WORKER_HEARTBEAT_INTERVAL_MS=5000 +WORKER_HEARTBEAT_TTL_SECONDS=20 +MAX_UPLOAD_BYTES=104857600 +PROVIDER_DOWNLOAD_TIMEOUT_MS=180000 +PROVIDER_DOWNLOAD_MAX_REDIRECTS=3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..79e4417 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,176 @@ +name: CI + +on: + push: + branches: + - main + - master + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: frameflow-ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Migrations, tests, build, and audit + runs-on: ubuntu-24.04 + timeout-minutes: 30 + env: + NODE_ENV: test + WEB_ORIGIN: http://127.0.0.1:4173 + DATABASE_URL: postgresql://frameflow:frameflow@127.0.0.1:54329/frameflow + REDIS_URL: redis://127.0.0.1:63799 + JWT_ACCESS_SECRET: ci-access-secret-with-at-least-32-characters + JWT_REFRESH_SECRET: ci-refresh-secret-with-at-least-32-characters + EMAIL_VERIFICATION_REQUIRED: "false" + S3_ENDPOINT: http://127.0.0.1:9000 + S3_PUBLIC_ENDPOINT: http://127.0.0.1:9000 + S3_REGION: us-east-1 + S3_BUCKET: frameflow + S3_ACCESS_KEY: frameflow + S3_SECRET_KEY: frameflow-local-secret + S3_FORCE_PATH_STYLE: "true" + FFMPEG_PATH: ffmpeg + FFPROBE_PATH: ffprobe + + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + + - name: Install system media dependencies + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends ffmpeg fonts-noto-cjk + + - name: Install dependencies + run: npm ci + + - name: Validate production smoke-test CLI + run: npm run smoke:production -- --help + + - name: Validate Alertmanager smoke-test CLI + run: npm run smoke:alertmanager -- --help + + - name: Validate Stripe smoke-test CLI + run: npm run smoke:stripe -- --help + + - name: Validate isolated restore-rehearsal CLI + run: npm run restore:rehearse -- --help + + - name: Validate scheduled maintenance CLI and systemd units + run: | + ./scripts/scheduled-maintenance.sh --help + systemd-analyze verify deploy/systemd/*.service deploy/systemd/*.timer + + - name: Start test infrastructure + run: | + docker compose up -d --wait postgres redis minio + docker compose run --rm --no-deps minio-init + + - name: Apply database migrations + run: npm run db:migrate + + - name: Run test suite + run: npm test + + - name: Create and rehearse a real isolated restore + shell: bash + env: + COMPOSE_PROJECT_NAME: frameflow + FRAMEFLOW_ENV_FILE: ${{ github.workspace }}/.env.production.example + FRAMEFLOW_BACKUP_METRICS_DIR: ${{ runner.temp }}/frameflow-metrics + FRAMEFLOW_RESTORE_METRICS_DIR: ${{ runner.temp }}/frameflow-metrics + run: | + backup_parent="${RUNNER_TEMP}/frameflow-backups" + ./scripts/backup.sh "${backup_parent}" + backup_dir="$(find "${backup_parent}" -mindepth 1 -maxdepth 1 -type d -name 'frameflow-*' -print -quit)" + test -n "${backup_dir}" + npm run restore:rehearse -- "${backup_dir}" + + - name: Build web and server + run: npm run build:all + + - name: Audit production dependencies + run: npm audit --omit=dev + + - name: Show infrastructure diagnostics + if: failure() + run: | + docker compose ps + docker compose logs --no-color --tail=200 postgres redis minio + + - name: Stop test infrastructure + if: always() + run: docker compose down --volumes --remove-orphans + + production-images: + name: Production gate and container images + runs-on: ubuntu-24.04 + timeout-minutes: 30 + + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Create synthetic production configuration + shell: bash + run: | + production_env="${RUNNER_TEMP}/frameflow-production.env" + { + echo "APP_HOST=studio.frameflow-ci.test" + echo "MEDIA_HOST=media.frameflow-ci.test" + echo "WEB_ORIGIN=https://studio.frameflow-ci.test" + echo "API_PUBLIC_ORIGIN=https://studio.frameflow-ci.test" + echo "S3_PUBLIC_ENDPOINT=https://media.frameflow-ci.test" + echo "COMPOSE_PROJECT_NAME=frameflow-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + echo "FRAMEFLOW_VERSION=ci" + echo "ALERTMANAGER_WEBHOOK_URL=https://alerts.frameflow-ci.test/webhook" + echo "POSTGRES_DB=frameflow" + echo "POSTGRES_USER=frameflow" + echo "POSTGRES_PASSWORD=ci-postgres-password-with-32-characters" + echo "DATABASE_URL=postgresql://frameflow:ci-postgres-password-with-32-characters@postgres:5432/frameflow" + echo "REDIS_PASSWORD=ci-redis-password-with-32-characters" + echo "REDIS_URL=redis://default:ci-redis-password-with-32-characters@redis:6379" + echo "JWT_ACCESS_SECRET=ci-access-signing-secret-with-32-characters" + echo "JWT_REFRESH_SECRET=ci-refresh-signing-secret-with-32-characters" + echo "CREDENTIAL_ENCRYPTION_KEY=ci-credential-encryption-secret-with-32-characters" + echo "S3_BUCKET=frameflow" + echo "S3_ACCESS_KEY=frameflow-ci-access-key" + echo "S3_SECRET_KEY=frameflow-ci-storage-secret-with-32-characters" + echo "EMAIL_VERIFICATION_REQUIRED=true" + echo "RESEND_API_KEY=re_ci_configuration_validation_only" + echo "EMAIL_FROM=FrameFlow CI " + echo "BILLING_SUCCESS_URL=https://studio.frameflow-ci.test" + echo "BILLING_CANCEL_URL=https://studio.frameflow-ci.test" + } > "${production_env}" + echo "PRODUCTION_ENV=${production_env}" >> "${GITHUB_ENV}" + + - name: Validate production Compose configuration + run: docker compose --env-file "${PRODUCTION_ENV}" -f docker-compose.prod.yml config --quiet + + - name: Build production images + run: docker compose --env-file "${PRODUCTION_ENV}" -f docker-compose.prod.yml build config-check web + + - name: Accept a safe production configuration + run: docker compose --env-file "${PRODUCTION_ENV}" -f docker-compose.prod.yml run --rm --no-deps config-check + + - name: Reject the placeholder production example + shell: bash + run: | + if COMPOSE_PROJECT_NAME="frameflow-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" FRAMEFLOW_VERSION=ci docker compose --env-file .env.production.example -f docker-compose.prod.yml run --rm --no-deps config-check; then + echo "The production gate accepted placeholder configuration." >&2 + exit 1 + fi + + - name: Remove build containers + if: always() + run: docker compose --env-file "${PRODUCTION_ENV}" -f docker-compose.prod.yml down --remove-orphans diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc7a938 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules/ +dist/ +server/dist/ +.env +.env.local +*.log +.DS_Store +coverage/ +.turbo/ +tmp/ +backups/ +.env.production diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 0000000..b063d18 --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,48 @@ +# syntax=docker/dockerfile:1.7 + +FROM node:24-bookworm-slim AS build +WORKDIR /app + +COPY package.json package-lock.json ./ +COPY server/package.json ./server/package.json +RUN npm ci --workspace @frameflow/server --include-workspace-root=false + +COPY server ./server +RUN npm run build --workspace @frameflow/server + +FROM node:24-bookworm-slim AS runtime +ENV NODE_ENV=production +WORKDIR /app + +RUN DEBIAN_FRONTEND=noninteractive apt-get \ + -o Acquire::Retries=3 \ + -o Acquire::ForceIPv4=true \ + -o Acquire::http::Timeout=30 \ + -o Acquire::http::Pipeline-Depth=0 \ + -o Acquire::http::No-Cache=true \ + -o Acquire::BrokenProxy=true \ + -o Acquire::https::Timeout=30 \ + update \ + && DEBIAN_FRONTEND=noninteractive apt-get \ + -o Acquire::Retries=3 \ + -o Acquire::ForceIPv4=true \ + -o Acquire::http::Timeout=30 \ + -o Acquire::http::Pipeline-Depth=0 \ + -o Acquire::http::No-Cache=true \ + -o Acquire::BrokenProxy=true \ + -o Acquire::https::Timeout=30 \ + install -y --no-install-recommends ca-certificates dumb-init ffmpeg fonts-noto-cjk \ + && rm -rf /var/lib/apt/lists/* + +COPY package.json package-lock.json ./ +COPY server/package.json ./server/package.json +RUN npm ci --omit=dev --workspace @frameflow/server --include-workspace-root=false \ + && npm cache clean --force + +COPY --from=build --chown=node:node /app/server/dist ./server/dist +COPY --chown=node:node server/drizzle ./server/drizzle + +USER node +EXPOSE 8787 9092 +ENTRYPOINT ["dumb-init", "--"] +CMD ["node", "server/dist/index.js"] diff --git a/Dockerfile.web b/Dockerfile.web new file mode 100644 index 0000000..8697f93 --- /dev/null +++ b/Dockerfile.web @@ -0,0 +1,23 @@ +# syntax=docker/dockerfile:1.7 + +FROM node:24-alpine AS build +WORKDIR /app + +COPY package.json package-lock.json ./ +COPY server/package.json ./server/package.json +RUN npm ci --include-workspace-root + +COPY index.html ./ +COPY src ./src +COPY public ./public + +ARG VITE_API_URL=/api/v1 +ENV VITE_API_URL=${VITE_API_URL} +RUN npm run build + +FROM nginx:1.29-alpine AS runtime +COPY deploy/nginx/default.conf.template /etc/nginx/templates/default.conf.template +COPY --from=build /app/dist /usr/share/nginx/html +EXPOSE 80 +HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=5 \ + CMD wget -qO- http://127.0.0.1/health/live >/dev/null || exit 1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a4c371 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# FrameFlow AI Comic Studio + +FrameFlow is an end-to-end AI comic drama production workspace. It includes project and episode management, reusable character and scene assets, AI script and storyboard jobs, shot production, TTS/video/lipsync processing, FFmpeg rendering with immutable source manifests and SRT/VTT sidecars, immutable versions, review workflows, user-scoped persistent notifications with authenticated realtime updates, email-backed workspace invitations, delivery, usage quotas, persisted administrator-only AI provider connection verification, Prometheus metrics, infrastructure capacity and backup-age alerts, and Alertmanager webhook notifications. + +## Local development + +Requirements: Node.js 24+, Docker Compose, and FFmpeg. + +```bash +cp .env.example .env +npm ci +npm run infra:up +npm run db:migrate +npm run db:seed +npm run dev +``` + +The web app runs at `http://127.0.0.1:5173` by default. The repository's current preview setup may use port `4173` instead. The API readiness endpoint is `http://127.0.0.1:8787/health/ready`; it also verifies that the generation worker heartbeat is current. + +Cloud jobs require valid OpenAI and Replicate configuration. Missing provider credentials cause explicit failed jobs; the system does not substitute generated demo output. + +Publishing to Douyin, Kuaishou, Bilibili, and Xiaohongshu requires a separately deployed connector that owns each platform's application credentials and API-specific behavior. FrameFlow stores encrypted channel tokens, schedules delivery jobs, and verifies signed status callbacks. The connector HTTP contract, environment variables, and live acceptance checklist are documented in [docs/deployment.md](docs/deployment.md#publishing-connector). + +## Verification + +```bash +npm run build:all +npm test +``` + +The GitHub Actions workflow in `.github/workflows/ci.yml` runs migrations, the complete web and server test suites, a real three-store backup and isolated restore rehearsal, production builds, a production-dependency audit, production Compose validation, container image builds, and both the accepting and rejecting sides of the production configuration gate. Its production values are synthetic and generated only inside the runner; no deploy credentials are stored in the workflow. + +After deployment, `npm run smoke:production` runs an authenticated, provider-free production path through persistence, object upload/download, BullMQ, FFmpeg rendering, subtitle sidecars, review approval, audit logs, and secure download delivery. The default mode reports AI provider configuration without starting billable jobs. A separate `--include-ai` mode performs live OpenAI and Replicate generation only after an exact billable-charge acknowledgement, complete seven-workflow readiness, and a 700-credit preflight. Required environment variables, provider-specific parameter handling, and data-retention behavior are documented in the deployment guide. + +Production deployment, TLS/media routing, monitoring, controlled firing/resolved Alertmanager webhook acceptance, read-only Stripe resource verification, backup, restore, and upgrade procedures are documented in [docs/deployment.md](docs/deployment.md). +The production Compose stack includes a fail-fast configuration gate before migrations; it rejects placeholder secrets, unsafe public endpoints, and incomplete provider or billing configuration without printing secret values. +Production backups are checksum-protected and pass a standalone read-only archive verifier before success metrics are published. A separate restore-rehearsal command restores all three data stores into randomly named, labeled Docker resources with no published ports, verifies their contents, publishes rehearsal metrics, and removes the isolated resources. Supplied hardened systemd timers run a verified backup daily and require a fresh successful backup before the monthly restore rehearsal; the scheduler refuses to use a missing or unexpected backup mount. diff --git a/deploy/alertmanager.yml.template b/deploy/alertmanager.yml.template new file mode 100644 index 0000000..1cc4797 --- /dev/null +++ b/deploy/alertmanager.yml.template @@ -0,0 +1,22 @@ +global: + resolve_timeout: 5m + +route: + receiver: frameflow-operator-webhook + group_by: [alertname, severity] + group_wait: 30s + group_interval: 5m + repeat_interval: 4h + routes: + - receiver: frameflow-operator-webhook + matchers: + - alertname="FrameFlowDeliveryTest" + group_wait: 1s + group_interval: 5s + repeat_interval: 1h + +receivers: + - name: frameflow-operator-webhook + webhook_configs: + - url: "__ALERTMANAGER_WEBHOOK_URL__" + send_resolved: true diff --git a/deploy/alerts.yml b/deploy/alerts.yml new file mode 100644 index 0000000..5144aeb --- /dev/null +++ b/deploy/alerts.yml @@ -0,0 +1,156 @@ +groups: + - name: frameflow-availability + rules: + - alert: FrameFlowApiDown + expr: up{job="frameflow-api"} == 0 + for: 2m + labels: + severity: critical + annotations: + summary: FrameFlow API is down + description: Prometheus has been unable to scrape the API for two minutes. + + - alert: FrameFlowWorkerDown + expr: up{job="frameflow-worker"} == 0 + for: 2m + labels: + severity: critical + annotations: + summary: FrameFlow worker is down + description: Prometheus has been unable to scrape the generation worker for two minutes. + + - alert: FrameFlowDependencyUnavailable + expr: frameflow_application_dependency_available == 0 + for: 2m + labels: + severity: critical + annotations: + summary: FrameFlow dependency is unavailable + description: "API readiness dependency {{ $labels.dependency }} has been unavailable for two minutes." + + - alert: FrameFlowWorkerHeartbeatStale + expr: time() - frameflow_generation_worker_heartbeat_timestamp_seconds > 30 + for: 1m + labels: + severity: critical + annotations: + summary: FrameFlow worker heartbeat is stale + description: The worker metrics process is reachable but its Redis heartbeat has stopped. + + - alert: FrameFlowInfrastructureExporterDown + expr: up{job=~"frameflow-node|frameflow-minio"} == 0 + for: 5m + labels: + severity: critical + annotations: + summary: FrameFlow infrastructure metrics are unavailable + description: "Prometheus has been unable to scrape {{ $labels.job }} for five minutes." + + - name: frameflow-capacity-and-backup + rules: + - alert: FrameFlowHostFilesystemLow + expr: | + ( + node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|tracefs|cgroup2?"} + / + node_filesystem_size_bytes{fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|tracefs|cgroup2?"} + ) < 0.15 + and on(instance, device, mountpoint) + node_filesystem_readonly == 0 + for: 15m + labels: + severity: warning + annotations: + summary: FrameFlow host filesystem has less than 15% free space + description: "Filesystem {{ $labels.mountpoint }} on {{ $labels.instance }} is running low on space." + + - alert: FrameFlowMinioCapacityLow + expr: | + minio_cluster_capacity_usable_free_bytes + / + minio_cluster_capacity_usable_total_bytes + < 0.15 + for: 15m + labels: + severity: warning + annotations: + summary: FrameFlow object storage has less than 15% usable capacity + description: "MinIO cluster {{ $labels.server }} is running low on usable object-storage capacity." + + - alert: FrameFlowBackupStale + expr: | + (time() - frameflow_backup_last_success_timestamp_seconds > 90000) + or absent(frameflow_backup_last_success_timestamp_seconds) + for: 15m + labels: + severity: critical + annotations: + summary: FrameFlow has no successful backup in the last 25 hours + description: Run and verify the scheduled PostgreSQL, Redis, and MinIO backup. + + - alert: FrameFlowRestoreRehearsalStale + expr: | + (time() - frameflow_restore_rehearsal_last_success_timestamp_seconds > 3024000) + or absent(frameflow_restore_rehearsal_last_success_timestamp_seconds) + for: 15m + labels: + severity: warning + annotations: + summary: FrameFlow has no successful restore rehearsal in the last 35 days + description: Restore a verified backup into the isolated rehearsal environment and investigate any validation failure. + + - name: frameflow-performance + rules: + - alert: FrameFlowApiHighErrorRate + expr: | + ( + sum(rate(frameflow_api_requests_total{status=~"5.."}[5m])) + / + clamp_min(sum(rate(frameflow_api_requests_total[5m])), 0.001) + ) > 0.05 + and sum(rate(frameflow_api_requests_total[5m])) > 0.05 + for: 10m + labels: + severity: warning + annotations: + summary: FrameFlow API error rate is high + description: More than 5% of API requests have returned 5xx responses for ten minutes. + + - alert: FrameFlowApiLatencyHigh + expr: | + histogram_quantile(0.95, + sum by (le) (rate(frameflow_api_request_duration_seconds_bucket[10m])) + ) > 2 + for: 10m + labels: + severity: warning + annotations: + summary: FrameFlow API latency is high + description: API p95 latency has exceeded two seconds for ten minutes. + + - alert: FrameFlowGenerationFailureRateHigh + expr: | + ( + sum(rate(frameflow_generation_jobs_processed_total{result="failed"}[10m])) + / + clamp_min(sum(rate(frameflow_generation_jobs_processed_total[10m])), 0.001) + ) > 0.20 + and sum(rate(frameflow_generation_jobs_processed_total[10m])) > 0.01 + for: 10m + labels: + severity: warning + annotations: + summary: FrameFlow generation failure rate is high + description: More than 20% of recent generation attempts have failed. + + - alert: FrameFlowQueueLatencyHigh + expr: | + histogram_quantile(0.95, + sum by (le) (rate(frameflow_generation_job_queue_delay_seconds_bucket[10m])) + ) > 60 + for: 10m + labels: + severity: warning + annotations: + summary: FrameFlow queue latency is high + description: Generation job p95 queue delay has exceeded 60 seconds for ten minutes. diff --git a/deploy/nginx/default.conf.template b/deploy/nginx/default.conf.template new file mode 100644 index 0000000..0b711e3 --- /dev/null +++ b/deploy/nginx/default.conf.template @@ -0,0 +1,83 @@ +upstream frameflow_api { + server api:8787; + keepalive 32; +} + +server { + listen 80 default_server; + server_name ${APP_HOST}; + root /usr/share/nginx/html; + index index.html; + client_max_body_size ${MAX_UPLOAD_SIZE}; + + add_header X-Content-Type-Options nosniff always; + add_header X-Frame-Options DENY always; + add_header Referrer-Policy strict-origin-when-cross-origin always; + add_header Permissions-Policy "camera=(), geolocation=(), microphone=()" always; + + location /api/ { + proxy_pass http://frameflow_api; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Connection ""; + } + + location /health/ { + proxy_pass http://frameflow_api; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /metrics { + return 404; + } + + location ~* \.(?:css|js|jpg|jpeg|png|webp|avif|svg|ico|woff2?)$ { + try_files $uri =404; + expires 7d; + add_header Cache-Control "public, max-age=604800, immutable"; + } + + location / { + try_files $uri $uri/ /index.html; + add_header Cache-Control "no-cache"; + } +} + +server { + listen 80; + server_name ${MEDIA_HOST}; + client_max_body_size ${MAX_UPLOAD_SIZE}; + + location = /minio/v2/metrics { + return 404; + } + + location ^~ /minio/v2/metrics/ { + return 404; + } + + location = /minio/v3/metrics { + return 404; + } + + location ^~ /minio/v3/metrics/ { + return 404; + } + + location / { + proxy_pass http://minio:9000; + proxy_http_version 1.1; + proxy_request_buffering off; + proxy_buffering off; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/deploy/prometheus.yml b/deploy/prometheus.yml new file mode 100644 index 0000000..945905d --- /dev/null +++ b/deploy/prometheus.yml @@ -0,0 +1,32 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +alerting: + alertmanagers: + - static_configs: + - targets: ["alertmanager:9093"] + +rule_files: + - /etc/prometheus/alerts.yml + +scrape_configs: + - job_name: frameflow-api + metrics_path: /metrics + static_configs: + - targets: ["api:8787"] + + - job_name: frameflow-worker + metrics_path: /metrics + static_configs: + - targets: ["worker:9092"] + + - job_name: frameflow-node + metrics_path: /metrics + static_configs: + - targets: ["node-exporter:9100"] + + - job_name: frameflow-minio + metrics_path: /minio/v2/metrics/cluster + static_configs: + - targets: ["minio:9000"] diff --git a/deploy/systemd/frameflow-backup.env.example b/deploy/systemd/frameflow-backup.env.example new file mode 100644 index 0000000..438aebc --- /dev/null +++ b/deploy/systemd/frameflow-backup.env.example @@ -0,0 +1,9 @@ +# Copy to /etc/frameflow/backup.env and keep it readable only by root and the +# FrameFlow service group. These paths must match the installed application, +# encrypted backup mount, and Node Exporter textfile collector configuration. +FRAMEFLOW_ENV_FILE=/srv/frameflow/.env.production +FRAMEFLOW_BACKUP_MOUNTPOINT=/mnt/encrypted-backups +FRAMEFLOW_BACKUP_DESTINATION=/mnt/encrypted-backups/frameflow +FRAMEFLOW_BACKUP_METRICS_DIR=/var/lib/frameflow/metrics +FRAMEFLOW_RESTORE_METRICS_DIR=/var/lib/frameflow/metrics +FRAMEFLOW_RESTORE_TIMEOUT_SECONDS=300 diff --git a/deploy/systemd/frameflow-backup.service b/deploy/systemd/frameflow-backup.service new file mode 100644 index 0000000..160eb77 --- /dev/null +++ b/deploy/systemd/frameflow-backup.service @@ -0,0 +1,35 @@ +[Unit] +Description=FrameFlow verified PostgreSQL, Redis, and MinIO backup +Documentation=file:///srv/frameflow/docs/deployment.md +Requires=docker.service +After=docker.service network-online.target +Wants=network-online.target +RequiresMountsFor=/mnt/encrypted-backups +AssertPathIsMountPoint=/mnt/encrypted-backups +ConditionPathExists=/srv/frameflow/scripts/scheduled-maintenance.sh +ConditionPathExists=/etc/frameflow/backup.env + +[Service] +Type=oneshot +User=frameflow +Group=frameflow +SupplementaryGroups=docker +EnvironmentFile=/etc/frameflow/backup.env +WorkingDirectory=/srv/frameflow +ExecStart=/srv/frameflow/scripts/scheduled-maintenance.sh backup +UMask=0077 +TimeoutStartSec=6h +Nice=10 +IOSchedulingClass=best-effort +IOSchedulingPriority=6 +NoNewPrivileges=true +PrivateTmp=true +ProtectHome=true +ProtectSystem=strict +ProtectControlGroups=true +ProtectKernelModules=true +ProtectKernelTunables=true +RestrictRealtime=true +RestrictSUIDSGID=true +LockPersonality=true +ReadWritePaths=/mnt/encrypted-backups/frameflow /var/lib/frameflow/metrics /var/run/docker.sock diff --git a/deploy/systemd/frameflow-backup.timer b/deploy/systemd/frameflow-backup.timer new file mode 100644 index 0000000..202dec2 --- /dev/null +++ b/deploy/systemd/frameflow-backup.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Run the FrameFlow verified backup every day + +[Timer] +OnCalendar=*-*-* 03:15:00 +RandomizedDelaySec=15m +AccuracySec=1m +Persistent=true +Unit=frameflow-backup.service + +[Install] +WantedBy=timers.target diff --git a/deploy/systemd/frameflow-restore-rehearsal.service b/deploy/systemd/frameflow-restore-rehearsal.service new file mode 100644 index 0000000..262bf59 --- /dev/null +++ b/deploy/systemd/frameflow-restore-rehearsal.service @@ -0,0 +1,36 @@ +[Unit] +Description=FrameFlow isolated restore rehearsal of the latest verified backup +Documentation=file:///srv/frameflow/docs/deployment.md +Requires=docker.service frameflow-backup.service +After=docker.service frameflow-backup.service network-online.target +Wants=network-online.target +RequiresMountsFor=/mnt/encrypted-backups +AssertPathIsMountPoint=/mnt/encrypted-backups +ConditionPathExists=/srv/frameflow/scripts/scheduled-maintenance.sh +ConditionPathExists=/etc/frameflow/backup.env + +[Service] +Type=oneshot +User=frameflow +Group=frameflow +SupplementaryGroups=docker +EnvironmentFile=/etc/frameflow/backup.env +WorkingDirectory=/srv/frameflow +ExecStart=/srv/frameflow/scripts/scheduled-maintenance.sh restore-latest +UMask=0077 +TimeoutStartSec=6h +Nice=10 +IOSchedulingClass=best-effort +IOSchedulingPriority=6 +NoNewPrivileges=true +PrivateTmp=true +ProtectHome=true +ProtectSystem=strict +ProtectControlGroups=true +ProtectKernelModules=true +ProtectKernelTunables=true +RestrictRealtime=true +RestrictSUIDSGID=true +LockPersonality=true +ReadOnlyPaths=/mnt/encrypted-backups/frameflow +ReadWritePaths=/var/lib/frameflow/metrics /var/run/docker.sock diff --git a/deploy/systemd/frameflow-restore-rehearsal.timer b/deploy/systemd/frameflow-restore-rehearsal.timer new file mode 100644 index 0000000..f59fdaf --- /dev/null +++ b/deploy/systemd/frameflow-restore-rehearsal.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Run a FrameFlow isolated restore rehearsal every month + +[Timer] +OnCalendar=*-*-01 05:15:00 +RandomizedDelaySec=30m +AccuracySec=1m +Persistent=true +Unit=frameflow-restore-rehearsal.service + +[Install] +WantedBy=timers.target diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..9a57775 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,324 @@ +name: ${COMPOSE_PROJECT_NAME:-frameflow-prod} + +x-server-image: &server-image + image: frameflow-server:${FRAMEFLOW_VERSION:-latest} + build: + context: . + dockerfile: Dockerfile.server + +x-server-environment: &server-environment + NODE_ENV: production + API_HOST: 0.0.0.0 + API_PORT: 8787 + API_PUBLIC_ORIGIN: ${API_PUBLIC_ORIGIN:?Set API_PUBLIC_ORIGIN} + WEB_ORIGIN: ${WEB_ORIGIN:?Set WEB_ORIGIN} + LOG_LEVEL: ${LOG_LEVEL:-info} + METRICS_HOST: 0.0.0.0 + WORKER_METRICS_PORT: 9092 + WORKER_HEARTBEAT_KEY: ${WORKER_HEARTBEAT_KEY:-frameflow:worker:heartbeat} + WORKER_HEARTBEAT_INTERVAL_MS: ${WORKER_HEARTBEAT_INTERVAL_MS:-5000} + WORKER_HEARTBEAT_TTL_SECONDS: ${WORKER_HEARTBEAT_TTL_SECONDS:-20} + METRICS_TOKEN: ${METRICS_TOKEN:-} + DATABASE_URL: ${DATABASE_URL:?Set DATABASE_URL} + REDIS_URL: ${REDIS_URL:?Set REDIS_URL} + JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET:?Set JWT_ACCESS_SECRET} + JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:?Set JWT_REFRESH_SECRET} + CREDENTIAL_ENCRYPTION_KEY: ${CREDENTIAL_ENCRYPTION_KEY:?Set CREDENTIAL_ENCRYPTION_KEY} + ACCESS_TOKEN_TTL: ${ACCESS_TOKEN_TTL:-15m} + REFRESH_TOKEN_TTL_DAYS: ${REFRESH_TOKEN_TTL_DAYS:-30} + EMAIL_VERIFICATION_REQUIRED: ${EMAIL_VERIFICATION_REQUIRED:-true} + EMAIL_VERIFICATION_TTL_HOURS: ${EMAIL_VERIFICATION_TTL_HOURS:-24} + PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-30} + RESEND_API_KEY: ${RESEND_API_KEY:?Set RESEND_API_KEY} + EMAIL_FROM: ${EMAIL_FROM:?Set EMAIL_FROM} + S3_ENDPOINT: http://minio:9000 + S3_PUBLIC_ENDPOINT: ${S3_PUBLIC_ENDPOINT:?Set S3_PUBLIC_ENDPOINT} + S3_REGION: ${S3_REGION:-us-east-1} + S3_BUCKET: ${S3_BUCKET:-frameflow} + S3_ACCESS_KEY: ${S3_ACCESS_KEY:?Set S3_ACCESS_KEY} + S3_SECRET_KEY: ${S3_SECRET_KEY:?Set S3_SECRET_KEY} + S3_FORCE_PATH_STYLE: "true" + OPENAI_API_KEY: ${OPENAI_API_KEY:-} + OPENAI_TEXT_MODEL: ${OPENAI_TEXT_MODEL:-gpt-5.6-sol} + OPENAI_IMAGE_MODEL: ${OPENAI_IMAGE_MODEL:-gpt-image-2} + OPENAI_TTS_MODEL: ${OPENAI_TTS_MODEL:-gpt-4o-mini-tts} + OPENAI_TTS_VOICE: ${OPENAI_TTS_VOICE:-alloy} + AGNES_API_KEY: ${AGNES_API_KEY:-} + AGNES_TEXT_MODEL: ${AGNES_TEXT_MODEL:-agnes-2.5-flash} + AGNES_IMAGE_MODEL: ${AGNES_IMAGE_MODEL:-agnes-image-2.1-flash} + AGNES_VIDEO_MODEL: ${AGNES_VIDEO_MODEL:-agnes-video-v2.0} + AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS: ${AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS:-900} + AGNES_VIDEO_POLL_INTERVAL_MS: ${AGNES_VIDEO_POLL_INTERVAL_MS:-4000} + GENERIC_TEXT_API_KEY: ${GENERIC_TEXT_API_KEY:-} + GENERIC_TEXT_BASE_URL: ${GENERIC_TEXT_BASE_URL:-} + GENERIC_TEXT_MODEL: ${GENERIC_TEXT_MODEL:-} + GENERIC_IMAGE_API_KEY: ${GENERIC_IMAGE_API_KEY:-} + GENERIC_IMAGE_BASE_URL: ${GENERIC_IMAGE_BASE_URL:-} + GENERIC_IMAGE_MODEL: ${GENERIC_IMAGE_MODEL:-} + GENERIC_VIDEO_API_KEY: ${GENERIC_VIDEO_API_KEY:-} + GENERIC_VIDEO_BASE_URL: ${GENERIC_VIDEO_BASE_URL:-} + GENERIC_VIDEO_MODEL: ${GENERIC_VIDEO_MODEL:-} + GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS: ${GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS:-900} + GENERIC_VIDEO_POLL_INTERVAL_MS: ${GENERIC_VIDEO_POLL_INTERVAL_MS:-4000} + REPLICATE_API_TOKEN: ${REPLICATE_API_TOKEN:-} + REPLICATE_IMAGE_VERSION: ${REPLICATE_IMAGE_VERSION:-} + REPLICATE_VIDEO_VERSION: ${REPLICATE_VIDEO_VERSION:-} + REPLICATE_LIPSYNC_VERSION: ${REPLICATE_LIPSYNC_VERSION:-} + REPLICATE_PREDICTION_DEADLINE_SECONDS: ${REPLICATE_PREDICTION_DEADLINE_SECONDS:-900} + STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY:-} + STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET:-} + STRIPE_PRO_PRICE_ID: ${STRIPE_PRO_PRICE_ID:-} + STRIPE_STUDIO_PRICE_ID: ${STRIPE_STUDIO_PRICE_ID:-} + STRIPE_PORTAL_CONFIGURATION_ID: ${STRIPE_PORTAL_CONFIGURATION_ID:-} + BILLING_SUCCESS_URL: ${BILLING_SUCCESS_URL:-} + BILLING_CANCEL_URL: ${BILLING_CANCEL_URL:-} + PUBLISHING_CONNECTOR_URL: ${PUBLISHING_CONNECTOR_URL:-} + PUBLISHING_CONNECTOR_SECRET: ${PUBLISHING_CONNECTOR_SECRET:-} + PUBLISHING_CONNECTOR_TIMEOUT_MS: ${PUBLISHING_CONNECTOR_TIMEOUT_MS:-30000} + FFMPEG_PATH: ffmpeg + FFPROBE_PATH: ffprobe + WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-2} + MAX_UPLOAD_BYTES: ${MAX_UPLOAD_BYTES:-104857600} + PROVIDER_DOWNLOAD_TIMEOUT_MS: ${PROVIDER_DOWNLOAD_TIMEOUT_MS:-180000} + PROVIDER_DOWNLOAD_MAX_REDIRECTS: ${PROVIDER_DOWNLOAD_MAX_REDIRECTS:-3} + +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: ${POSTGRES_DB:-frameflow} + POSTGRES_USER: ${POSTGRES_USER:-frameflow} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 5s + retries: 20 + restart: unless-stopped + + redis: + image: redis:7.4-alpine + environment: + REDIS_PASSWORD: ${REDIS_PASSWORD:?Set REDIS_PASSWORD} + command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD:?Set REDIS_PASSWORD}"] + volumes: + - redis_data:/data + healthcheck: + test: ["CMD-SHELL", "redis-cli -a \"$${REDIS_PASSWORD}\" ping | grep -q PONG"] + interval: 5s + timeout: 5s + retries: 20 + restart: unless-stopped + + minio: + image: minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e + command: server /data --console-address ":9001" + environment: + MINIO_ROOT_USER: ${S3_ACCESS_KEY:?Set S3_ACCESS_KEY} + MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:?Set S3_SECRET_KEY} + MINIO_API_CORS_ALLOW_ORIGIN: ${WEB_ORIGIN:?Set WEB_ORIGIN} + MINIO_PROMETHEUS_AUTH_TYPE: public + volumes: + - minio_data:/data + ports: + - "${MINIO_CONSOLE_BIND:-127.0.0.1}:${MINIO_CONSOLE_PORT:-9001}:9001" + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"] + interval: 5s + timeout: 5s + retries: 20 + restart: unless-stopped + + minio-init: + image: minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727 + depends_on: + minio: + condition: service_healthy + environment: + S3_BUCKET: ${S3_BUCKET:-frameflow} + S3_ACCESS_KEY: ${S3_ACCESS_KEY:?Set S3_ACCESS_KEY} + S3_SECRET_KEY: ${S3_SECRET_KEY:?Set S3_SECRET_KEY} + entrypoint: ["/bin/sh", "-c"] + command: + - >- + mc alias set local http://minio:9000 "$${S3_ACCESS_KEY}" "$${S3_SECRET_KEY}" && + mc mb --ignore-existing "local/$${S3_BUCKET}" && + mc anonymous set none "local/$${S3_BUCKET}" + restart: "no" + + config-check: + <<: *server-image + environment: *server-environment + command: ["node", "server/dist/config-check.js"] + read_only: true + tmpfs: + - /tmp:size=16m + restart: "no" + + migrate: + <<: *server-image + environment: *server-environment + command: ["node", "server/dist/db/migrate.js"] + depends_on: + config-check: + condition: service_completed_successfully + postgres: + condition: service_healthy + read_only: true + tmpfs: + - /tmp:size=128m + restart: "no" + + api: + <<: *server-image + environment: *server-environment + command: ["node", "server/dist/index.js"] + depends_on: + migrate: + condition: service_completed_successfully + redis: + condition: service_healthy + minio-init: + condition: service_completed_successfully + read_only: true + tmpfs: + - /tmp:size=512m + healthcheck: + test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8787/health/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] + interval: 10s + timeout: 5s + start_period: 15s + retries: 10 + restart: unless-stopped + + worker: + <<: *server-image + environment: *server-environment + command: ["node", "server/dist/worker.js"] + depends_on: + migrate: + condition: service_completed_successfully + redis: + condition: service_healthy + minio-init: + condition: service_completed_successfully + read_only: true + tmpfs: + - /tmp:size=4g + healthcheck: + test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:9092/health/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] + interval: 15s + timeout: 5s + start_period: 15s + retries: 10 + restart: unless-stopped + + web: + image: frameflow-web:${FRAMEFLOW_VERSION:-latest} + build: + context: . + dockerfile: Dockerfile.web + args: + VITE_API_URL: /api/v1 + environment: + APP_HOST: ${APP_HOST:?Set APP_HOST} + MEDIA_HOST: ${MEDIA_HOST:?Set MEDIA_HOST} + MAX_UPLOAD_SIZE: ${MAX_UPLOAD_SIZE:-100m} + ports: + - "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-8080}:80" + depends_on: + api: + condition: service_healthy + minio: + condition: service_healthy + restart: unless-stopped + + prometheus: + image: prom/prometheus:v3.5.0 + command: + - --config.file=/etc/prometheus/prometheus.yml + - --storage.tsdb.path=/prometheus + - --storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-30d} + volumes: + - ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml:ro + - ./deploy/alerts.yml:/etc/prometheus/alerts.yml:ro + - prometheus_data:/prometheus + ports: + - "${PROMETHEUS_BIND:-127.0.0.1}:${PROMETHEUS_PORT:-9090}:9090" + depends_on: + api: + condition: service_healthy + worker: + condition: service_healthy + minio: + condition: service_healthy + node-exporter: + condition: service_healthy + alertmanager: + condition: service_healthy + restart: unless-stopped + + node-exporter: + image: quay.io/prometheus/node-exporter:v1.9.1 + command: + - --path.rootfs=/host + - --collector.textfile.directory=/textfile + pid: host + volumes: + - /:/host:ro + - ${FRAMEFLOW_BACKUP_METRICS_DIR:-/var/lib/frameflow/metrics}:/textfile:ro + read_only: true + cap_drop: + - ALL + security_opt: + - no-new-privileges:true + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:9100/metrics"] + interval: 15s + timeout: 5s + start_period: 5s + retries: 10 + restart: unless-stopped + + alertmanager: + image: prom/alertmanager:v0.28.1 + environment: + ALERTMANAGER_WEBHOOK_URL: ${ALERTMANAGER_WEBHOOK_URL:?Set ALERTMANAGER_WEBHOOK_URL} + entrypoint: ["/bin/sh", "-ec"] + command: + - |- + case "$${ALERTMANAGER_WEBHOOK_URL}" in + https://*) ;; + *) echo "ALERTMANAGER_WEBHOOK_URL must use HTTPS" >&2; exit 1 ;; + esac + escaped_url=$$(printf '%s' "$${ALERTMANAGER_WEBHOOK_URL}" | sed 's/[\\&|]/\\&/g') + sed "s|__ALERTMANAGER_WEBHOOK_URL__|$${escaped_url}|g" /etc/alertmanager/alertmanager.yml.template > /tmp/alertmanager.yml + /bin/amtool check-config /tmp/alertmanager.yml + exec /bin/alertmanager \ + --config.file=/tmp/alertmanager.yml \ + --storage.path=/alertmanager \ + --enable-feature=receiver-name-in-metrics + volumes: + - ./deploy/alertmanager.yml.template:/etc/alertmanager/alertmanager.yml.template:ro + - alertmanager_data:/alertmanager + ports: + - "${ALERTMANAGER_BIND:-127.0.0.1}:${ALERTMANAGER_PORT:-9093}:9093" + read_only: true + tmpfs: + - /tmp:size=16m + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:9093/-/ready"] + interval: 10s + timeout: 5s + start_period: 5s + retries: 10 + restart: unless-stopped + +volumes: + postgres_data: + redis_data: + minio_data: + prometheus_data: + alertmanager_data: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..63fc37b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,69 @@ +name: frameflow + +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: frameflow + POSTGRES_USER: frameflow + POSTGRES_PASSWORD: frameflow + ports: + - "54329:5432" + volumes: + - frameflow_postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U frameflow -d frameflow"] + interval: 3s + timeout: 3s + retries: 20 + restart: unless-stopped + + redis: + image: redis:7.4-alpine + command: ["redis-server", "--appendonly", "yes"] + ports: + - "63799:6379" + volumes: + - frameflow_redis:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 3s + timeout: 3s + retries: 20 + restart: unless-stopped + + minio: + image: minio/minio:latest + command: server /data --console-address ":9001" + environment: + MINIO_ROOT_USER: frameflow + MINIO_ROOT_PASSWORD: frameflow-local-secret + ports: + - "9000:9000" + - "9001:9001" + volumes: + - frameflow_minio:/data + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 3s + timeout: 3s + retries: 20 + restart: unless-stopped + + minio-init: + image: minio/mc:latest + depends_on: + minio: + condition: service_healthy + entrypoint: >- + /bin/sh -c " + mc alias set local http://minio:9000 frameflow frameflow-local-secret && + mc mb --ignore-existing local/frameflow && + mc anonymous set none local/frameflow + " + restart: "no" + +volumes: + frameflow_postgres: + frameflow_redis: + frameflow_minio: diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..f646a73 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,350 @@ +# Production deployment + +The production stack contains Nginx, the React web build, the Fastify API, a BullMQ worker, PostgreSQL, Redis, MinIO, Prometheus, and Alertmanager. API and storage services are not published directly. Nginx routes the application host to the SPA/API and the media host to MinIO. + +## Prerequisites + +- Docker Engine with Compose v2 +- Two DNS records pointing to the deployment host, such as `studio.example.com` and `media.example.com` +- An HTTPS reverse proxy or load balancer in front of port `8080` +- OpenAI and Replicate credentials for real generation jobs +- A Stripe account, recurring Price IDs, and webhook signing secret when subscription billing is enabled +- An HTTPS operator webhook that accepts Alertmanager webhook payloads +- An encrypted off-host destination for daily backups + +Both public hosts must be forwarded to the same Nginx port with the original `Host` header preserved. TLS is required because production refresh cookies are secure. `S3_PUBLIC_ENDPOINT` must exactly match the public media origin; providers and browsers cannot use the private `http://minio:9000` address. + +Production registration requires verified email by default. Configure `RESEND_API_KEY` and a verified `EMAIL_FROM` sender before startup; password-reset, verification, and workspace-invitation links use the first origin in `WEB_ORIGIN` as their public base URL. Workspace invitations remain valid when email delivery fails and the API returns a one-time manual link, but operators should treat a `FAILED` delivery result as an email-provider incident rather than asking the inviter to recreate the workspace. + +Subscription billing remains read-only when Stripe is not configured. To enable checkout, set `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_PRO_PRICE_ID`, and `STRIPE_STUDIO_PRICE_ID`, then register `https://studio.example.com/api/v1/billing/webhooks/stripe` for `checkout.session.completed` and `customer.subscription.created`, `customer.subscription.updated`, and `customer.subscription.deleted`. Configure the Stripe Customer Portal before exposing subscription management; `STRIPE_PORTAL_CONFIGURATION_ID` is optional when the account default configuration is used. + +Before enabling billing, run the read-only Stripe resource smoke. It never creates a customer, session, charge, subscription, or event. Use `--require-live` for the production account: + +```bash +FRAMEFLOW_STRIPE_APP_ORIGIN=https://studio.example.com \ +STRIPE_SECRET_KEY='use-the-secret-store-value' \ +STRIPE_WEBHOOK_SECRET='use-the-secret-store-value' \ +STRIPE_PRO_PRICE_ID=price_replace_with_pro \ +STRIPE_STUDIO_PRICE_ID=price_replace_with_studio \ +STRIPE_PORTAL_CONFIGURATION_ID=bpc_replace_when_not_using_default \ + npm run smoke:stripe -- --require-live --json +``` + +The smoke retrieves the current account, expands both configured Products from their recurring Prices, validates active licensed recurring billing and live/test mode consistency, finds the explicit or default active Customer Portal configuration, and locates the exact enabled FrameFlow webhook with all four required events. The secret key and webhook signing secret are read only from the environment and are never printed. Stripe does not expose an endpoint's signing secret through its API, so this check can prove that `STRIPE_WEBHOOK_SECRET` is configured but cannot prove it belongs to the discovered endpoint. Complete one signed test subscription event through the FrameFlow webhook and confirm the workspace plan/credit update before accepting billing. + +## Publishing connector + +Direct delivery to Douyin, Kuaishou, Bilibili, and Xiaohongshu is intentionally isolated behind an operator-owned connector. The connector holds platform application credentials and translates the stable FrameFlow contract into each platform's OAuth, upload, polling, and token-refresh APIs. Without it, download delivery remains available and the publishing UI reports every external channel as not configured. + +Configure these values together: + +- `API_PUBLIC_ORIGIN`: the public HTTPS FrameFlow API origin used to build OAuth and status callback URLs. +- `CREDENTIAL_ENCRYPTION_KEY`: a production-only secret of at least 32 characters used to encrypt channel access tokens, refresh tokens, and OAuth PKCE verifiers at rest. +- `PUBLISHING_CONNECTOR_URL`: the connector's public HTTPS origin. +- `PUBLISHING_CONNECTOR_SECRET`: a shared secret of at least 24 characters. FrameFlow sends it as `Authorization: Bearer ` and also uses it to verify connector callbacks. +- `PUBLISHING_CONNECTOR_TIMEOUT_MS`: timeout for each connector request, from 1,000 to 120,000 milliseconds. + +Every connector request is JSON and includes `platform`, one of `DOUYIN`, `KUAISHOU`, `BILIBILI`, or `XIAOHONGSHU`. The connector must expose: + +- `POST /v1/oauth/authorize`: accepts `{ platform, state, callbackUrl }`; returns `{ authorizationUrl, codeVerifier? }`. The platform must return the supplied `state` to `callbackUrl`. +- `POST /v1/oauth/exchange`: accepts `{ platform, code, callbackUrl, codeVerifier? }`; returns `{ externalAccountId, displayName, avatarUrl?, accessToken, refreshToken?, tokenExpiresAt?, scopes?, metadata? }`. +- `POST /v1/oauth/revoke`: accepts `{ platform, externalAccountId, accessToken, refreshToken? }`; returns `{ revoked: boolean }`. +- `POST /v1/publish`: accepts `{ platform, deliveryId, sourceUrl, callbackUrl, account, destination }`; returns `{ status, externalId, publishedUrl?, credentials? }`. `status` is `PUBLISHING` for asynchronous processing or `PUBLISHED` only when the platform has confirmed publication. `sourceUrl` is a short-lived signed media URL and must not be persisted or logged. + +For asynchronous work, POST status events to the supplied FrameFlow `callbackUrl` with this body: + +```json +{ + "eventId": "provider-unique-event-id", + "platform": "DOUYIN", + "deliveryId": "00000000-0000-0000-0000-000000000000", + "externalId": "platform-video-id", + "status": "PUBLISHED", + "occurredAt": "2026-07-31T12:00:00.000Z", + "publishedUrl": "https://platform.example/video/123" +} +``` + +`status` may be `PUBLISHING`, `PUBLISHED`, or `FAILED`; include `errorMessage` for failures. Sign the exact raw JSON bytes with HMAC-SHA256 using `PUBLISHING_CONNECTOR_SECRET`, and send the lowercase hexadecimal digest as `x-frameflow-signature: sha256=`. FrameFlow deduplicates events by platform and event ID, rejects stale or mismatched events, and never allows a terminal delivery to regress. + +Before enabling a channel in production, bind and revoke a dedicated test account, publish an approved test render, wait for a signed terminal callback, open the returned platform URL, verify title/description/visibility/tags/schedule behavior, and confirm that refreshed credentials remain usable. Configuration-only readiness or a successful queue submission is not acceptance evidence. + +## Continuous integration + +`.github/workflows/ci.yml` provides two required pre-deployment checks. The verification job starts isolated PostgreSQL, Redis, and MinIO services, applies every migration, runs all web and server tests, creates a real backup of those services, restores it through the isolated rehearsal path, builds both applications, and audits production dependencies. The container job validates the production Compose model, builds the server and web images, confirms a synthetic safe production configuration is accepted, and confirms `.env.production.example` is rejected because it still contains placeholders. + +The synthetic values exist only inside the CI runner and are not deployment secrets. CI proves the repository is internally buildable and the safety gate works; it does not prove external provider credentials, public TLS/media routing, email delivery, billing webhooks, alert delivery, or cloud generation jobs. Complete the live checks below for every release candidate deployed to a real environment. + +## Production smoke test + +Use a dedicated, verified account with the `OWNER` or `ADMIN` role. The smoke runner accepts its password only through the environment, requires HTTPS outside localhost, and does not disable certificate validation. Its default mode never starts OpenAI or Replicate jobs. It performs these checks through the public application origin: + +- API liveness plus PostgreSQL, Redis, object-storage, and worker readiness +- authenticated service readiness including FFmpeg, AI configuration, and any persisted provider-verification state without starting a new provider request +- billing/usage read-model access +- project, episode, immutable script, asset, and shot-version persistence +- multipart object upload plus signed-download SHA-256 integrity +- a real Redis/BullMQ worker health job +- a 640x360 FFmpeg render, immutable source manifest, SRT/VTT sidecars, and signed video download +- render review approval, audit-log persistence, download delivery, redirect handling, and delivered-video integrity +- durable render/delivery notifications, user scoping, and persisted read state + +```bash +FRAMEFLOW_SMOKE_BASE_URL=https://studio.example.com \ +FRAMEFLOW_SMOKE_EMAIL=production-smoke@example.com \ +FRAMEFLOW_SMOKE_PASSWORD='use-the-secret-store-value' \ +FRAMEFLOW_SMOKE_WORKSPACE_ID=00000000-0000-0000-0000-000000000000 \ + npm run smoke:production -- --json +``` + +The workspace ID is optional when the account belongs to exactly one workspace. The default per-job timeout is 180 seconds and can be changed with `--timeout-seconds`. The test creates a uniquely marked project and archives it in a `finally` cleanup path on success or failure; use `--keep-project` only for diagnosis. Archiving preserves its database history and private media objects, so apply an operator-reviewed retention policy to old `[SMOKE]` projects rather than granting the test runner destructive storage permissions. + +For local-only verification, explicitly allow an HTTP loopback origin: + +```bash +FRAMEFLOW_SMOKE_BASE_URL=http://127.0.0.1:8787 \ +FRAMEFLOW_SMOKE_ALLOW_HTTP=true \ +FRAMEFLOW_SMOKE_EMAIL=studio@frameflow.local \ +FRAMEFLOW_SMOKE_PASSWORD='FrameFlow2026!' \ + npm run smoke:production -- --timeout-seconds 120 +``` + +A passing default report proves the local production path, storage, queue, render, review, and delivery adapters worked for that deployment. It never contacts an AI provider. AI readiness is configuration-only unless an owner or administrator previously completed the provider connection check; persisted connection status still does not replace the billable generation acceptance run. + +To validate the live provider path, add `--include-ai` and the exact billable-charge acknowledgement. Both are required; setting the environment acknowledgement alone never enables provider calls. Run this only in a workspace where test media and provider charges are acceptable: + +```bash +FRAMEFLOW_SMOKE_BASE_URL=https://studio.example.com \ +FRAMEFLOW_SMOKE_EMAIL=production-smoke@example.com \ +FRAMEFLOW_SMOKE_PASSWORD='use-the-secret-store-value' \ +FRAMEFLOW_SMOKE_WORKSPACE_ID=00000000-0000-0000-0000-000000000000 \ +FRAMEFLOW_SMOKE_BILLABLE_AI_ACK=I_ACCEPT_BILLABLE_AI_CHARGES \ +FRAMEFLOW_SMOKE_AI_VIDEO_SECONDS=5 \ + npm run smoke:production -- --include-ai --json +``` + +The live preflight runs before project creation and requires all seven workflows (`script`, `storyboard`, `image-openai`, `image-replicate`, `tts`, `video`, and `lipsync`) to be `CONFIGURED`, plus at least 700 remaining workspace credits. It then creates one OpenAI character image, one Replicate consistency variant, an OpenAI script and storyboard, OpenAI speech, Replicate video and lipsync media, and an FFmpeg render. Every provider job uses `maxAttempts: 1`; the report verifies stored media, provider/model attribution, the final render, and one usage-ledger entry per provider job. The uniquely marked smoke project is archived in the same cleanup path used by default mode unless `--keep-project` is supplied. + +`FRAMEFLOW_SMOKE_AI_VIDEO_SECONDS` accepts 1 to 30 seconds and defaults to 5. Some configured Replicate model versions require additional input fields. Supply only fields documented by those exact model versions as JSON objects through `FRAMEFLOW_SMOKE_VIDEO_PARAMS_JSON` and `FRAMEFLOW_SMOKE_LIPSYNC_PARAMS_JSON`; the runner rejects malformed JSON and arrays before login. Leave them unset when the selected versions need no extra parameters. Do not put provider tokens or other secrets in these JSON values or command-line arguments. + +Example Caddy routing in front of the stack: + +```caddyfile +studio.example.com { + reverse_proxy 127.0.0.1:8080 +} + +media.example.com { + reverse_proxy 127.0.0.1:8080 +} +``` + +The web client keeps one authenticated server-sent event stream open at `/api/v1/workspaces/:workspaceId/events`. The supplied API response disables proxy buffering and sends a heartbeat every 20 seconds. Preserve the `X-Accel-Buffering: no` response header, keep the upstream read timeout above 60 seconds, and do not enable response caching or compression that buffers `text/event-stream`. Notification history and read state are persisted in PostgreSQL, so reconnecting clients recover missed events through the regular notification endpoint; the existing task poller remains a degraded-mode fallback when streaming is unavailable. + +## First deployment + +1. Create the production environment file and replace every placeholder secret. + + ```bash + cp .env.production.example .env.production + openssl rand -hex 32 + ``` + +2. Create the host directory shared by the backup script and Node Exporter. If `FRAMEFLOW_BACKUP_METRICS_DIR` is changed in `.env.production`, use the same path here and in the backup scheduler environment. + + ```bash + sudo install -d -m 0755 -o "$(id -un)" -g "$(id -gn)" /var/lib/frameflow/metrics + ``` + +3. Validate interpolation, build the lightweight configuration gate, and run it before starting any stateful application service. + + ```bash + docker compose --env-file .env.production -f docker-compose.prod.yml config --quiet + docker compose --env-file .env.production -f docker-compose.prod.yml build config-check + docker compose --env-file .env.production -f docker-compose.prod.yml run --rm --no-deps config-check + ``` + + The gate rejects development defaults, placeholder credentials, identical JWT signing secrets, localhost or non-HTTPS public endpoints, unauthenticated database/Redis URLs, Replicate model versions without a token, and partially configured Stripe billing. It prints only a sanitized capability summary and never logs credential values. The migration service also depends on this check, so an unsafe configuration cannot migrate or start the API through the supplied Compose stack. + +4. Build and start the stack. Database migrations and bucket initialization run as one-shot dependencies before the API and worker start. + + ```bash + docker compose --env-file .env.production -f docker-compose.prod.yml up -d --build + docker compose --env-file .env.production -f docker-compose.prod.yml ps + ``` + +5. Verify public and internal health. + + ```bash + curl -fsS https://studio.example.com/health/live + curl -fsS https://studio.example.com/health/ready + docker compose --env-file .env.production -f docker-compose.prod.yml exec api node -e "fetch('http://127.0.0.1:8787/health/ready').then(r=>r.text()).then(console.log)" + docker compose --env-file .env.production -f docker-compose.prod.yml exec worker node -e "fetch('http://127.0.0.1:9092/health/ready').then(r=>r.text()).then(console.log)" + ``` + + API readiness includes PostgreSQL, Redis, object storage, and the Redis-backed worker heartbeat. A running API returns `503 not_ready` when the generation worker is absent or stale, so the web service is not promoted while production jobs cannot run. + +6. Create the first workspace owner through the registration API, then use that account on the login screen. + + ```bash + curl -fsS https://studio.example.com/api/v1/auth/register \ + -H 'content-type: application/json' \ + --data '{"email":"owner@example.com","password":"replace-with-a-long-password","displayName":"Studio Owner","workspaceName":"My Studio"}' + ``` + +Public registration should be disabled or protected at the edge after account provisioning when operating an invite-only deployment. + +## Media and model checks + +MinIO CORS is restricted to `WEB_ORIGIN` for browser requests. CORS does not make objects public; every object remains private and requires a short-lived signature. + +Before accepting production work, verify one job of every configured provider type: + +- script generation and storyboard generation +- character image generation using reference asset versions +- speech generation +- image-to-video generation +- lipsync generation +- episode render, immutable source-manifest capture, SRT/VTT subtitle download, and approved video delivery + +Workspace owners and administrators can run a non-generating connection check from the AI Services page. OpenAI verification retrieves every distinct configured text, image, and speech model through the Models API. Replicate verification reads the authenticated account endpoint, so it proves the token is accepted but does not prove that a configured model version can complete a prediction. Results are stored per workspace, audited, and automatically ignored after a credential or model configuration change. Provider response bodies and credentials are never stored. Complete the live billable workflow below before treating generation as accepted. + +Replicate must be able to fetch the public media origin over HTTPS. Provider output downloads are accepted only from public HTTPS addresses; every redirect is revalidated, streamed data is capped by `MAX_UPLOAD_BYTES`, and `PROVIDER_DOWNLOAD_TIMEOUT_MS` plus `PROVIDER_DOWNLOAD_MAX_REDIRECTS` bound stalled or redirecting responses. Do not mark provider validation complete when only queue creation succeeds; inspect the resulting media and usage ledger entry. + +`REPLICATE_PREDICTION_DEADLINE_SECONDS` controls both the local polling deadline and Replicate's `Cancel-After` deadline. It accepts 5 to 86,400 seconds and defaults to 900. Set it high enough for the selected model versions, but keep it bounded so a worker timeout does not leave a remote prediction running and accruing charges. + +## Monitoring + +Prometheus listens on `127.0.0.1:9090` by default and scrapes API, worker, host, and MinIO metrics over the private Compose network. MinIO's metrics endpoint is unauthenticated only inside that network; Nginx returns `404` for both v2 and v3 metrics paths on the public media host. Alertmanager listens on `127.0.0.1:9093` and sends grouped firing and resolved notifications to `ALERTMANAGER_WEBHOOK_URL`. The URL is rendered into a temporary in-container config and must use HTTPS. Keep `METRICS_TOKEN` empty with the supplied scrape configuration. If metrics are exposed outside the Compose network, configure a token and update Prometheus authorization at the same time. + +Useful checks: + +```bash +curl -fsS http://127.0.0.1:9090/-/ready +curl -fsS http://127.0.0.1:9093/-/ready +curl -fsS 'http://127.0.0.1:9090/api/v1/targets' +curl -fsS 'http://127.0.0.1:9090/api/v1/rules' +curl -fsS 'http://127.0.0.1:9090/api/v1/alerts' +curl -fsS 'http://127.0.0.1:9090/api/v1/alertmanagers' +docker compose --env-file .env.production -f docker-compose.prod.yml logs --since=30m api worker node-exporter prometheus alertmanager +``` + +The supplied `deploy/alerts.yml` rules cover API/worker/exporter disappearance, stale worker heartbeat, dependency readiness, host and PostgreSQL-volume disk pressure, MinIO usable capacity, backup age, restore-rehearsal age, API error rate and latency, generation failure rate, and queue delay. Prometheus evaluates these rules and routes alerts to the bundled Alertmanager. The exact `FrameFlowDeliveryTest` alert uses a dedicated one-second group wait and five-second group interval so production acceptance does not change the timing of operational alerts. + +Run the controlled delivery smoke before launch. The exact acknowledgement is required because this command sends real firing and resolved notifications to the configured operator webhook: + +```bash +FRAMEFLOW_ALERTMANAGER_URL=http://127.0.0.1:9093 \ +FRAMEFLOW_ALERT_TEST_ACK=I_ACCEPT_TEST_ALERT_NOTIFICATIONS \ + npm run smoke:alertmanager -- --json +``` + +The production Alertmanager enables its supported `receiver-name-in-metrics` feature so the command can scope notification counters to `frameflow-operator-webhook`. The command records those counters, posts a uniquely labeled firing alert, waits for the alert to become active and for a successful webhook attempt, resolves the same alert, then waits for both the inactive state and a second successful webhook attempt. It fails when Alertmanager reports a failed notification and always attempts to resolve a firing test alert after an intermediate error. A passing result proves that the webhook returned success for both payloads. Use the returned `testId` to confirm the receiver performed its own downstream processing; Alertmanager cannot prove work performed after the receiver acknowledged the HTTP request. + +## Backups + +The backup script creates a PostgreSQL custom-format dump plus Redis and MinIO volume archives, then writes checksums. Before publishing success metrics it runs the read-only backup verifier, which checks the required file set, manifest shape, exact checksum inventory, PostgreSQL custom-format signature, readable gzip archives, and unsafe absolute or parent-directory archive paths. Only after every check succeeds does it atomically publish backup timestamp, duration, and size metrics for Node Exporter. Run it from the repository root or a daily scheduler with an explicit off-host destination. A failed run leaves the previous success timestamp unchanged so the stale-backup alert can fire. + +```bash +FRAMEFLOW_ENV_FILE=/srv/frameflow/.env.production \ +FRAMEFLOW_BACKUP_METRICS_DIR=/var/lib/frameflow/metrics \ + /srv/frameflow/scripts/backup.sh /mnt/encrypted-backups/frameflow +``` + +After the first successful backup, verify the metric through Prometheus: + +```bash +curl -fsS --get http://127.0.0.1:9090/api/v1/query \ + --data-urlencode 'query=frameflow_backup_last_success_timestamp_seconds' +``` + +Copy completed backup directories off the application host. A local Docker volume is not a disaster-recovery backup. Test checksum validation and restore into an isolated Compose project on a regular schedule. + +### Scheduled backup and restore rehearsal + +The supplied systemd units assume a system Docker daemon, an application checkout at `/srv/frameflow`, a `frameflow` service account with supplementary membership in the `docker` group, an encrypted mount at `/mnt/encrypted-backups`, and the standard metrics directory. Change every matching path in both service units when the host layout differs; changing only the environment file is insufficient because the systemd filesystem allowlist and mount assertion are intentionally explicit. + +Create the service account according to the host's account-management policy, mount the encrypted off-host filesystem through `/etc/fstab` or a dedicated mount unit, then install the configuration: + +```bash +sudo install -d -m 0750 -o root -g frameflow /etc/frameflow +sudo install -d -m 0750 -o frameflow -g frameflow /var/lib/frameflow/metrics +sudo install -d -m 0700 -o frameflow -g frameflow /mnt/encrypted-backups/frameflow +sudo chown root:frameflow /srv/frameflow/.env.production +sudo chmod 0640 /srv/frameflow/.env.production +sudo install -m 0640 -o root -g frameflow \ + deploy/systemd/frameflow-backup.env.example /etc/frameflow/backup.env +sudo install -m 0644 deploy/systemd/*.service deploy/systemd/*.timer /etc/systemd/system/ +sudoedit /etc/frameflow/backup.env +sudo systemd-analyze verify \ + /etc/systemd/system/frameflow-backup.service \ + /etc/systemd/system/frameflow-backup.timer \ + /etc/systemd/system/frameflow-restore-rehearsal.service \ + /etc/systemd/system/frameflow-restore-rehearsal.timer +sudo systemctl daemon-reload +sudo systemctl enable --now frameflow-backup.timer frameflow-restore-rehearsal.timer +``` + +`scheduled-maintenance.sh` resolves both configured paths, rejects relative paths, root, whitespace, symbolic links, destinations outside the mount, and inactive mount points. This prevents an unavailable encrypted mount from silently redirecting backups onto the application host. The monthly restore unit requires the daily backup service and waits for a fresh successful backup before selecting the newest timestamped directory. It verifies that directory once before the restore script verifies it again immediately before any Docker call. + +Run both units manually during first deployment and inspect their logs and timers: + +```bash +sudo systemctl start frameflow-backup.service +sudo systemctl start frameflow-restore-rehearsal.service +sudo systemctl status frameflow-backup.service frameflow-restore-rehearsal.service +sudo systemctl list-timers frameflow-backup.timer frameflow-restore-rehearsal.timer +journalctl -u frameflow-backup.service -u frameflow-restore-rehearsal.service --since today +``` + +The units intentionally do not delete old backups. Apply an operator-reviewed retention or immutable-storage lifecycle policy at the off-host destination, and keep at least one verified recovery point outside that policy's deletion window. + +Re-run verification after every off-host transfer and before any restore: + +```bash +./scripts/verify-backup.sh /mnt/encrypted-backups/frameflow/frameflow-20260731T040000Z +``` + +Verification is read-only and does not connect to or modify the running stack. Do not proceed when it reports a checksum, manifest, dump-format, or archive-path failure. + +At least monthly, restore a recently transferred backup into the isolated rehearsal environment: + +```bash +FRAMEFLOW_RESTORE_METRICS_DIR=/var/lib/frameflow/metrics \ + npm run restore:rehearse -- \ + /mnt/encrypted-backups/frameflow/frameflow-20260731T040000Z +``` + +The rehearsal verifies the backup before making any Docker call. It creates a randomly named internal network, three new empty volumes, and temporary PostgreSQL, Redis, and MinIO containers without publishing host ports. Every resource carries both a restore-rehearsal marker and a run-specific label. Cleanup rechecks both labels and refuses to remove a resource if either label differs, so the script never removes the live Compose project or an unrelated similarly named resource. + +PostgreSQL validation restores the custom-format dump with `--exit-on-error`, checks migration history and core tables, and queries representative business tables. Redis validation loads the restored persistence, checks `PING`, `DBSIZE`, loading state, and AOF health. MinIO validation starts the production-pinned server image and uses the pinned `mc` client to check administrative readiness and list restored buckets and objects. On success, the script cleans the temporary resources and atomically publishes timestamp, duration, PostgreSQL table-count, Redis key-count, and MinIO object-count metrics for Node Exporter. + +Failed rehearsals are cleaned automatically. For incident diagnosis only, add `--keep-on-failure`; the command prints the exact retained resource names and label values. Inspect those labels before manually removing anything. The `FrameFlowRestoreRehearsalStale` alert fires when no successful rehearsal metric exists or the last success is older than 35 days. + +Verify both disaster-recovery freshness metrics through Prometheus: + +```bash +curl -fsS --get http://127.0.0.1:9090/api/v1/query \ + --data-urlencode 'query={__name__=~"frameflow_(backup|restore_rehearsal)_last_success_timestamp_seconds"}' +``` + +For recovery, stop application writers first: + +```bash +docker compose --env-file .env.production -f docker-compose.prod.yml stop web api worker +``` + +Restore `postgres.dump` with `pg_restore` and unpack the Redis/MinIO archives only into newly created, empty recovery volumes. Restoring volume archives over live data can leave stale objects and is not supported. Start dependencies, run the `migrate` service, then start API, worker, and web and complete the media/model checks above. + +## Upgrades + +Use an immutable `FRAMEFLOW_VERSION`, build the new images, take a backup, and then recreate services. The migration job completes before new API and worker containers become healthy. + +```bash +./scripts/backup.sh /mnt/encrypted-backups/frameflow +docker compose --env-file .env.production -f docker-compose.prod.yml build +docker compose --env-file .env.production -f docker-compose.prod.yml up -d +docker compose --env-file .env.production -f docker-compose.prod.yml ps +``` + +Rollback application images only after confirming that the new migration remains backward compatible. Restore the database from backup when a migration is not reversible. diff --git a/index.html b/index.html new file mode 100644 index 0000000..12e7cca --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + + FrameFlow AI 漫剧工场 + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cfb4d66 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6502 @@ +{ + "name": "frameflow-ai-comic-studio", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frameflow-ai-comic-studio", + "version": "0.1.0", + "workspaces": [ + "server" + ], + "dependencies": { + "@vitejs/plugin-react": "latest", + "concurrently": "^9.2.1", + "lucide-react": "latest", + "react": "latest", + "react-dom": "latest", + "typescript": "latest", + "vite": "latest" + }, + "devDependencies": { + "vitest": "^3.2.4" + } + }, + "node_modules/@aws-sdk/checksums": { + "version": "3.1000.23", + "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.23.tgz", + "integrity": "sha512-Hv4VX5+IdDYmAbOdiwZguz8fLh3WnE4VtyJwVNEHLulA+OYy7Z5L0ETGUlX2T4g8DLO8XxCV8CyWrtVL4uwqkg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.1098.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1098.0.tgz", + "integrity": "sha512-6Z53QG2jdujsCt3eHO2cjCpdfvz2Pgs+hP/NINuGONZUJmdrHLLDvWM9F114Yq0NPIGtk+yA/GCjG3XiUhw+gA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/checksums": "^3.1000.23", + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/credential-provider-node": "^3.972.75", + "@aws-sdk/middleware-sdk-s3": "^3.972.69", + "@aws-sdk/signature-v4-multi-region": "^3.996.43", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/fetch-http-handler": "^5.6.13", + "@smithy/node-http-handler": "^4.9.13", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.977.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.977.3.tgz", + "integrity": "sha512-6YZTpF5Zzl0KdSrztM0l6ErKdnXrnnodIDYfayHE9SFfZU8Ubxls7H2XnfWT121jgwiG+WP1z5kyfVDsH5V4qA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@aws-sdk/xml-builder": "^3.972.37", + "@aws/lambda-invoke-store": "^0.3.0", + "@smithy/core": "^3.31.1", + "@smithy/signature-v4": "^5.6.12", + "@smithy/types": "^4.16.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.64", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.64.tgz", + "integrity": "sha512-14kkR5aj1c7D+cYCrEcG2W3xw87wMYAEUeB/tMiQ2j0RVKzzdewd4mJw1+Q0JVLr4IFU1JHGDCyj0WqLrtIixg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.66", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.66.tgz", + "integrity": "sha512-BrZxoXScBZ+nTOYy388zHkz1n5cS8C+uGFMozD4w9OKEWMq39Cu/9l/k385Hb54dtv0VIeh12f8h67o3xDNH9g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/fetch-http-handler": "^5.6.13", + "@smithy/node-http-handler": "^4.9.13", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.973.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.9.tgz", + "integrity": "sha512-d/mMvS+sQjSWNA6+JCldK1YB/jQmtoWM8Izj10mrOZdRCeWNVb8IYQuuyHHKKKXcpGo5Pd0LIK6onHbLvlhuVQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/credential-provider-env": "^3.972.64", + "@aws-sdk/credential-provider-http": "^3.972.66", + "@aws-sdk/credential-provider-login": "^3.972.71", + "@aws-sdk/credential-provider-process": "^3.972.64", + "@aws-sdk/credential-provider-sso": "^3.973.8", + "@aws-sdk/credential-provider-web-identity": "^3.972.70", + "@aws-sdk/nested-clients": "^3.997.38", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/credential-provider-imds": "^4.4.16", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.71", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.71.tgz", + "integrity": "sha512-l93922lXnTs5RjM3QrMCXSmXiEgLFLaQ0Lco9F3tJ08o0mzGdAj6m2nAXDuTMHoUuL0u7RKmrhm+Z8/7GCilyg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/nested-clients": "^3.997.38", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.75", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.75.tgz", + "integrity": "sha512-sdFhR4E3HWZefGL6OsBhxqXdqtFvxGOh8VLfiu9yttPgVNcpEozEDPmrTYmXA3CIf6npUETVLveQPGQ7GBzVhg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.64", + "@aws-sdk/credential-provider-http": "^3.972.66", + "@aws-sdk/credential-provider-ini": "^3.973.9", + "@aws-sdk/credential-provider-process": "^3.972.64", + "@aws-sdk/credential-provider-sso": "^3.973.8", + "@aws-sdk/credential-provider-web-identity": "^3.972.70", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/credential-provider-imds": "^4.4.16", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.64", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.64.tgz", + "integrity": "sha512-Q5noG5vfFo++bUaLGcjj8OHX5tmwa1O/5nDVMeaSSZgjzgvWbW6tgu/gSa+aENwcJXjoXDQh+8TRZR2zHds/aw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.8.tgz", + "integrity": "sha512-37okeZyRdVkGrU6nyKBPGqQvyl/7CEiMpUVOb0+BCNCIR0VAuBxNgjMb0mnsR1EXm8dqQFfQZOJ5YW/0sBfa1w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/nested-clients": "^3.997.38", + "@aws-sdk/token-providers": "3.1098.0", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.70", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.70.tgz", + "integrity": "sha512-Ps/f9USafScb6CSQTRPNMzdKL5x5XRwDIRgFvnuFWfClGZe7/fI7iCFqXdxKjc9LBxP28E7iUgNloGgfgw406w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/nested-clients": "^3.997.38", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.69", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.69.tgz", + "integrity": "sha512-ziSQA8AkB+u4K/5t/SStFbeoiNTG04reUeddCLNCAgmdRJGQ3+MJcpZOXXLdD6uyfCqSK1/R6004gRdXvHbYQA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/signature-v4-multi-region": "^3.996.43", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.38.tgz", + "integrity": "sha512-jQDs+nxnmgo4+WPOmY373HIC8jx4KyYYMYDI74FWrzX3Ba9fYsV0dSA+7PNYNkhRbbRCRLre83tQ31F1ACCHkA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/signature-v4-multi-region": "^3.996.43", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/fetch-http-handler": "^5.6.13", + "@smithy/node-http-handler": "^4.9.13", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/s3-request-presigner": { + "version": "3.1098.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1098.0.tgz", + "integrity": "sha512-1FQp9O22rWMGBhLZI/fP14kVoxsylk4b8yHh3n78pbTvo1+NUEoe5gG4tFLTz+p6UpCna5qqjp28VlSJO3v8fA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/signature-v4-multi-region": "^3.996.43", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.43", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.43.tgz", + "integrity": "sha512-lKekx8bLBXSv4O+cslk9Zfnw2XKSkWBs3uWL5QGhH2ZAQfNS7FE0vcSSN2vD/AhxX54ZTywWxR4STThoeOXlBA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.2", + "@smithy/signature-v4": "^5.6.12", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1098.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1098.0.tgz", + "integrity": "sha512-6cFAviffeqYGjrXn4FqGbWcTxB3nbpBpQXUm6MvnrWZThJaVBTHHnespHgSUh4yVLfzhipSh9H/XjzkHQd9P4g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.977.3", + "@aws-sdk/nested-clients": "^3.997.38", + "@aws-sdk/types": "^3.974.2", + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.974.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.2.tgz", + "integrity": "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.37.tgz", + "integrity": "sha512-zKq4HQum8JwDyEuyfuI4bbiAcU0KxP6qy+9PR/IsR92IyE/DaBAikzAS50tjxip4bqIIANpCcG+Yyj6CVhXupg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", + "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@drizzle-team/brocli": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz", + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@epic-web/invariant": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", + "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", + "license": "MIT" + }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.hirok.io", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.18.20", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.hirok.io", + "dev": true, + "license": "MIT", + "dependencies": { + "@esbuild-kit/core-utils": "^3.3.2", + "get-tsconfig": "^4.7.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/ajv-compiler": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.5.tgz", + "integrity": "sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", + "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", + "license": "MIT" + }, + "node_modules/@fastify/cookie": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@fastify/cookie/-/cookie-11.1.2.tgz", + "integrity": "sha512-Dtrpk/YOGUsbRMvP/8ZqPpwnMRv0qSqodFdoQ2B589Obc7jw4s4Qla+cV72Bsm7WsZJnqlYFX/i7uSBq0xzg6g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "cookie": "^2.0.0", + "fastify-plugin": "^6.0.0" + } + }, + "node_modules/@fastify/cookie/node_modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@fastify/cors": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.3.0.tgz", + "integrity": "sha512-ggQGua+xHv1MvePbPr0v//xLYEsCXbWspquXCJS9Ot5YoRXq8J8ZWzHnxDBVnbtXosvistXo6LtNzOJswf64Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fastify-plugin": "^6.0.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/@fastify/deepmerge": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-3.2.1.tgz", + "integrity": "sha512-N5Oqvltoa2r9z1tbx4xjky0oRR60v+T47Ic4J1ukoVQcptLOrIdRnCSdTGmOmajZuHVKlTnfcmrjyqsGEW1ztA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/error": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz", + "integrity": "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.1.0.tgz", + "integrity": "sha512-PxcYtKLbQ8Z+yApiqjK8FwxIwvEj38k2OiLc17u8dkJSlmfi2wHHPaSnaoqBPQqtvF8YVsDgDpP2snDCfFrpfw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^7.0.0" + } + }, + "node_modules/@fastify/forwarded": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.2.tgz", + "integrity": "sha512-NE8HgKLgYejV9lDpqkEFaDKMLYelJBVfHekhB0UKvX0ghagXRJqg68feg8er1NPXxG4N9i6vPxzt8E+3wHfcmA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/helmet": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@fastify/helmet/-/helmet-13.1.0.tgz", + "integrity": "sha512-SvVOU0IrzYJW1BvSkfq9G1WUdW3dnaRUvg6m0BtgGMBmML62No0VmSu087jecH58SFbicbREgZTPJ89mAguupA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fastify-plugin": "^6.0.0", + "helmet": "^8.0.0" + } + }, + "node_modules/@fastify/jwt": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@fastify/jwt/-/jwt-10.2.1.tgz", + "integrity": "sha512-8FHalB082a6HFj+neP9TdJZrUa65Aq6mtozVjd3vH3Yy7hmjRJUDKLPdxYRYF9S077JeN9RgimsautqnijbDlQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.2.0", + "@lukeed/ms": "^2.0.2", + "fast-jwt": "^6.2.4", + "fastify-plugin": "^6.0.0", + "steed": "^1.1.3" + } + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", + "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@fastify/multipart": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-9.4.0.tgz", + "integrity": "sha512-Z404bzZeLSXTBmp/trCBuoVFX28pM7rhv849Q5TsbTFZHuk1lc4QjQITTPK92DKVpXmNtJXeHSSc7GYvqFpxAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@fastify/deepmerge": "^3.0.0", + "@fastify/error": "^4.0.0", + "fastify-plugin": "^5.0.0", + "secure-json-parse": "^4.0.0" + } + }, + "node_modules/@fastify/multipart/node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/proxy-addr": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.0.tgz", + "integrity": "sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/forwarded": "^3.0.0", + "ipaddr.js": "^2.1.0" + } + }, + "node_modules/@fastify/rate-limit": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@fastify/rate-limit/-/rate-limit-10.3.0.tgz", + "integrity": "sha512-eIGkG9XKQs0nyynatApA3EVrojHOuq4l6fhB4eeCk4PIOeadvOJz9/4w3vGI44Go17uaXOWEcPkaD8kuKm7g6Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@lukeed/ms": "^2.0.2", + "fastify-plugin": "^5.0.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/@fastify/rate-limit/node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/sensible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@fastify/sensible/-/sensible-6.0.4.tgz", + "integrity": "sha512-1vxcCUlPMew6WroK8fq+LVOwbsLtX+lmuRuqpcp6eYqu6vmkLwbKTdBWAZwbeaSgCfW4tzUpTIHLLvTiQQ1BwQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@lukeed/ms": "^2.0.2", + "dequal": "^2.0.3", + "fastify-plugin": "^5.0.0", + "forwarded": "^0.2.0", + "http-errors": "^2.0.0", + "type-is": "^2.0.1", + "vary": "^1.1.2" + } + }, + "node_modules/@fastify/sensible/node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@frameflow/server": { + "resolved": "server", + "link": true + }, + "node_modules/@ioredis/commands": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.10.0.tgz", + "integrity": "sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==", + "license": "MIT" + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lukeed/ms": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz", + "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.1.tgz", + "integrity": "sha512-KjZdi8Q1wh89gsVmghvbrMgWl6ZWmRmHV6wjB7/g4Zf0dyO+hH3neZUtuDNPO00qq5YE5RITVWvrIZKRaAmzGQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@phc/format": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", + "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.3.tgz", + "integrity": "sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.3.tgz", + "integrity": "sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.3.tgz", + "integrity": "sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.3.tgz", + "integrity": "sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.3.tgz", + "integrity": "sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.3.tgz", + "integrity": "sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.3.tgz", + "integrity": "sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.3.tgz", + "integrity": "sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.3.tgz", + "integrity": "sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.3.tgz", + "integrity": "sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.3.tgz", + "integrity": "sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.3.tgz", + "integrity": "sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.3.tgz", + "integrity": "sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.3.tgz", + "integrity": "sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.3.tgz", + "integrity": "sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.3.tgz", + "integrity": "sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.3.tgz", + "integrity": "sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.3.tgz", + "integrity": "sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.3.tgz", + "integrity": "sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.3.tgz", + "integrity": "sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.3.tgz", + "integrity": "sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.3.tgz", + "integrity": "sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.3.tgz", + "integrity": "sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.3.tgz", + "integrity": "sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.3.tgz", + "integrity": "sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@smithy/core": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.31.1.tgz", + "integrity": "sha512-CyogUINxvi7C7LDsh8Syo6hVJOT9ckz4rG8dRZfTJ8r91HkMY59PnNooaj7WcHyxEkxPfBAmbgztZU+xTo76lg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.4.16", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.16.tgz", + "integrity": "sha512-QfuLWAkLzptffFW980AFeHZFdqds2B64rpEd3uJ6lgs3xVn9QegGMUgUcj+4d7dRrAsya3r58ZKpku97WcFb4w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.6.13", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.13.tgz", + "integrity": "sha512-4fW86pEUOMbrD5nkbyl/tTvPHHWJFbuB2odl6ps9lWfHoXf9HWh3Q/Smh59qH1g7+c/BSZghX6bbUk4gsiMs8A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.9.13", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.13.tgz", + "integrity": "sha512-Nmd/Nl35zfYrd+a6OO2cDJb3GPh9bgTjIUhcM+JFfjpp8/osCgboDV5nCT1I01Pv6R13eSKDKLSoVa5ZB6Zsfw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.6.12", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.12.tgz", + "integrity": "sha512-I6KLtq3H0qqSuV9vLglfi8puHqzygzWHOnI4z/Rdoo+q50vvo18vBRdPAvvEtcaKROz7Zn6qnPa14kRfPH6PcQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.31.1", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz", + "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.4.tgz", + "integrity": "sha512-XcCQz0TBpBgljhj0gMuuDj49i6Ytqh5q1osT/Gp5uAVJUCTWxyskk/l1jwYYiu2xcNHHipdMz40EGfM1VdamVg==", + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.7", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argon2": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.44.0.tgz", + "integrity": "sha512-zHPGN3S55sihSQo0dBbK0A5qpi2R31z7HZDZnry3ifOyj8bZZnpZND2gpmhnRGO1V/d555RwBqIK5W4Mrmv3ig==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@phc/format": "^1.0.0", + "cross-env": "^10.0.0", + "node-addon-api": "^8.5.0", + "node-gyp-build": "^4.8.4" + }, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.3.0.tgz", + "integrity": "sha512-g2tQ7LE7oOSqDfwEm3M+ZCMTJc7KiZCdJ4UwyZJb5ckTKyYu50OYmvv0mCFXPuYXoM4zkSt8zM9XQ9KCvxA74A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "fastq": "^1.17.1" + } + }, + "node_modules/bintrees": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", + "license": "MIT" + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bullmq": { + "version": "5.81.3", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.81.3.tgz", + "integrity": "sha512-Q7uEH2G92rVjX3Yl2qw3+6VEO15uxehC6DfeTHQBQTehddcRDSDuquD9zuvDjxiCffXsPUaBwrRlvlbVcgKs7g==", + "license": "MIT", + "dependencies": { + "cron-parser": "4.9.0", + "ioredis": "5.11.1", + "msgpackr": "2.0.5", + "node-abort-controller": "3.1.1", + "semver": "7.8.5", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "redis": ">=5.0.0" + }, + "peerDependenciesMeta": { + "redis": { + "optional": true + } + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.1.tgz", + "integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.4.tgz", + "integrity": "sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==", + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.9.0", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cross-env": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", + "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", + "license": "MIT", + "dependencies": { + "@epic-web/invariant": "^1.0.0", + "cross-spawn": "^7.0.6" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/drizzle-kit": { + "version": "0.31.10", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.10.tgz", + "integrity": "sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@drizzle-team/brocli": "^0.10.2", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.25.4", + "tsx": "^4.21.0" + }, + "bin": { + "drizzle-kit": "bin.cjs" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/drizzle-orm": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", + "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=4", + "@electric-sql/pglite": ">=0.2.0", + "@libsql/client": ">=0.10.0", + "@libsql/client-wasm": ">=0.10.0", + "@neondatabase/serverless": ">=0.10.0", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1.13", + "@prisma/client": "*", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/sql.js": "*", + "@upstash/redis": ">=1.34.7", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=14.0.0", + "gel": ">=2", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@libsql/client-wasm": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "gel": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "prisma": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-7.0.1.tgz", + "integrity": "sha512-eRSayARSbbwlBjpP4vnTTIRD5QPcIrmihPxDeN1DtKnHPg66UuJLx+8hlK1kaFdjvzyQ/dzALoi4vwAQ+T+iZA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^4.0.0", + "json-schema-ref-resolver": "^3.0.0", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/fast-uri": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.1.tgz", + "integrity": "sha512-YPOs1zD5TG2+EZt+r88LwF6mclA7TPkpwMP7ZN3TO2HiHS8TXvq7QA/17iJsV9dubcLo/f8eEYqMBruyQV21hQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-jwt": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fast-jwt/-/fast-jwt-6.3.0.tgz", + "integrity": "sha512-qFVn4V6rdsqUVOr6WoSF8rt569SdWvORlPKhT4fh3vMeMN6pmkGdWcSfKdLM/G9B2KZp/9E/EOgsYbJUaaT2rQ==", + "license": "Apache-2.0", + "dependencies": { + "@lukeed/ms": "^2.0.2", + "asn1.js": "^5.4.1", + "ecdsa-sig-formatter": "^1.0.11", + "mnemonist": "^0.40.0", + "safe-regex2": "^5.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-uri": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==", + "license": "MIT", + "dependencies": { + "reusify": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fastify": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.10.0.tgz", + "integrity": "sha512-A9L0ziuWGQHgEEVgF3davQ9vbD93IuX+lo2IsxapQmu5b/Y/ynn9m9K5JHt9dvyJXOFc5iN0Zk5GHEOqnzhWjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^4.0.5", + "@fastify/error": "^4.0.0", + "@fastify/fast-json-stringify-compiler": "^5.0.0", + "@fastify/proxy-addr": "^5.0.0", + "abstract-logging": "^2.0.1", + "avvio": "^9.0.0", + "fast-json-stringify": "^7.0.0", + "find-my-way": "^9.6.0", + "light-my-request": "^6.0.0", + "pino": "^9.14.0 || ^10.1.0", + "process-warning": "^5.0.0", + "rfdc": "^1.3.1", + "secure-json-parse": "^4.0.0", + "semver": "^7.6.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/fastify-plugin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-6.0.0.tgz", + "integrity": "sha512-fZOty7z3O7vOliF6d8bHE3wiEh1KcNnKEQensSgTk9C1DvN6nRLS++XVd86v33Hw/8u9Un8A1zDrQ8ujcQDHEg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastify-raw-body": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fastify-raw-body/-/fastify-raw-body-5.0.0.tgz", + "integrity": "sha512-2qfoaQ3BQDhZ1gtbkKZd6n0kKxJISJGM6u/skD9ljdWItAscjXrtZ1lnjr7PavmXX9j4EyCPmBDiIsLn07d5vA==", + "license": "MIT", + "dependencies": { + "fastify-plugin": "^5.0.0", + "raw-body": "^3.0.0", + "secure-json-parse": "^2.4.0" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "url": "https://github.com/Eomm/fastify-raw-body?sponsor=1" + } + }, + "node_modules/fastify-raw-body/node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastify-raw-body/node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, + "node_modules/fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fastseries": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-1.7.2.tgz", + "integrity": "sha512-dTPFrPGS8SNSzAt7u/CbMKCJ3s01N04s4JFbORHcmyvVfVKmbhMD1VtRbh5enGHxkaQDqWyLefiKOGGmohGDDQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-my-way": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.7.0.tgz", + "integrity": "sha512-f2JHn75x2JlwUwLenZypgczR7YWMb/uO9BvUXtus+JMgkbIkLADd38cI4EiV+OQqrGo1Zlq6V8wnqMJ8e62wUQ==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/helmet": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.3.0.tgz", + "integrity": "sha512-Qgpiaws3Sm30Av8Eah6sjMCZZwjlBu+E68rhpCWBshY1lb09HtLwj5GviX0OyQIn+ulUS0iX0AxN5n3tLZzz1w==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ioredis": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.11.1.tgz", + "integrity": "sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "1.10.0", + "cluster-key-slot": "1.1.1", + "debug": "4.4.3", + "denque": "2.1.0", + "redis-errors": "1.2.0", + "redis-parser": "3.0.0", + "standard-as-callback": "2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ipaddr.js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.4.0.tgz", + "integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-ref-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", + "integrity": "sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/light-my-request": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.6.0.tgz", + "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^1.0.1", + "process-warning": "^4.0.0", + "set-cookie-parser": "^2.6.0" + } + }, + "node_modules/light-my-request/node_modules/process-warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", + "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lucide-react": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.27.0.tgz", + "integrity": "sha512-rJicGl/3Fly/E0rOH1YmPZ6e49JCnKknh1ox1vpHnkfjujAkKA6sqUZvH3MTAaXXjgexyUwgNwTJzTtYuAFYJw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/media-typer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/mnemonist": { + "version": "0.40.4", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.40.4.tgz", + "integrity": "sha512-ZAv+KNavneRVzu4tUeOgzkScI3W5BGwZ3rkxIpKtzzVgfTtWQFN1CgX0U72cyvyh3iTuHL3SiSmrQxTlryEIcw==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-2.0.5.tgz", + "integrity": "sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==", + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.4" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.0.tgz", + "integrity": "sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==", + "license": "MIT", + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/openai": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-7.2.0.tgz", + "integrity": "sha512-/P0jZP2WDSwSuiilTTcU4mkepzdSAiRrnTK2e9pk9KOzBoE3L9aHz2oIyIXqGbqnnMsGC0Izr223MOUhG2JuvQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "@aws-sdk/credential-provider-node": ">=3.972.0 <4", + "@smithy/hash-node": ">=4.3.0 <5", + "@smithy/signature-v4": ">=5.4.0 <6", + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-provider-node": { + "optional": true + }, + "@smithy/hash-node": { + "optional": true + }, + "@smithy/signature-v4": { + "optional": true + }, + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz", + "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^3.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^4.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz", + "integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/postcss": { + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postgres": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.9.tgz", + "integrity": "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==", + "license": "Unlicense", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/porsager" + } + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/prom-client": { + "version": "15.1.3", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", + "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.4.0", + "tdigest": "^0.1.1" + }, + "engines": { + "node": "^16 || ^18 || >=20" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rollup": { + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.3.tgz", + "integrity": "sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.3", + "@rollup/rollup-android-arm64": "4.62.3", + "@rollup/rollup-darwin-arm64": "4.62.3", + "@rollup/rollup-darwin-x64": "4.62.3", + "@rollup/rollup-freebsd-arm64": "4.62.3", + "@rollup/rollup-freebsd-x64": "4.62.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.3", + "@rollup/rollup-linux-arm-musleabihf": "4.62.3", + "@rollup/rollup-linux-arm64-gnu": "4.62.3", + "@rollup/rollup-linux-arm64-musl": "4.62.3", + "@rollup/rollup-linux-loong64-gnu": "4.62.3", + "@rollup/rollup-linux-loong64-musl": "4.62.3", + "@rollup/rollup-linux-ppc64-gnu": "4.62.3", + "@rollup/rollup-linux-ppc64-musl": "4.62.3", + "@rollup/rollup-linux-riscv64-gnu": "4.62.3", + "@rollup/rollup-linux-riscv64-musl": "4.62.3", + "@rollup/rollup-linux-s390x-gnu": "4.62.3", + "@rollup/rollup-linux-x64-gnu": "4.62.3", + "@rollup/rollup-linux-x64-musl": "4.62.3", + "@rollup/rollup-openbsd-x64": "4.62.3", + "@rollup/rollup-openharmony-arm64": "4.62.3", + "@rollup/rollup-win32-arm64-msvc": "4.62.3", + "@rollup/rollup-win32-ia32-msvc": "4.62.3", + "@rollup/rollup-win32-x64-gnu": "4.62.3", + "@rollup/rollup-win32-x64-msvc": "4.62.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex2": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.1.1.tgz", + "integrity": "sha512-mOSBvHGDZMuIEZMdOz/aCEYDCv0E7nfcNsIhUF+/P+xC7Hyf3FkvymqgPbg9D1EdSGu+uKbJgy09K/RKKc7kJA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + }, + "bin": { + "safe-regex2": "bin/safe-regex2.js" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/steed": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/steed/-/steed-1.1.3.tgz", + "integrity": "sha512-EUkci0FAUiE4IvGTSKcDJIQ/eRUP2JJb56+fvZ4sdnguLTqIdKjSxUe138poW8mkvKWXW2sFPrgTsxqoISnmoA==", + "license": "MIT", + "dependencies": { + "fastfall": "^1.5.0", + "fastparallel": "^2.2.0", + "fastq": "^1.3.0", + "fastseries": "^1.7.0", + "reusify": "^1.0.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/stripe": { + "version": "22.4.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-22.4.0.tgz", + "integrity": "sha512-LVJ+tcSYeqOSnXr3i+Kz2tZ7y0crLLdP2uwD/4wccrmEVyn0g/Heo0pF7as7rxS/sOjJzrb1lxgZY0Y0Dx1pSA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tdigest": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", + "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", + "license": "MIT", + "dependencies": { + "bintrees": "1.0.2" + } + }, + "node_modules/thread-stream": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.2.0.tgz", + "integrity": "sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==", + "license": "MIT", + "dependencies": { + "real-require": "^1.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/thread-stream/node_modules/real-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz", + "integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/toad-cache": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.4.tgz", + "integrity": "sha512-m1TdR/rvT7kgGJZhspNtXdsdYk0fddFpJJFlG5s+UkPFo6lkLoZ3YLOaovPYjq1R75NP5JfeTlSHaOsE09peCg==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz", + "integrity": "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "server": { + "name": "@frameflow/server", + "version": "0.1.0", + "dependencies": { + "@aws-sdk/client-s3": "^3.850.0", + "@aws-sdk/s3-request-presigner": "^3.850.0", + "@fastify/cookie": "^11.0.2", + "@fastify/cors": "^11.1.0", + "@fastify/helmet": "^13.0.1", + "@fastify/jwt": "^10.0.0", + "@fastify/multipart": "^9.2.1", + "@fastify/rate-limit": "^10.3.0", + "@fastify/sensible": "^6.0.3", + "argon2": "^0.44.0", + "bullmq": "^5.58.0", + "dotenv": "^17.2.1", + "drizzle-orm": "^0.45.2", + "fastify": "^5.5.0", + "fastify-raw-body": "^5.0.0", + "ioredis": "^5.7.0", + "ipaddr.js": "^2.4.0", + "openai": "^7.2.0", + "pino": "^10.3.1", + "postgres": "^3.4.7", + "prom-client": "^15.1.3", + "stripe": "^22.4.0", + "zod": "^4.0.17" + }, + "devDependencies": { + "@types/node": "^24.2.0", + "drizzle-kit": "^0.31.5", + "tsx": "^4.20.4", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + } + }, + "server/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "server/node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9b00673 --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "frameflow-ai-comic-studio", + "private": true, + "version": "0.1.0", + "type": "module", + "workspaces": [ + "server" + ], + "scripts": { + "dev": "concurrently -n WEB,API,WORKER -c cyan,green,yellow \"npm:dev:web\" \"npm:dev:api\" \"npm:dev:worker\"", + "dev:web": "vite", + "dev:api": "npm run dev --workspace @frameflow/server", + "dev:worker": "npm run worker --workspace @frameflow/server", + "infra:up": "docker compose up -d postgres redis minio minio-init", + "infra:down": "docker compose down", + "backup:verify": "./scripts/verify-backup.sh", + "restore:rehearse": "./scripts/rehearse-restore.sh", + "smoke:production": "node scripts/smoke-test.mjs", + "smoke:alertmanager": "node scripts/alertmanager-smoke.mjs", + "smoke:stripe": "node scripts/stripe-smoke.mjs", + "db:generate": "npm run db:generate --workspace @frameflow/server", + "db:migrate": "npm run db:migrate --workspace @frameflow/server", + "db:seed": "npm run db:seed --workspace @frameflow/server", + "test": "npm run test:web && npm run test:server", + "test:web": "vitest run --config vitest.config.js", + "test:web:watch": "vitest --config vitest.config.js", + "test:server": "npm run test --workspace @frameflow/server", + "build": "vite build", + "build:server": "npm run build --workspace @frameflow/server", + "build:all": "npm run build && npm run build:server", + "preview": "vite preview" + }, + "dependencies": { + "@vitejs/plugin-react": "latest", + "vite": "latest", + "typescript": "latest", + "react": "latest", + "react-dom": "latest", + "lucide-react": "latest", + "concurrently": "^9.2.1" + }, + "devDependencies": { + "vitest": "^3.2.4" + } +} diff --git a/public/assets/character-linyao.jpg b/public/assets/character-linyao.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e0cc997941032adaee75a803229a13cffe337e84 GIT binary patch literal 167945 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

@MW6KS*9 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≠cgEDXXx%oCmhHpL>rwZ9}th1q61*%ur)@bB{h zyUX#`{{RqW(9=&flkpL@g(4raBWf2_zLEv7%8c?%w5L5+B&!ane2eAU_p>uN)NfH-cjnJ-HX8Wj4Q!`UBat_7H%MR zuG*<(+eS~i5TccD!c(0u<~fKOGzQ+7B8-KC)~*8HrPMszeA$@c3Az8%F1D7K=Zh7o&|tBW+{%t}|1+|dgn&bJb_hD1$UJkz!h|o3BEk(T?OQ2jEF)M`=4-&ec0%DbKxm>Wi&HiArl*Vx_vV^`j z5Kt|w)nJZ{Kkfi2ZSqFh4>dXi;g%r9a{{45)G$iH8?$dR!1CA-3h9fggK_2Y7K+U- zSn>q9jvByeimA0b?szkJBWmKa&k%55q9Ma+N-{ZOjzO;zW|p-J7SibcWh*KplS5%G z!k1mb3ORgY5N_~z<_(T|g{!i-d6$NeI57aLFA|V5T##(PQP*ShE30^`+|U%a?G+Jd zHu-|3+m~#z-M!URu;1!kWHpjwL<<_b;MAeKClYpG?6&lkzutcM7tmaOHfThu#C!4rXt0%0S#6j66oM#T4+D7oOcq z15k}Z%FX_v!Lc3OA4|Mu7HI^$^BkH3u5Klq32tUe;_@`dVaBQ4RvkBAxTq|k?&29? zu3P^A$+a36BPd$N$2SlqyqS8Jt(oXxk9yM}}0;(NdM^$;Gt-ykT zS!tGYi#}zEVm>@X0cLNB$DG}FFABjD1%K=fN^3_lhdAwpJyvR2OP@Cd<*Xa4f=CtO zr8#(p^5oES0m}!7(%Rzb@G#vMlN`mc=eYSA>D(Pf1lJPghuSN4@x&{kzWbIL zQGCi24lAgYs_M=nKva%#$^1*%;O-O^L7dkzoVe_RAQbyUtv~iP9A}?LX7g|#e>^WrMP$e%fZ`t&p-BMrH(m&;vyA+mHm1#P=?PRkK~sNOK&@m zEvv+{AW>Q4`Nn=`GNXxW{1vv8()F-AHa~#?W z7*)6k@=7fP4!B6XhwGTVCd9`M~Ch^1`Zedb$+jvkna3riCi zm^~E^Aggfffx=-A#5g!bO4$c%8K;avuxf?@YQy_Vv~zFFT@+w(DLkvXl|W@=s89;G zh3a@Y9m_hFZE%p@oHXVRLaklJN`km&P_2W5ZwyRAjTdCV7^9b#2p6Wg$51{M689K{EXKK+ z2Gv&ON{&X2MvVnOXxTn-s1*WFKg_}t)z9VxAUx-AnFF%YBVoRHnQGFx(K19WaR!lP z9%^YT7$60U%$p9`x#^B|OCe98!i z#&F9oGp`cimum`$`_7@WYgzbkJdxoA-BIdUrzSu*4TZ-a%tfl6-k4wu_Lc|`>Lsla z1{ql0K-(V?SR7uOh%(8nmrwxZPf-9au;Sx|iVWEn04OyLtANonf~74Vz9wjVo0PxV zf{S$3LQUr$&>H}^gUn^g%-an=sY_WNrDJ||9hSE9a01u0@d

#57pqx#BlvbC;-t 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 sgk(4qjCA|0joE=ZT6bOfb{2mvA@ zO%#L>zzRqa{N3aKz3YA7d)NBDTL#uyPv*=ynVCH^d+%rO{PX^wj{r(fTUQ%^Kp}t* z_y_#6Mr)<3q2Xw3YNV~JuLVFL06?pw@8#zYMF9ZLFF4TjnmWeH+6F^81wa8R00Bq= zz)hE+TLxy@Hvq8cYH47Cz(#-Zf6A|S0Qe>VAd2Z2V=(`z|9^!TTy6yh0|3MrY<=0) zEyxAL@gVjM3%>QY{yT`7oqhgdDEu!D1Um>~^k3}pFD&{$ZT^L^f3Yjh&lPO*x6ij+ zajt*yFo+XFL)<_N(+6=vsFzz9h~I*k-!}y31>z$RGvnND1_1z^_HTW#n~NuiB|%IZ zc*9f!#3}%Qr1khO?EGIi*zGphPXN&Hzl9I<^6(7C2)kUwNGU2RV07HVeBFYB#f)#d z_}mP1#c25BZr$|51Hiw={P!t<@$cMXz)6;qQk0VulNJZ3|KH_*d-LC|{`cUoZ2#3_ z&*Xn(24Q*gpSu4%`=2`hN&rwe0O#hxf9jkI0HE_80H7EDQ^#Kp0O#TX;2Gh+#>4V= zy?6!(-%^s02n!1n_i}R)|2v`oF8_}W{@wC_4gTx<#Q%QZzvm94>E?bj#5Wl8cT!#a zef>iMF+sO(y0~G){_l(U|M!Fc)vf>Php4HWyIY`}ANW-k;41U-^8m%|=js*g*T{f&5!;`cxLc-<@a4 zP5Rfm2Qhg6f3E+R3p4}#2o3V`!2GS&Fuj3s2?-4Si@`nd_d)?s1Lpu{fDPaR_yA!* z43Gxo0c8LSXaRbF5pV;r1{?qvz!Sg$fj}4#3B&>kKnm~x$N>t0GN2l$1Db(0pcCi= zhJaCE0+i(1QG;kf^dY7YYlsuX z1L6k>fkZ;?LQ)`^kU~fWqz=*w>4pqJ#vwD11;{4|8S)cy0);_oq0G<=P(i2!Q~`Pw zdL4QLY7g~*20+81@z8W=KC}|r2z>?}f=)o^pdX<-&;u9%qk*x&cwk~M1(*iR2xbFw zhXul-Vac#uSS73()&m=Z5n&%;yRc(80?q`-z{TLoa2>cg+yx#0kA|nh3*nF9&)~yw zBK#BlJNyp?9R(+a2!#@bE`=3^2Spe~0!1!G4aHN65sEpA4T@g~1cC)2gpfz*AgmGI zhzLX~q6E=`7(~n<))5Dkl$30gB9y9>MwB-xgDDdz3n&{YpHt3KZcrW}X^`AVX{0vN z2I+^4L*^pukpswCBnkPO3PmMAr9@>!Y*Y~ZBYHDW}p_LR;9i{?M)p^ zolo6NJwm-qy+=bs!%L$`V?yIa6GM|v^MvLV%_o{;T1MJSv>LQ_v>~+Vw6(N@v2>K{>F>}N(LbY~rT==4>YTv2tLGffg`dkk z*M5$0ZWl#`5=3dBZla=5MW}AnJnDdfi9w3Nhyllt%23ZR&alNu$tcLE#pucy&sfFy zl5w30#>B^@!Q{epm#La*glU5r!7RkA%k0gZ!ra6>#r*v|<9V6$7UyrDFFN0U{v!*F zMUX|8#g`?6rH$ns%L(fR)~l>;tVyiRth20#XbvVeF;sBka2z%pA%bE*!}mZ5)f7P|i!7rkoL+Rh(})4=!+BxOU;zg@Ow& zFYI!$aACQ;xw5$ixX9d0+-lrj+}YgExwkRrF;_9Zn0(AI<~t83j}A`=PX*5u&u?BK zUUS|!-WJ{!K59M%K6k!sz88Go`MLQG_#^on_!kAJ1QY~31@Z*O1P%p-1T6*c3w8=_ z3895_g~EjzgqDTrgs%t(2v-Wfy@yrbBsc&sF+6s**y^i5ez*+;ovc}qn|#Z9GJWnGn5 z^`>ft>PIz_yl z=7F=WbFuSx7Y&y@mmOEEYql%dP1P;ajpVNCp6R~jq3V(4LH4}jnd`ahrQucR^}}1o zyUhF0$H=GF=O157-xeGa=Y;F_WAyX!8}{e&zwJMBOXOCd-_y{Tt?{w!~?$v z?;c)x_&AdxGdy!W%OLAnHYPhcdq2l9XFOLXw=9o3FC_0{zJ7jJ0e``Rg406J!nq># zqLyOL;-uok64#R1Qfz5+*@d!{vXgSJ^7j?jDxOseR_0bAszR$at1YU>9w|Jkt6{H6 zsX43ltNr-c^zm?=d|h2VXMIKkv>~K{+-TQ0-K5#n)hyOr(ZbS_@&tGi@?^W!sr6mk z^|lx73hm7u0v*LqnVu#;gFM4O``+o<`LWBoYo=ST`$dm(&(mJ<-r7E%zM}r~{TTz) z1Mvg@JP&_dfRq;W9Qb+@7;ti3}1@B3V-eRhW+;DyVduNAAvvq z`I)-MwpY6^v;X42_~64Y+^^q<$wzEQkB=3O$4)FyNWa5QDNpmyE}r%Lx&CMQAKX9x z{IdjT0B|S_27|)E3mhyIR0s;N&>)crDmofaLD10B(xaFe=+7~oqorj;GcuiLVP$2d zXJF%CV_|1zVP*OI63E{tDJZBB2x^vdwC7mV{s!V5qdATS2VKf?eg zXuH5b^Wnb?8weBzr$A65!MkjK?||j68S{UZ|GE3mB0vj+fNy~@fHu+ePBekyo^N3? zf2JU|u1gwAH#>m~nNyPv|F#y2JrtazN3D9Dv!Iurfhh%sXC5_?m zajFLW8+524pd2)qtP(Dv1p!IyFs%ke5{vZIV4y`o(LC|Gnu)Ujt$___Bts-Mu!Znx zL0)!7PiLQ8V|-fxf?on3yF~{e3n0mhVT#3YG9#&F)e_F z$b5vxzyXdBp{s^RsgR)#7L(9nskXP1)Mvx=>Gc()=IAxsOfJHY_JNk*9X#OpCJQ=Lj? zF4;JL3(XT}s_sNp5fd{Aeeg;{R6|2QUeX{N#>5GT=--gk2iO?m5Xt=SM4i!KM@~ULDF`34HB``8lZz(?}Cu@N*l!vIzc@(P!#%{JUtpbv<&<_y{I8t)VLYoL~UXr z#Y6!~L}yV@N&-x9a9(8q3~&*OuG8gZ({V~bdg>-7AR)9UX+CxS_(4!8SSnCx2}tLp zasz0lBy5uXfwcNV4EnK~pp+n$PP`=O8Pn>A0&|jRNyJ?WQ1Fr%12ZN}3X%yvD>yCb znGXQe`3g)}X#{hXOk-xe^n)R3>bLP40BR6L4Zs*+s6l`agQbdzd7>Xf&7{t*DZ>-z z^q2~?o0;H1LVPti{V@aIST7M(x*A^{+xVcD)Q zJt-bWSE|bH@rRk3_xR&qWqH*j5_OPPdY4?Uqe^5(iFx|{^+yGHM59-uj!w7xNPQVe z{i^uS9b7qq9bWxzX+D>_m;hb06fK}P{ddh`0iH@W9asJ#L92vpeN8Fjw=vY1ayX=3 zpYefKN0JOMjAYJCs(wLlDLloY?;MOoOBz6(WPoXyvD45XAeEG!1t1uaPFoPoSvd$x z{O0TNdw~JhdHCt!1}J_@lje7``s{xYbctm%mJ$tJ)g!vO7$-pT#t@@ZkvbX! zmwqsuI7A0^=1F0AjA#UmA+(w@{39CJB3=Lx;1Bv-YMN~=m@f$_cX|w<0jL|TvlE>H zdW3%{CV?#VcodkSMZQ8%gsQuw`?mHJcd|E=w8G43jB{G~^XOzZ*74C12azh>_|VnD zNvoY=vRM(5)VM$$g3evalPx@ykhdLTZ5HHEHL$b$dEy;u&Zle< zLFz1cHG^4VKJq3*9J}JjpEw;q(X147K2TmrCyA&_kFAgzBq9dA?m}wlY5-wLH1JxZ zvE^c>u6D^xj&B#~!%^EoPo#s?m)mMWWrW&CYXQGiBFrurUAP=vPcW;sN2rGNUg+{F z{L-wPUOI4LqLy1(I#hC_am#~rqi|J@o!}xUbg6!8`K`eXZMqTGY#nmwX}wVh`H%Gq znXs$Wcjf7RKr8YA^YrW`b*&g`b@XGWm})815R6wEHHYy+Vc2w>tB2?=As#yMfZLq& zmr9Hi5dmYe$Om9>v_r|x}?Ne-?+0nloPx?KAR`1D!ADdd?=Dv;wqwl@NLQNw4a_+ zR4Y%>ZD2?7;nscGeUa3M-PspMuJbYL2m>X@R?TyTN?hxkg@+l_HUl2}jz%UfI)2KCup04HHu&+0U9Mz~+j1YVS>@ba zut`=`I%&V=kT!2muU*D>{^j%4_Oi(D&FLY_YmMC}Y+0?d-Q=y;Q?mAbwQB5b{1@9Q zWjpwXv19NXiER6~+P%P--nM%%i(nI0ZiRfXeBx^^7eir-o{p8o7y!a*3&InfqC1q-` za+lv^ZnVG6>qi%|Zb&WUT``p!i};E5SuG_M6jf!{^wwQtz~#dG>UH{k3SDKxtm;#uo17ghQT$jCg3sWph?Dhefhyi}OqU9_gR* zA+iR6Y0;)Vk&z{Ww-v*ehw-WJ91Q}5tR9#mnamm5_$cN!r2VyZytQyAcgFk0TYuFZ z{R23X_ujBn$MZq301bSQ2{o7W6o>(s&I=+zYK0k_2pAwe+1(Lrbx#n0B)SSK2Sdl8 zflJ?_436#c(NuV6UikXF0scg<=~?4GVQlC4M*rs^xy>{Y zYad%V^9FfWvEpv&ke~A`lTw$STS~cTby`yi=NPWkOeo4+U*5(yCVi>6#eprr)}tZ?)5RIIzCPZTpRM zQ0=z*U|L5X)S(HF!4Vkn>ZAULnuJ!wV?otb4nWYcn=$apQKGSvBqD#&I{_p~5de{b z$48X$sgzIKP4vQ5F85VfO6DT|G{S$3u7J4e#`a-xdtFv5N-wJ@%g?ixWpQ41>V1UR zjM&-vcT?S`{@gA6Sy?I4Zg7rS_pXly=?cM!OH;e0052w3NGSfqfa>z$MQ>1V% zu8@g@t!jyx=nx|_L{j+tOZSkJin8YU^INToCk_kEGQZzW20GeMa&uS3;TI#O-{HF= zn%7^A5f>Vde7PF38hzPGn)tWh$UQkCz}na?stGA;$I2KIr-Uk=2gc2UanU zqRc7n>h7ZTf>)E%m96ux3_{FI!T~gO4>Zvi`P}d)t%SnRD3Pt_Wq)S2_I|x0G*hy| zsF|=xCky~JDM#_4WHg-_Vm(2wF&_!gs^g`ALH-ij^RWQ4tS|t%3m}AtGwTd&eF5RM zkVtxQy9aq(@4bpf50;A3WUHQLTF=||(vWnQ-t6Xg2aSk@5GqPMc8U~3C!QObsY->2 zcdCk$H7dL5p45v@CyS6Nuef(vr)}kQZO`*1p3IH0q#p!~-w%{mbIIF1Ha(j1fASK4 zEUMOWo=`YK4%$&Odbf9Ze|>&qtIC?RRuWDsm3L_~=MhO=cQ&x1gRjN#w>2+5Trv(l zE|eKlUXA<*a6dl#^M~7ij#Ly+PKtv7@ehDG!T4dME{{&KC#Z@bW>_SOLPXcXA{8`2 z7hOC-Gv^uTBcP`T(FxQV@DV=I`{#xZx=)qF4Z6Gcml6pjCB>)XO{KkgO9b8Z&2U|h zq=3Y)_MF=`_NONciw*v2KbGjz!>wzSmS*akPDWU5l~XhHP383Dr3FMVjX5R`uixCu zmCbCb?*3G-`+8`3ytFiewS2tf_(Rwuf<*S%HvTZLcr!ebeS@^UYu1O~<;u$$h!hT1 z{Jo(mQEQ#--p){MzyjFl@yD>FnqKdGIU{!5Yo}b+5YdtmWlP-Ly7&@bz-A1@Xit{| z`TT2Csc9@7C_yS28D>EMn)(o>?Oq(Cs5ztuT1CLct}Z_@TP?Z72QZW*LQqOpWvt?O zNd%~7Sl>V`thy8`(Ai`a8ec z>tQ}s-djDrvV^NNA(Mt?U2#3Ed<8))D-W7qc<1;EX8T^ZZIjZDdfGWfm?5Mu7oSBQ zuX2=p7~={nBTIgW_P^rK)%64aCq=M*v-?ABUf;3)*#{3pbd}OcpuQz9ju-J53W!#| zjbFQP{irnV((h{{Y9p(J)ezgIB9xS*Mmc!A@&{z{Lg|>LutUbo3FXj13MO^nl{BK5 zsvIq)3`veb=Wnpc6*r<55f~f{i5>{sQ7IE!0+qvQaBig4afqK(KWVNxO8zlgQsyZg@##=Z=TlNz;uMSj0j}om?Je}8LkJJc`lq_~A|2hv z$b{FQ4mkb#6t(uhWqR3l%mFrl3;>+iE$t~?u{kzs+nLzf;|9ntUT{o27)fO(cNPM(tKZlVxd^{lm}LcK;|ty-ZJQB|I(8FMT0L+zxR{Ur3&bqD87T5jB zKlgWkzJD=HK_>}1v_Jxt6cb=z3YUWEu%U`Ir7);$!ADNOG!d!;pOt45ff~~w3V8Hx zP{4RP&Lu7Uls*pWjU8)ImY$gCkm=s6udSQ!Z+;4!gjeSP7b5FMo7e^On54V6HEsjAQXyts4J-sz(Eta9R5;45sRSJ2LJ=Q z8c6`~zRJI$51?tSj#_YgyO)m*^Uh^NUNCgUAG8Hb3bR^s`1II5VzgD2fX#W>Ul&<= zNqo1pwiU3y)7HQD`Mmm8 zshWVGxP<~5K*?-@E{zi{NQI0NvmxlhG@2{9QP)1(9Y~0fPixOB)X7SpqUTAW(voJ3{y$7XRD)XBU^jHUq;%S(J+v2 zpn}5~uorD;;IlGPKqU%^$kgTW^m+*Zh-yh@ea%r??-(pv5~XOSfAhh_UQ5)+)gxmtLjq4+6o$ep$*$S3E9H=*(7(Ck=aQ1{t#_*ni+vVv-tDdHnIM$8P${6)r- z)v^A0!#fsjO#Aq+A|+CijO>g+0>2Cpmyjt1!y@4T55NoP4FWt*c`B0bl`A4xVuqx# z-tiZ0O!-Pfi@z0~32mJA?BQ)CZ+)%V!CMQ}#9oV#|- z(DvvgoIPNB%=VRiiKVpMN{ABUvHBP2qW5B>IU5t=>$@Q9;LNspH}h3%)85PG!|`u- z(CUFAp?V}yT(fYkn@MStEVG8TGqYEX{!yn}H)*E1KZsD~#)`h|lhB%RMLnhT8s*y` zNWIU{a ztmD0O^*sO6SX%HIS_D&xQ zl%HXOc7SDlQ7S&{X5Wwb`hE|!DCXr)pMQ0qDdL;M!cvy*Ir)L|q}Tp9@$6;^;k~MS z_JKo-+MGZg)kyUNkgv(etv5_?PUKRVsBYC6CH8>NoFb?FxS9Qx3x*$IUX4Gula`mrtxy_xgkzPRVid` zuCz#eB3k~@>yZZQkW6CUHEU;4(YD^O$%}>$(eKxx-Zzqb?saSu4PS|Kh&85FC$89K z_EMVb7?1OtJgab@Gbt?M5$9aG{N^*Eoo-a+&>T;yHMA{$>Q!Yuc0bg9@ALQmbKJG! zH-!&2Ay|l;YpQ4I8+(iB0lfpHZkP z>z!Eg>4$zL9uIDaWf8mj$=1CsCjLtd}QnYgzq&T)uYSIG+2SX7eK2k8<|@5K!!N zX)h=l1FDf~EcAj#oCRfEO(m*;>H|S~?I- z&?A8h@bgp%Cc

  • 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
      K;|4{!O^w18V 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

      `k#m6mpV5C!sGW>i73)R@=F#@ZmPKG~j1 z3WK1;9Hh}Cs=D^-cNu2iqu~6l^yKIkDV4@g8wL^V z--T{SZ{rmU3;))AW#zWtp+4-XDmgy3|N4gZn z+>a+Iwn$=VB#ZP=yOohgvDetj!lL)(9(8Px4o)%%7W0=&VL|If^A0T{MBs_Gx)}VG zfnb;DHaoVVBSqZ`5sYpB>^2bW3d076XW1Rt!vn2^Sq&+PdqZ~KFwc7o}F z4||{9ZrE*SQjR7$tuB`rU(sn%Opn@h+l;9Z_N;d`8Hi`gJx~F$>eP-%q)SYG3xuEX zf*;+?kS_28PyT(F)0Cwx35I5`S5Uv+n#y{+Z{C@KxlO-?3!%N$UZUsc_ul_a=dalc?z2;GH^eF!0E?z_xPx+%{S(lsCGondgSYrh4R>GE@$(S|R)>|@+JgR>2>RKBgVTaMH8P7katC)v8=H|L@ zqm&zI($+gj?s{=;eSbjRMPGX}$aKWc@N`S^cNwghMBEU6YS1{=t}-pqdN?c7JJZm%(4Qv zSZyYe_B{!b*1aya=S1=s_6n;-C6e??oQ!(1Qv4dWV3(WZ5S+P0zP2XGsR`^!Iaghd zY1An!%JjI7LcoPMwJAAJGj(#Y=Ecwpwt3^s=F02H9hDBd7RJ66+b1*w3$1h0Sdm`e z8>(o5ZXpwK)wfB!3F@$K2#w`97Z06BE=-~HF{+jUI|wHgSG289da`@QbWnp;*ulwi zpBCtVGy8OUq`=NUC{ki)nNC|oY>#ZdKS!TU$6V%&iF?)&1E&+{x!PNLHxB&Yi9Wz|LEPHJc6j=yoL@MGo^b>fw~cjCR+Ggw$^OZ+aA6f+q>2l9*Qgb2bO=QGY#VN>`J{i3vS4GP8=MO(h{)9`{YH8W_yCoi5DHn=g*d~fsUg#PJ zdglYy>BJhbnfYH;`{odzspPy7TIrReV6fe&q+>_&^(iy zzCdl2=k%$|gSECZ?o}&JL|Jc=fF+uco&sXX>v|z!+H-hA&OWJSJ3WHcesbP_&K*@g z*D_Hl5$6PJOVaVvq|7(#OIRMZw7ANuH)ItWGFsBz+%t}9P~AKa>ww^LRi}oOJ=&-} zK0H|=lf{|qAMktB;vUHl7D>Izzv&y78tr|0v>{&RsAL7NO$_aq6Nq-J1v%1qtV-r5 zh@{ak`y7XjM?@9un@orpvP&WgcoeEZU(Ue<>V9f zEz@Hi8?uu8VGM1FMC;r9fq7Z)1N+y4F)X(O00cx`fve$U^Un0%K$<@w<w7ORVD#m9VOYWAm;~&kh94Nnbeh@1e^4_;PK-j&D7CY^=m~2Xs zKD+e<@nC~Sf9IYKLYvIGx8?Whs(_|GT)Bsa8t%AMrdL(9v$oJh7F2&HQ8-3{p#aJrzs!KB|F(D)-m=9#KjJxRMV3i;%9_aN1w?wV#Mk7U!g>R zs0}{Vey<=70U%~f)9vg2#D#`ixPDp`+t`@U($y3IYRU}|e%{y?jFu@ScE-#PKte_* z>CfP%7tZ&kOKt3K>E7Gy zK@f0(#-{0%-L&sAwDR!^njX9drA;rb3vN?&Kb1EZzM7VP$+1l&#(Fib7h#!>gMC4* zj)iqS*th#VOs>=*N1x2IKmswFVCY`y!F42hQGH@zVFZ!Ga z<$LXn3_-+&(R0f;#mvK)md-i89ddyrpAEKLW|Q2wLsY=k_L;v`Y9|M3gCd=JT^i2X zy8I67aZyB~RcAV5d-*V{o^^hj&qUGHl~S8f7)nV}>6ysYZI6-|Xz{Rru>bhyZON!}gS2KEHKrO4`o7;up-aQR(tf zdse*MZ*xO@1|H!XZ(tce(9*$S zXk1jygiUa2K~{&$5U_Yjn_AHaZ~Wctql=hg2|kio3n&POzNXsf)D#e{`mX6-r9s=; zJ@enL9q$gl=-`X2t7=-+>&)zazK@Pi)~$NcCH!hwwenS#!Qs2ilYkdC;p14FR}hM| zTPD{WcwGdkafJEPk%#bEyHS*O+pBG-~ zgcgW;cs7E2639Zwv`n*&TZp=C8ZV5^q;JSu%U|DH*)C_->V04}=3^Wt%;`@;DNnA0 zh--qF%+u*$zQ?kNtiRE?cpRT~DWxIHOuO_F3-$|`7DG2s1gFY1ywum^L53W+?vP4V zp_IX+Q%cB)ncGC+!Rsm^F)NrFre>u^N%8-NQ)ufXYMeX&MN-9XnJ|@F?&KIyOT8nb z4yf&-HMR5Mt{1nm2v6?Xo3~?*elgxVgS;L>%dpIRE{HI>s_A*8=_1ukbK|ijfn`$b z0U_lau}slkVxnf@Q*GvuQOZ*Rinl*d=rde(2j#tYjeRils`34oE*<APm=n0Y~d_ZEczD_{Z1sbSiE3LCBcAia| z@O=KJZR1|Vq*c|5VWmD*IPORN06DA8cS>f~m^4vvgPyq{$N~`AZ`{Q6Lf!PEP^QD3 zmf$aQTg&+^j`bl2S_FLc6v2u8UFHLKn=|WeN}hg z`%WVmy4|>#-gm-vUuFYt;H-7)(w^pyR+*X-aXQ4n*8eVi_z2;r5TS+}lhvZ7fPa=# z_+92D2VevA*_N}*J3XC;yP&lcL7?xq@E5^2Om!|{1K(gv2}Eqiu+>gR?>0SZ*=x^B zBpP~Z*D!zUexYlZs~V1e6FLDObghDLWvh@Co$}WKTj&WSk*N(aQ)Z?y?T{<{zjgZ& z1HX==KsbNMI=K46nSjpH`X~V2zR`hEsmbiwZ(GtGSG=GV>)7^JCmTQ5Mm(T++6VR8 zNAC@`_}lKbZ1i|Y6$>|kj?1ea`F75C2pw|pCNnklTVANOm8T#o<$g2h#&~uqa5Kx@ z_=@d>iq%s_F@>0>nrY5CqxQXIGtcOVO*g1g@pJ_X#DNEl*PDb-@&tYjs_?Joaa#sBs^E?=7U!{F0|-n zNy7?sAh>E4S*2z7T}IVyD;|YIEi<*?2&Ul-^DaFG(&Gq^7*R!}X(PG=>-Dc)5Y0Ly;A#?K}({=8V2v`M` zPSsJ3wy3aX#ECh1ymfWrZUR#?0*0v6CCJfFA-drvUENIm4MfUZMVsBv0sP^_4pg1j z5J;V>mN{pZaB~yZK-=Z3rH9VQ!|ywwn~Icp5Di?M08O^`y2^YYM#$iz`^G(8MGU< zI8Q2?NeKpHRIe||J~uDw!#mZEc#x;M(v3i9f^wm7Sm2f^~`T3@SUqT1IR zObD8)zi;p%P$ZrJjJ2y|E6LB!a zeD$vXI>!C@W|q4*5#g>9YeyZLSG2#T=uc#ttTS@qFwXIbxqRXNHIUmdx3#esjeyw+ zyk#M@U*hitu19~h-)W0o%d&$+!DWY|*wnDJrmZ)c_Myp**Y|DCZkcGy2@Af6-PB<&@=Z9z2EKY z;B6t*Zs|Vt*5v1q97J;V$jy$8TmbJpm%f>_TEjVcedU~519%T_NA2`|ObFG?=cTSl zF?(?0mbWd09i812zp-ON6zv*2aGu0KF8y}>+p%^h_D*yig7jTx(NB9H zuj?9Klnr&=Qv_h~fXru*2jrcA-UwI2Ty36V-nUBmK6E@vo7Wk0@HVqFy!hp+Jh!hX=yX}^;(1f#O4 z*ZIQm&R8@UaT;~RoEeo@31bAL=Ck*^Cao9&-o_C%Yu6Mc>1L+5`rgz8hP)8B4u*A} z5IA9Ex3#%s6rAyH2kC^_f2W@=J}TA0dE(wu@Mj9Y?F)+<=(X+EKrWC=is8 z{5wX7%*W*8gEX^?ub*7f`*gV3ycyU$u{2zE0?RjwUW0HubHj+bY@b1Onz~W+O8BrQ zga=8S-cEluf9K3?W~mRhR3E1PlgWW%2Hb=Rn%;<>ZV_0~TRXhIcB>~p1QMX6;hLOb z<{KPrrd_lbDg;9kJ}5~S6>Ti<>>yKoo_kQp!7(AVbeO!pj~{K@HO_jF#LQu!vt zEXyiK@)ht}W2)21MOtVf9eiYRp z;OVI4BC7o>^WCeWOiRJL*G}+&+;85n|c;TlH7kQ{vRTx--4bOa3ITwLqPV$Y>q44zR34#lpux;|1N?O`(-eu(1yQ?#RDFlZMDEE*M$FaHHm-2ntAKq@ zK|vFtE@x1Cz4DlRD=LP7o_EJfD+7(COA)7XyH*;9`^=nJk_PMv_NJ*v?JFtguX4iX z&`zx_e(->hJDAsCcZ}}2+E!}5rk@_^$+J;MRN?lTl-v&#`GRJxc~uWo*9SuJlKM7>mIpw`NO2)>1Gfkj;=-AhWf|szk{%bkL<|V=IcMj}J}?gyHla zIrOzwXa}d=#exfI|mea}2g} zx$F$tJ+dd!ML z+7+ipv=xpv9!ge5^>vNdxq)4#C+1|?SlA0~PIg|CI^8FScU(dVmLH;vxcNX@eT=T@ zf3q`9$4PIX)-q)D)eY=V^#-I)_QF*v^)&L{u|rIQ$w5V1)sIq7>5!`l1>rYC1-2og zqJ}4?{cqO9qd?pu;W)hTYFBK;W?JmyjeWBhTVNv&Zr(GGur3*I&cRLjvpgC+^EewH z+)Qw=-hG1)jt6eN5U)vUNS7rmKW{#(CI7jHfbXYl&`)yW4>@RqyJgM$0l0nN&QqLS zzTD+{;swPs7YJkR=%n%ZaW8K{hB;A-IO>;-zzWktvo4i=$+DE(nXbUvdrNQ3dGulO z`F^#8dFTLSICC_(Ci7|}Q#c&P*jV@3O_(Uf`8`WTDj}o5Yw$IAt^@_|Rs^^b;RaOU z07y&NgN^Hd2szPIO7`;6aS)L*JD_$1rvr=^^($2A_gp#KH}F)|rEx1Qr&X=cxJdZA#h}$=$;Pk9{)KWFNa+r3jzo$y)l* zbKmMmEXl76x$}qtAVyH1hoI^$nDj$9j)*!nWzLAP?r(TC=;HEPx6g`2i;ql}Q+&|; z+{Jp|IN9)+hfbld)Kl(!%eS9f@yanfRddn@nM3-J7zhoT*vZ7ETUYs+@C1>v0i>8f znyOEaS9uEY2D41@sw$iMh$DMdD-Rkty!O5g0!a>G(9R5#%)dHaqo3C6oAJR+cx6&f zq*FWEqFMUJi+-kKzA61f`q4X{RrZ^CL_5%s?A?Shn3pm})@F~nkM|-zT`al`zW0<{ zy-vtw8gL5&@A>m}vGmxQcoSYzu^573Mq|>uN#+JT{`Jn-o-qL@_M~ly@i`?xIIXs8 z--o;%dmYGiE4PaFo5Wbrz9vi$-;0ct)&3AVbvZ*R-l-G)UFI<2UIk+RDZ-#7w+`+? zN!Gf4{}8e5lv@=cH5b%uxe$3rj-aKw31={FP3Y*h$oidY;HE>p4GBbRd$X7k(+i(y zR%V%9nfi0C0xUyR3nZ`6GiioLk1u~tK81kp0GtDJ(N>gbGGODz6X!shcf~V@MO6r` z8i7$!H)zjW68SWz>g#qh=w)$*La1H<<5sa=k=SjAszLEPXxVGb<-S+ZomCmy$kGw9 zhyzOXuf+h-c?aqb9%AbE*@<_3JLB2}DBN&6@FI;V8&vpiX2?Lg1v9gI!(9;>cGM>j zGeIHN@`u0t58)a}@4E~yKJRa?8#>5qHw8W8wvBECi3|J*O)6~?JNZkoFu=O* z7hQ%A$oAgsj2ZN-WbBtS%kPzajlHbREz)kHdExwbkn-ff#0Av_nh(_V;MG-f4FnOh z*qeX~h$8;dD9mfH6f=Y=$g*xX7-_|WXyzuKC2AqnnJ#+h?HjaHiM^cEjw13+k_bF@ z)WV26DFP2qt`g@HCUEE8+FUaA0$gV}(g99Kl~529<{QBz-M9HG+K|yIe~=wr7PZ{I zn$L7Z5B*X>-i+DJvO6x}MlBZ!rH^9v=}HElA;9dMj|cci6<>_jKj)vxxSIwa`^k>D z!TarZfIRYDCNG$4S5UWue7oYLVwn_9tV%-iX_=Kc<~ew;&)QuII9~n`$yAimu5{3~jYcz@iJHX38J8?q+-C zzBSY}SZq6!KvBXz4zN|nt=@bR+8$b!lz?pj@nrQ4R-esvK-BL|nQ$j26b&eFgItVn ziH;*Df`Bs04@E(XiQE+w_@|84#(aL0ikSwj=8F?CQ+MHTqdc_`nKE;GgI}r3h%dau zj9=}AZst_bW6hrz<`%ggj`!ACZDNJ}7I?_D=RvzZDffxV5|C!ma;6HiCs-;ZmRTe7 ztK=y_Yzc9e^yMVGkQWCv)sH|^5(heDJ&#rmxcspfHWjC)cyl z=ayLE3-E(-kK8OT0N{utoI^z#)=|!#ULM-R*;Mk?cg@BMvMlD2gBlfLrN`}TmLTM&BAYDgSMHqbtT6VmEXtWhWaD$A=8gZu=XTlDHCBeh(I|f`F z6xwWK(^L@K{NWlT;|1+Cv~_4DrZBdA4{U=Y*?*U5cUN5J2o{D(5L(U?*6N#a=#hph zgZ@Dc<>7jCq}AV(t}*gWObOQbk;N79NU?$JmQ%*m!W*K&=^4GuuF{e z(|71G7;ptG0l=Q11qt-b)36<6gwm7uJ|R60uct+UUU5V{LWDSAxn@nt38hVmcWm7^ z-KLyW^ZqVVq4GY%wjK-Ht3ZpmxJE|(?_TQ`@qQKrh`%e^)tnyJyLk4>aSF<$`TT${ zqWld-)&3^)E@WcBUu(xEpQ7jhU&YfXGY4zfroS z?w1bcJ;V3OikYqZUHVDYP2FG;8Yp}51@>U=@Za*bAy`<3=Y*Nr2&`;+*Q0hbaldCI zrpsbQFr`VW1Bk*Ohpx7r%20w2Anf}sp7XtB*`P;P*EV?klyCgwf%&SNH=c-^&6x&Y zyCDG8Cq3e3iv#?=z{2m=>Xwdw_tZ&Su*04P5Lw{UyVyo-Qm12UOgWHIy}=H6^x0jl zR*SN{6`$K@@jUdQ%WE{p>RI4w;2I}l28lYK*jj-6Br6Vq2ePIBJ~4x++4DT|bZ{?p zwqm2XOFDt~R+6F_x^Nc`6cLNjk^g%)82^1jy0YJt;nE;} zb;aA;)hF%XrCSe>zk@1+yOmf--V z7Ni3rbKq$S`$j*c-a& zpQ)8W+R1c%?=>Q1Ib;O}qien%641^PJN_?A?;g(NxnvGSg`75&^SRih98yFv!ieN0N##)L{oUvK{qF19pZ6cT?$h&e zeD3TM{2Jx`{Ixn*;in3_$7ABq9Yq^18-9Kt=PWN!0u}8?5qUb>z9GW;Y)U38wB99>G55+`8KMK)kYH7aIE4Eaeu#xFoPJ>OFePI@e$484h1av}fiT zStn{Qj(mvT-fi4HEIHeCjsRX+H4Gk^2t|%~U)Ne~GaG)FG-*Sx!_fsSmWC3v zUHjd3f;-$sl02e0QOViHgum0==HPwG+ubXZL2y*j8cnxbkfCUxeVOfqcvq(`oM=6JL*-wyC!uDD=2!jp?(lZS+3$r9DW{mQ zj0g2U|Ia_u>(X=C1g9(L?X~4Wl} z9;{GuAgZ-_1_N!y$R@gf1-FD3kKnbdkCxZ0dEGb)J;?;G6e$+rY4c`?KyRGgfiH$@ z9)yNPmB%&}PPq>U{~Ez_-RSMz4IAlAX%qUaFw~)m<87z-!k^Fy=-oB9_xB#AJ$OY6 zn|{e4newlE)>=w+e7JS@Vw}T8F$F^Kg7?Ji>~@cWOJzcL*X$dF zEPgx!P2(=wqdcgCt#h;$bw~qpCv}`PF9IeY$l)zi`*4%JF70uAnhGcQUCX1}nj^FGbe};(Rx6 zvcg9SG^KR@#5z_*?1pkKX(8DE{huv8j+FV7<^E2emZi0Ze(<4TZIr%x65Zz={GSQ-c}o3!&z13)d&Em(XcB9t2JbsJjrm1z6+T;dpjAv{ zix~BUPe0H1`8v^773aINh%kZe((Co#0e@X}&TsI7++?%s3Tx7jwllhB+h*}r4CKOr zCYW8EgoxkXeYz6T69sHBB?Rqh9UApejyV}q?sM$kn|02{)K_8a(uFD$M{aY>)!IP@ zLGj_!vjzt7Zq9hUWwM>bw)3;2<#lhwzUi#?%ENtn%jR%xz?RGHjBJy`!lZ^mIf6d+ zu($iETUTOx4Mqrk^7N_pKR)$ytU@dymUcgY+i|WQ1KLf}ncexh>Nj@C0201Dcv^6f z#`r}nRGgR@(CTz;*xtR2d5>HT%xOel`}nDO>&%0}$J+%ORWi{Bcsz_tr@slNY;wT$ z&wOd=;*_aGInT#-Q9plu&^=G6^2_AL;VZtbYtZ)(>E0Dv z*r+bsh1W24A2qd40hZKW;SqcF8XuQ7C;y7w=!MR)%-WqY zKgGZt2?gtmteJEKy}1c<5jtWzIoP7o;RXO%!(5{Y|V$#}2z;c}V%al9n)xlQtVkf8nF=YXIB8G8wSL?hZz{9HIfq z{#uU;X%TG*{-9Li703yWJvd5 ztHN5gs=a>x%Qwb8CfT9?W=?RyJ{?_WFqz{@KJz5KiK6%(bZmx8VEbfTi>|L9ji3=6 zh?gIxD1I7{kYqP(&;6uDGK3+H0o}PL@gZgy?`izPYdK1{-VM4s*Cq5BU49gD!=0ic zD)RL5R2BOFQU#&cT-p^zBj~v4w!EUFsE{W61IK!90__*fPXx@)BY(`7nBV4#GjF?u zxe_mt^Kv-T{od2c1X>Y!q|amY(7{{3e(k1X8}n({Wc$(Q!R$+2;OXsEyBVTKlk1Cc z&Nh~b(!HTPT|{%n+AH{TXvG9aDLZ_h*`p@RMDQ+YXLYs@fsSIBb#U|2@YfZ}#jZCs zf8Tq4aVMj+Zq|SOm$?erYMpEwDcW}0Xmo~=)ZUUCTFKSXD-Wwe7q~Oh)5iKUW;kr% z2pU+t;ojSYJ{e9}m2n;N9?8dzz~|%%(_1*Vihb-xQRTQl=Sx#oMET`{KcrcSxt zJ5$ExGxwVi?ipI}_9n#DN@4xI9Zrb2_+~|Sh5Hwfx!Wf)*3%KCk88ER`n0}^`E_SC zc7yaB1A>*B`i2}GR}0qv5-gQqSH$@1^`LHjqi+F!@uNfy_(xq}OtrV$Nx~(>HQ%JS|%_;TW z`>^dkgqi&Fu&N_OsF|86^YzF`+XxxmuGCY|_4oFii0%=8;h^S%NEUbDR}V!c>Qzg{ zzFW(?$3Ne1jO=~|Qk!Emr_Tzw8JPP14*;vYi7+OJv=96bQ1Rw~w6Pi+JWU8`+Wzd= z_{4RQyUx^YpIEekUrh<6YiBsju$;?#cN5RD!ppL_m~$8FCi+!)w(UX=9pmm%!8psx zTXofNqX%`^PUzRyEER`kUbVWDTT}QR&+OwqS?>aKWwqJOal{)9PwTmkk~ycchruNt zUglG7PD{nXc~k9mcv?7zzrFInI!%dKh?0paza)0dsWV`tUfB`uMlWDVVB^n+@V7sN zrKfr@xuS(W7QMc@{aOJw2kX0Iz3Pdu=?W;1YS>)0Z;4_ujct<|qM2FU!~UHmevh}6&dvGn>_)<+mWa+IBUYLc z4Att}hAzJZA8FXB%=Jc(-vO57x$4~2ZNL4eP42W2O_6oe!?E1;3L7f0N)dI)&Gi$R zpy_jV*jdFe_GqWeyz$3?LX1Isu=#uN+;J-@U6pz3rZx<{cDI#oZY+Ck%kt` z&%~y4^fQi=8+GN02bw{r;attXs?`^WtP}EV0@hD)DU<0d4Ld6|eA_6lEi}DI*u7EN z8;ce}ZvR}z{PJ*nCr^Lgg#7}FLDP5bir41`%2+ z@b&XZ#KMp_9^=$def`Wt2uqZ1B}+sW7m4buy?*8c0dwjMKDN2Aziwk!3%!HNDeh65 zSgV$gUnUot*?6~!g)8g>!kU|KS3pmMDVC=Aas<(RVdy6Pbroh&OW*ZL;Jv`+Uzd9; z?gUFCw%Aa~w4Gw^HGZ5)FCi)m)1XIdS7Q7>j@C^-cl|~y)%WeV>QTvsvYl>6Dv)k_ zsB=AU-03^)lV8X-SGf@|SDdX(bW56ZM<(JxSF~|ql36nl3VjKDS0$ThY1)8PQROW=vF@S0BPj~JT zrhA{V-zJc{vkXFV^W5)pqNg>dwTusvI(?dR=v(Y94??yvE4=!3)wbWK>B0ppA#Il+ zx^=%wX9v^pnI-QO+TujEL>T4gJZ6NFYNEybx9MA(?FTsKUzwE4MV#G6_U(i7GQM9n zN{R_f842Fgftwxcs{*AJ3FW<2?b4by1y9_J(abCrn9YQ}Pz%}js1Fn&y*ccGA9mJf zBUUuizH`!clRA@5x7S1sDLW$;zE+1<(=Iy0>esLinY-svqW?K0+(-90;XXd|_I(~A zw&sFu-9@)uD8%Ty3L`dH;hHKmj={w=m$U;7MSp(P>SHR$2d+(p9Y65ZJRkrI^vNv3 zO@y>3_j^!%uDeeK)VL^S9H(iEhocuqN7_)WV=q7*?a~xz>owKU2sv(el#ni;)J|Is zG5a6DUh~6Q3WiBWi8C9OYk<`#M3w{12a>4z+I!S3v;d_ngXPY>&cBEb1oZv)nVl1b zvkZzHcIL6hs?5etJ&kbTYxCmZ@nOvDDXygJfWCW#J3BCa%$*8|7izNyA+O%qEuh@v zac!>qq{?t>BE?7DDSSc}TGy-2Ak%{~%l)_@*&ExZK(HOrZY$Nk#^vPC-KYO#-Q+Sm zsZ-uM_1*QIz8%~LqJ^S({%+I=3}p-Nro~0o1ur}wgbb>nh@OIjq=g9E7 zm7@_=|0-dlGOj|#dBSQ-S-3M`bai8c{RtISrP|!WF9mhh9x2Pl^`V0bWlrf9euV8p zW8w94Q*)dm_(?7|<7_l-?p$<3i6Od?)lsgYXg`9O+hKFn7D#$*I`_W`d4Ma4%q)2X z_Bkv3C(NZh)c4~yMTsuQ(W_u4YZ3e=nd{8sP4&0G1mQ>FgY-b_P-2d1o9b;GQvK^DZQ)lZvn?zrA zK(1apun$BNLRb;CyO(vAHGe+@HhWd%pgz?d4R1kEhR>Hm7$)Ida0qpWmk_1HEJe&T zro%~@Mt8S+W~!zbq7~yewI|Mt(FkA7rlHQkcDEL`eC1Cm0||Z`u%1%Y^~Y6T zaU1EtzPVM`Rw76y_iLM#Qza8B$${@-TOs*b4EH*;JeT}&dEwaIIf*3|#1n18tQg%` zd&T*@MofIbW2j5rUyMe zv&+VLVxQb}_qCM>?w=1%rz^+BHX1G!x{Ik1s2{E2Da`eW-bJjX-Hr1y)GOUa0n8KY- z3BFgKd=%Qiwh3j{Y~83~_l4F!bz!s!Ya&;szXtyIy!*w23t7g+|GoGATSp8EpQc<+ zbJO7}08mGx{o}*Nq>*|l@zI;08jk{aZ-Mhq+Oa%XhR5&P1y_!ZQ+Q_pMbQ%Ti*nsR z^%p9hAi7=`cS(q*q#rO!$$cR%+}yOi$o2U<_vjqhYA1wla20?~^gqXTT@5Vh!D#bM z(F*5+%0GR+rTQ80f8Nd-N)bJx)!u`To;X&VcN6&eOew+=U#eaBc9;vn-BzE4*Kx8tJ4vuvkYFyWQZ9Eso55f#u0&=t`wI|nl~B`{a4BL%LX5EGpHwu9I z*oXU40%sp*RVFDbxU-Us8oUGD?;@sRwQLyG(3qvi?OUtc=`HBF>2_}v^K||~Re_F9 zo8{4jW}M~@BhAsMIg}BHPih}N$t7AA;2h0#amTM~Z(Q%z*~|NE4%^K*(C)v_X^h9k zIALQPjaz6Q+;C2X40gP}zA|SHQ%Gtx>cKpO%X(LaPk4Z850A|{MsY;T+thR_xLpeH zEE-{gxlTOuE+qI0yOtRI&UM!Pxz*T1R>YIsTm?A$VRx8j<@~`_t|^o9;KMF4(5%>- zvCXdbMs29OtGBGCR$?+DM=yt?G@XqpkLa6oBdx@s*c*y0XJh6aac;6jRLh8oPSw`5 z`+(eBv3yJ=Q({HmF!2lhR3X6wG=lI_bZpIk-PjXhG|H{1 z==0w9rKx7;@BWdC8fmD*yrHrI`uieBlZOI_H13rK+cv~8gevU?% zPKZg_p34vP3I88J4NLet=NqL~6^F@)Zkg%%$OxB7Dz|4+yEGAwfzkxYLuCc$+Q*%C z4|V88@+5lSoYlv>K^b8LUyow?{pdI7>Hb)@HpDJI&0OiTm;8<1X9D$Iy;kfy5xx=D#BN@Nx&Q1 zsyUtVngQ>e?LDPmxQDZHGQs5jr_TuyIWtnbpsZ-Cq`x?|U}yyis=uoz)UI^hkYGs4 zgltKcpjvg(89fvwB!dDU&7MBMdq%dbzU;}7Bhm4+iQq+;rr1eyheQQJkv`I49IAt&>;vm=sAXTN zP_7vPr{EDX)``-jrWj@AuT*Ozr!;6=cAtL9)`FqtbjQ`Xoqb}E(>n~i0*5e(tjqUE z2l_I7)JMZ%Xjcdw&k4isbEOw3E)y}3^0g7&`UdZJuQu4mW0SqOv6} zbA|iC9n{p}6zJcB4yktI3%_6CcGHwgUs~PdGVy+^vo;l9H}YTCVSdH*gc72)VGA|G z*38fbT`mBo;J?Y=nO_) zmHWO^+5?91z2g~)5_NLxKJ5b6nWB! zP@3|Ka&CjsS2`yQ{yF&jW16Fhs|(#H5GCeM$(Fj3K?wdK-9youN@+wnz((%Er#(zb zmBh3IBJDo&6=|E5q@bZZUD~`0`MS<^kkBu@B9On_XE@Ur>Q@UGvm=eNma*E;g`e*h zfm)x4u0eH{r2|I860cf)gSS_T(9ylxH7U7gl(ab>n*XwlUMQS8GdkK5!Ma)aw&$k% zjj=P_#+BE{={{F-e5FEw*700VH+od4@Bp<>dUEZbB3r1La?Vz{dNwAWV6{5q!)W$) z>676?pr53FBXq{i^d`H#$jWfzt=)3TMWM-GHYUG=Lm2{!%(iA%j%bf2!o+Ms54>{h z!I)8cnha&`C08Enn>m}dAe>(~AhX-S7ObKE6LpZ8q3T;t`zlQ_PG5-QJJQ{ zIWOPA2hN7)(6g$Blr+3;YO6p{FB4aEB=>Wuo37PS_}-UepN8LF)NZfP$cDF-Scz0O zx?dmRQi1UNT^M`(WOVncV*&0Z^w^aW^4~L#CN_2MowI1a7xE53(mkVc$u!5ALaqnT zN0p&fNX+W!I!OTLu4g87=X)UQLRhOea!p+8{44Xe_ttyzM#CG~)h-M84I8J`4fmbJ z$tTy;hT2#K4uNj?-1_#df=(NFK&v!~5r$wxCETQ4D!G1^kIX*mwu6}DE`m$t!*)rG zE`$QX+n9!v@F=SK?=43_N{2J91ZS6(YUwl5t3?0FP|wH#x ztJ}W-)%NIK7uM!WW%HA$n!Uss*vf^kI#q`Z_s~*xPSBU>iCAEUPw^%PS(#8~uB_+~ zs3Q7wrP}>(<{m-6m?-Db+&stCUf|jsjCuGl*|ptmL?aTlVJ`4LqyGUY2@IW$?S+O_WBU=oo7*@D&>^F)&+*AjOp@t~5$$H&%IXR9=Q`84~5tZ64NXLPT(t zH2gL2z_M_XBSyz=UiIx$Li%p4vN&yE$1C^STi(&HB$V5!Q&CDUTUoq+T~b%Hl8VA_u*O;m*G6!{Q3BqXBkd$#p|xw zG3Y+{WrMs$O-L)?I`G zyk};6xJZ6|Wnx_7*!|Z^kbCzNLVowTuxS`6w6_&*WK)`yWyFQL+~B%~Qne(TM$n9$ zT=1#0VTF>7iyZ{S(_A^g%0!cQ2$@8g$Zo`Fd^)I|d{z^EM#)^-mCg+G*s!TvdZ_b1 zfDkF|XGL&Mxd&*%2*u3OobK&JS%W5+U_Wn%!jIgUXb&TkRIS!(Ovlk1(f4XU(}dew z=2&%HrNJppk#)HX9o6kg_(F3a9HkY>-yGmXLbr=68fsVWsddDHj4O$5WNrYq z52v$^Zrw$_WDeH4^+eoejx|hZ66CBt?-^pok?c3zu7-uX*M4qrjM3Zl@XtV+@=F%+ z;Eeu&gnmUtB{3aHBzOFzyL5TTXV84$42sh7*VVvA^J>L0blS9ayo23aZjYBz2fdxd zy38cQ3p!YFd}%#C?vm&uM!c(=2gteNQn}mq{i{TG1&uo2R-<+_ zIz*lkFw!PlCG8jb zIjiH^jORKVLLcndU}T&A4)^oMy6>eQ)j`M+K}PiEUG8Km6UhoUDiYPd$qHL9+}=wv zPDLmro=p{*DH67{b)vVzEd4&yeAb(E$|c!Z@Zw0a3C`{(wnk>gQ3Nh7jR$%5W5!Te;JWW6BaYvSBSm=X_gyh$tMvcIDEd_h{DdcUNAj0i5qXkz&N^rN*a=EiP$u**+$-Gy0zQ` zi0VBcQA_a8WXQFgFHui|r%`RCfi8`PNIb%H~ zq;hUjXR)X+j>I))W*+-^SEo)NqXc76Ku?`Jvg8R?-#lXFQyRFOT?Gxp)yEf4Y#^uD zt*Ev_=dPfA!qrYr$`+co!fAu={@LY*@qZp_BKPo28q8PcPi_4fgA){`(2NQh0&*eE z`+cLkd$}B}n2>~EH>@*~z`e#Jx1Dkwr(NCTNZp__8H^d$Ll2Qz&Zc#44bbNOhS5uV zI166xA&+Z)!^I_NuX<-q1b9xT@iBctt#z8Ihz*SzL3ev_OYh*j2|XsOoBxzH8$v6u zP<)oXg8P&Vt!FkcIbZ5dRC!4tz<5`GF>p&FbVRK$qnOm-&w_gI6Aj_jijMC*T3r7- z4ILSgC$+tg?wM)TAIYgZ-Zd@BL7XIDrU{~7rpgfD6?4VG+MNn-%q4o`*}_H9RVIyj z{J!t=s0|HiYiMDd@5s2a&-NT5mSC?CeR$@704K^ky}q51dk&*!>!VJuDsrMI9zF-L zO0|owy*sA-!h2%EwSnHeS^2v-a)U$eoP0%@zah_TMDFRcGop*07fxqzuON(#19ird z?m?eFrul;QouSO*<@n4l?{ZK5op=o#m`k&sQNjf_tmT4tBNzx7=y*fp=t6luVntBp z({reh6U7792QOY{YR{?d?=>u_nL}gl1)*)tZWk$3t>dIW|YAz7Z~XS z2i66?9j?v05ga)i6E06%-Z3g3EC=P5VI&mB>G#C{$&4YOeF6q(^SHuaq*1aF>u?p? zYw{^S*L62^QHVq-Ic-#C8dX7==k$5wV@H#qUNl08*(eLKh0!eP*m?dF`!5hW^tgug zAfmEN3D!cn|GI!EnXZ8Tirw(|eP+H~O0!5as<(Y~mN8f5$mP6r?VB`7RsIM`4wuyF zgL8IXC~eghna~QNn&RNB#L+ms{?*DbN_RcS*6+PTUn$ou$vw$jDU@EeSaj5w>G#n` zZF8syRAnw3S*5VS(c!deJT|dXV{l(42UtW@9wJi6xno4B_J06FZXGEM4B-9$4n7|4 z@qgPlBmio9+%D3{TX)Kv1|~S$-@&TL|G#{c=d7Aqew%3-P4fSif{bA9 z=LABia*zHF;NP;xwBz=4KUtlh+|T@6r1=#5E=EEvY1Qc4GM}_NuU`{Yxo@yFn$+UL zBYWLCZ8d;q<&{n%hbCEgQynxTc~0zTn9NG>7Xt*EuUk*>M-AG>)2ZO!890FK@-d0u z)MQbY??)i}WC?ukBQJ!_>~H%^%1|T+Aav5~zH*4q7PR6CZ#l>EOOX|AZ=HFfO5WFV;{q*lhptP#ER|-dZe(NAjP((wnY>XNr z162PtuRbt7t27lrqMkB8plafO@UmA^G&--?f!}5isq;}|(qa|CQ?GL4By%m1iL2mq zDz{D=Zs^=z4*&i;`*oh(iHO}!O0`E9(bFuCKM=(G`#!&Mm$h~V&2=$S^UN9ByCKDv zrICEMe#qzcj#=ILCF_?P_@28cNW$)jMSPC)<#_<=z((IOI5B-q)9kd*t4E4Y3{Jc= zkkyUt^s|sl+Sd^ZL00B2^3BL)TE7i%&=tiwWa^Q- zzONNeyFV^A2A)5k+(Lz9NoZgTWDTgTa9%A)i_{q*3-rG=i#K3Z9?M(}k;Wc!i0=kK zx_cfAeY8Z>wg7fKn2)r*GjHT&HJl_A?zth(&v&kJPtfH8#Y#-zipeK+NsAvK3(EQs zZlq_df-t3j{l_u&Hh+U#>jTc_P^C!O%Uen8D$;LT&t{=rOhTNfsYP zDo*fiscQ2q^;=j*6a%A^gJkIdo}h+)3t=hPO@nBgQT&5|yJ*Q5!J%YmY@e0my%dKK zm(*@ygCBBINB(mud(^@^5nGGkJKLFadQf~!!FNOLB+!$rbN^J?gpr7CwCs5VF6rhB z#w0o4ELmG+%LJ+JBEU{YGCu~YOFMuq^Ou%Jnqcwqowx8WSkrvVAEs=M9w|3~+=>`1 zJ1#45WFBxDDPm+dVW8uRoCIi*z5|zqg8!simfU*3)X%RxXxkbbk$)4SmMV`Nf7h{4 zA(8Sw0Fst*;TB2}IuE#I-Je!!N?K`|DY}2=Jm@{-oq({Ua27Ok%$sM+ZC?+4UA6Q{ zClzX2#zX4jkI@ZOdu(y$k;7Niu-y`Gn2SgIC7e{L2~``W^k%$#MtS+yF!|`0Aj_}) zWa&2%I-fRo!KoaCN_pe44zB9_FXvw=K5 zf27PjATrp^-$hbX<+$=^e#^BG7wqFe?Moy*e?3g2ug9RaRMFUBlYz?ZAAEwAf&l%$ zQ)+IuE5!j%2-|-Z%8e$nV7!4b$3As}8`Y4l4SN-SKf%8h%U-06xsH%Dm3Jt=~lIbICS6fognm$3#35 zXpdb3fS-VuOU{x6@Xx99gVuCwYWT}^!130VjQ%g62~;9S-sZa_9KfTDG8U4s;!_7} zU7X@&O`x!!*TC`t-6;Xuk)2L~eldUrp@HmS>)}#lNU)ol1t1j!5cY%03<3a&hQgf2 zU%YqV{4LrN)rHIF@~DDY^E{R_*2$P3nV;@H$ zM`aS1PCKtSruwzlLN@XM%$r}^us_BQ8@V)Zx4*%Iy@m(CFxmD%-mcU!39it=3s+Bf4rVy||noxGmhU$`tIyR9!+Gpc+9MgF# zLR;w8O11&$>Cm6#GErm|NMl8nb)L9< z<<*ZtRnOH~aO!;vz(OLq`%$cZ7Tchiemr!f`DrAt=K<}S&tNJ|*o-`)aws@h2855~fqQKlX#e-mD2aby}P;OTNXiCLafpK=oxW?sSM()WPtm_cO&zJz3#(eFI`S$jN29z!@Dr>!7f)mqQx{A8X78mLwqXG1+XFB`?H z>s*V>GpMg&`VlCTM`cw&H8%$S8GkMPe0yVUQm)@2|3c|i?wiM0-vr?X$2K-g9dT?2? zpC@=#doJq-OvcF@T)~BzKa^AxB@Clgl`0Wlm~!$tTLais3o7JW}q@(S-%0pZe6rD;17y)9f(axp#aaR ztjSQOj$QvQt*3N1zwd!sRpyju9$4@!DG+0*ASrkig7$m=C`sKyxxK-O&%y;yhagGc2{y?qGg-eTF5lVLK(D``9^~H;(T|;=| z&65E!QK@%dt+|!2@tkZ*m%m)LfeNVaEEcCWGA*N?FNZmjwWyx``{d_?BAcB$0#X2R z`9C?%weMws%>yS~8mM^!*%mU_)n1K07WP(bpG)YMxAW}-*5M;PF>w?@;h1*c3r z!HqQsQ^LIi7OfE*(A=Z}CPco_YRxNKTln_&YGcx2vT~mHIXj%0kSeML8xwv+;;}m|ZMDT@x zM9TFS6=M}!05jH_lt5aneA>sZra;;1Y^OMh9O3N@k%VN4UZ3GqFR-L3@}YhQ|M6Lp z2#-JMBLQc%9_zBWoNUxFddpQOxO{G2qbr!-fftCB>9XOW`~p_UmJa~=1LE_%3Vl=i z-pEX*!g&EIGNxfum|MocWXVXdJ*p2HdT%jW1VpVra(9Z?#^uB$1<72p8=eI3BRr!B`;mI}-44OAy;&Cs#vF-9xqnK-&nA*53B!Nk`wd^$rX40qnff!r4U|Rt5C#`46)ir=BIS! z6iZ8uMgjujDDu9K*w)CD1nF|??q7OWzfmQR&_oEiW4wQ@#4jBbCa54&oyVmzoa~F$ zmd8FJ0-*OeqN!Av$iXd8L|s!~&Wl#OtygE@fP+nHeYg_RPNc{Xywj5+CA<~^Bn$pY z9(S?CwLO$DvUnoLBXHX+iE@pUaG$YPafIfDTiORy!QNY6RX^d;JE37TS1wCgcKie zwvmWMx6T_#)fZp+$q%+kuwEZL&`NvGrZ3Xq3aX-ZpK zmHtfiSe63v;tgodYPOjHpg5RZPX{on1yri%)`|)DHsvR{#xpNS`aP0I~n{R4&PQNglC^P-JJM zMmi6QjwmRC zPYZ?*f^Hs%%0jhHW!uY9c_32uF1#qidH3Nv%zj1! z&3RxLV-FdZixAp1=8v_ z!eu=VN52{B;qICqd7I70Q!KN1*8sKU9gn8+9P72j?YyD~Lf(s>6Kbg+rc$$rjnn4_Abita5ptn-#QV zY4D|RoJE*F_N1x;A%NyI=~V?irFr+mV-{7x0Db{ruu`|89X~%mL3tp#wQ|p(BH2P- zWPe%PP|Bp%GRFdez8wBbOIQMM{C0;Qc9nd!2^xd6ab%L0Br zF^*zhZ~r+t+Mt=TdaK6LvAlU12qaDg{OH3Nz$gxb7t;z?{Tr>I6E0Law&OEpYggxo z7itf{pZR|3oIO&m{f&g#e)`{NT{hsU*)o`GYIec&GG{*R3Cr5v)s|5bJHH|QW!^bi zF4C22-#x2$$)vd1CHb!Du{D6S_t;Ji0E&z!$&MU9(y8sReOr~Eo2%s=X7NG@rE6ec z{U(sWfn?J!G0zi~CyS^Qc}r7M@OrZNqEYe)@ z@!tUeSv{bF#@KOZ+%MT-D`6NP#U!3$P@tthR2VFuB6d^gob-27fwdE%N4HeAZ~=Ay za0B~U9|niIBG0DqBI3w+zBR#1$$+U&mqEdk@N7ui=SVr>4-!bP@6u4<&w>HFRJfj5 zi_yt95`J=PU`?&)V#uJD_JfLh;ic*+*vwasuftVinpJu7&s1@|$1J~Sev8(U8LV*_ z&&+(^>!^Ak+bP{JXg73}B&fJj66nsU0X`5OUm7?_b~%oa1`e4fyNyFk3;Rj!9^XxE zgoI6^(!TM6t}X=-riNufL2goorYgK5z3a>B=G7?| zQ^&&jZ6U8t`^-o?tIJ-xnMp}By(~QM_$uhafpkI%@c?lACKbU<%;5Yc`SC|{oCI4< zQqYtW)r{>5b-EU9D9vQ2 zm`;HrBhzN)?fM1Hs6u{QK?U07JoCqHsI5u~jardT2MxRdWn=%4Qa(8uWN)38ek3~x zS^O;NwiJx?H={;fT^#{jx4XrQr6z=9*RzERF#^8MB~8mb7R@24YeDyKg(E!1r0lz1 zXkIuR;Uk(PuYaAYA}=8cc7~Q(Q$9tJNB%m;y5u}EwGgyE@m;jIX+=*> zdTj~G`*w(gNx#gE-E*7KBL&|uU`(2jg=Z3eyeCLY+ywpzW zbwAEyiT$wwUNYAL!+)|g#{$wl71I$dh+N}4Gg=L?dzqpJ;E4g;ULSOSw+3GB$({)E zd4bF6tbQ2EnZ&f!(&k(sA6dKu;wIU`LrVhAzvLcUxPLQO-F6NgDOp>-z5%T3AR39F-S-&U88AkDTr1b355GC3AmE43P9XL!mp{-oB(1??FAvLZ}f$ z21gY6%PaycEZ!yD0&v}(x)3q9&x7m~n`G;9z^%$<4`b8ym6C{pCGngA^*bICBnd%& z!89LWD(GIwzE!MwMW0bJcGw+IRaUOljJU~!)DM(jJ)!bIP2pS}Mah{@--Pnqp&w+R zTB;0bN1Wub9$Kz!*^p?Epf>Zq(K{Q5G7#d0n7vICQ_&Mf0^A2d$tk_Ix4JA;(+vTg z>HuEQ8es2NG3C=QA?Le4z}0VeWN%1}Ij?{P&xu$SB+H)*OVJtwT)6Hy(oD|?Oe|RG zpjsk*wWw{BPSQ7dYQdiP%MGol!IM1we;|SU_Q+0xxmp7+PcvtRHYF0o_uGO$Pw|94i%9YqYPe8ZJma=KmMnKyiFrCPd5jDso5)E(ZqYk4 zbK)ohMKGB?u+%&lU~$B3&Hv6KRV>A6bNSP$&KTM-S@NcfvUz~zy{#pQARk_EHq%re z!P9*z*k5^>{sW*{R{vc-*=n6@MlI{_y5W)|6D*gPtHw9111NII5F8H>AKQAQ#^eAj z&#kW_PbEkAJXKg$ULBZKFGlWOIhLn%-rI4_uQV6}z4d)ub!KpO-=$RMzpj4K@1_R8 zx;2${)pZ@4k@-^|Aky=U8vR=iRd#)!oXq4vqyn4X47XS8LO_R1$+LKhFt7bGSR`_a z|0oZ4<1^E#19jUnH2F8Ul6C`nd1eCuuyO!{rS5{?3z%N|tS5C>K*D6u=Yg86N{I#V zc(hRK3S>6`kcCkdK<7BUJuMHYI7?FZb02!RtJi5JVrqMBOr+FDiLzCB{$Z_!rs@yb zH+T5LFHvtx9awJqaUS{2pU+P09K8SQWG(eBS(jBSEquCvl3`^?TMjw|;qsGM0d~%6 z=j)j~r^H>Pj%LV6UQm--)XxFUu1WNts3lmvsdYv*SX#gnkgKH^I3Y0i20&`3Kusuc z%hN(X>-#-Q|&$scUq#KOU{Fv zvyj;y$$?O*BB17_RPAuV3oqxz1#(pry-DV_ypR~d?>p)|-=>0|g6|25DgH;joEGdP z#8-RRH>zZC0|#&sZdBtgbh(JV^_fTh?SRU>K-(4g6}e~hh&YtyrDgqbeaNFvqsC^2 z0BuOsp(^0N;VI?VlmMGpB+u_$eL0&E{<0fTz(8d4pEPo!N@*zom_?8q@0Qg|@RVWY3!<2dzf~1yiF2 zKr~p{%y2T2g;dTB5Wc{{|E;;yST4I>_DhVXR8X%ZeM}MuX^f~n`C#ehmGU^l{nFc~ z?tvOCxFI@QE~Pth{P$o|*_3*iM7V#^)REC~J)pbF8bE@xcJwjb4E|PsSsJHrxA1BV z{_?ubxIkZj>b}M3-FdlxF6k4?0Cn?fYh5Z&M4aPsPv|kb$F{6EzOGL|s!Q#l{%J1L zzi|83aHjxI5(^6*8ZfV_IJegXI6f|-rQgiM2L~hVZ>w(e4ZbQoJt*t7Ch=J6>CaMu zUA5cDg^CLwKU(uIKav9j0UGCTRO>K`uk`<1!vSBAgOBKBW$?aN`9%s};GT({Gm+!*k-Ky_81vK&hiZ@_zBFAM%HT$?z9rE%Q}R zNP6SdDy#i4g&|deY}NQk#eER}$Yu#Ze7nF=>50UZ#WkKgfk7)&nMDI*zW&(arg({y ze;g|ZJKmLz0$dz5GX*7I37)YjQ9EX1Gz1sqf)pbQ!?Ekd)=!Sq%6pEf-b_CU{snx= zvxr*yVr4mPn$d-C`b`#mRyEV7N?2McZseKA24Ntca2;eorZk`{iY79z76rO>Bl}S~ z6`+qzjsqwA#HBVVU#h}@k%s2@_i9(HYqe)27VQW6Y$vi^fLD1j%YRFw7MTZPRnofp~z>WZVJc|pZnxXY#_;V;7K&nk3awO}_8{8&7sQh?t^=F1ovPnLb^%nQJSm^@&==DwR(usZi?s^ZWn(*Lk1EIp_7fe!WDImD>)f zbRs4Zk+j4IjM#ww;f10APgU46#Bz7q`H3Q<#2WC7G-KUx)2P-SzG?cL!Q%&{tjpR& zM610gIiG!Y={`9y)#)D>qbz7=8*@3)C*6RiyFae9^am0$4nW=Db&%oS zrg1}FF*32uZAIhY@rvwy)-t%pNh0E=Dj=v_5DLN1lK-}ne>sS-Oq{VLfl#dFM-Dm3!=p&Fe4N^rMg(0wHZ z_|Sh)LU9Rei9M?ens%i4soiaq068=m^C)IraW8cp&h3#7g;kBYFHU zY{p-LTT^m0Fv<#+{A|C*czZ?vIyPJkLFmA&q**K$c(QF!0T`sHT=gy7mhb)UjGf{> z*$%&xC7%_rgovY1%#B$GGbee!Vz`Vx18NDSk^Tfn9;#c&FXMF!SD0vGwlTC5fn`cK z&4R2hrmX#-01)|Zz&@Q>$Wd{#pM8I48;|&|dlu00H15z_MMxA-~aO5d45m9|` ztvt>@f#AmGKrdDBnD@lXp*w%4SIs(F#}o1$gB21^8Yx;pwbn>?d`$**h2022`VkMBR zw8W@Lp~6obe7*(Sla8kuq_!9MaWbyD^~JcieDt2g3nfd!oPfrJz+yE8Ot45fD6Pto$Rp#X8Sn!pg}KkG0p zjh+bXC&oy#eN9VDxx9Rw=kFve8TV(eW+V_Vu)pyU#x1P1Gn3!6k{qE=qdJa)_sB4X z9an|rlDnSZXYw%a9AN#QKc^WStSf|+YBDP%n2dwk>X$8iygLf5HRXoPY2QNqwr2%# zj+7z*@pah1ei9Hffbg9IIO}FyOSjlYuXBe{xoxn~v>fRi8S{rh;RF(p$+0s&PpcS~ zl?B?^wHF|)YWcNznz;O>idbe7jiA}6^gXOD@B?3FyM-Go63I4xnx6Is23JZzzFW>l zopRm5bR_{V-hiTaBDK^no`jjtO!Rffvex^0t$tdxtE(~n^~)*b9k&26{BG||T~A7}98 z-zxOyU?oZlR>sk)e${%`!!lu=Q2)UKmZBR+9X0ee8F|4jhmpk4(&itiB>CWu4hKS9 zw&Ab3ONUw#F6`rQzaa!~4>D|W&iS-IB9CDlG5tTJ{KVH~Utni7{!?la4b5?iO0l#ERa$E*oDe9-)qrIfTwzE6A72W;i=KVZM$ z>KU5r(VNB{UijeDz?Ll_&j_{I@d}yk>;bMEIY@&^yZkCShAkiU5fEMeXT&&EW#@Sl z0IKTq`N0ZS(CaBUCr^vttp<$Ye|locJbdePtF znJ8Z)JYdB zfy*G!85K;Lz^5k-Vi5x6@XYxDe z)kSjk5`iM!hPd$H!@66IWydPim|dPic!)0_lj%V*#Db?r^W=Lz3~hy_Csxv8&id#Lnh7h;Ge$fS`e^GFnANiOc7M(jwbr%d zHHtt9E#<$)&v&HJJab87o`3?3$5mSIp94KF+|3wz&8${QNKPY)Go5njtb9$#v_{&m z;_k0RlFf|mRQ*&)cu%;Y4gR&fXJF{~wIswaw!np$=4$`Mlv&f^ZE)rYu6%8|;qVG& zcH-#z9*cJ2Nfr_}h3;ft=%cgth_}SZ!EW9B0~P^PlPraX?Y8Sv@zEo2^yd%l zqFJD5SBf08e1?=Z2(gGtm6kIabo}ZD`qOnGoli4p~hD zij7k-&caHo(WMP8`XCqlx2#0Yf5MV}4bU<9{0`2&o4F_fC=~-*#w0(38py zu&vl>=W98!9-o(O7dc)TmiKkend@?Z79$@wJT)`136>z4P`+DWBX+Bdks6tg7t4mL_d13?;;+xrKuFY5*tsOV}J*gqy*D!cQ{ zZyqLddy7`({>EgD_VTvFd~iT5O8-g=a01H6t6{I)gP>h8klN|l_Q_Z5(S5Nj^khxS zAaM%9%L=i^x4W$=vuxN;`EN|1t8k~0RAuOyrrGJXqP<=8M{<_1F%ko-q@p3ppjNZq zc^H*m5XWRFllZ9>oCux${6a+<|DX)zutZ@=IM7oZ5fJb5uLu)sQe2^+?%pSK2T$BW z^eALwg(KfMK-SA%nP+DaOo_M*{w;{ahkFUMCVb8Z-@gO`4kI2$E4{i3+&h(-9Gxl5 zj~QE+6#ZQ&Fo5vmn7dC~lfa;A5c#$4z&y58rI{`b-{QT>(kn>`DRGCyT4e3{$VoG* z-eVTfcCg;&=WQ98qGTO)|HZ+EMw6YaiT*j?um{eqT7g~j8ryZ@i1#;}QiNK&VMD?p z^>s<{CHzLK}sgq2K)C>XCh5N*DH`+tuL+Jkms8Zw>~y z&O?7sNRPxo!*4Td`qdZE<6|0$W;gbxB-?u%a6sRZg7XcXO&#<2Ps12{4 z6=A|WTs@4`!1)4#%*krjEqX!vf*d1#05bMb+83!!1bQ{o=(mr=%x0oSi>b=^h$UWN zrQzJESoaaCcfCEhgKWjC z6Jh%g`FRn9&0h~8I{--? zOXWb^!v;)8st0aU5`* zjo?F|$S8BAWH5LXQ!&D9OtO66B;f~U>EFurF&qA8yLMv$J^dl;z_Rp4OC;lX4b50O zHq#8S2zsmazj0i)%f33&Nd22VxLBc>tu5Z!?hrMYSnr%v$OAE!XNq1 z_3~$7iYt31fTBkdBP?h;VK=9_% z1T$l+tEQeX+z57xS+^~oJ9_nWxQ7Uc0Z$N0LVCDg%6J<|A^7{}CXEfie<#u;roy2A z0j{P4!cQo}J^N4AoO0FKBL{t`xNb4Lu_O@+tY+kx=q*e^!g;!+;MLlfrc8mWFz@(v zNe_?(out27)C-G3z}CaEX6$XyMPp99@v(x>_rbJpYRe$4D!U;v@wgr_QE7Onrd2@j zFmEy3iO}+EDRPdRuVX#n#?gG;^0*2l33ysjZOI3&wccoM$Wg`i$d%FNZBr-O-qH z+A*G8$KS4XUv3mc^iMYeQO48DvikTm76s>CDX}@aKMR9eng)U46*=TgzMzO35zXBl;b4>-nuV7$pJd=i!GwM?i03CaiWxbq!;Vp5csf+;<6QiyTr!>vA~^&}78%pZQ$KcCqqy zx!aY=$rC*O{alS3xM{+t%S6ODpTl$5EOR7nL-}7h+vx;NKg7~#=u{D6+lyZ?*H7x= z!k7lP6V_Qr!Aw)btjwFzhG1~flc^Lp{a>U!pAE|8a!s^T{r7Gie`fQC3z1*@c^Y}E z$kzrNsxJh<>$*}id%ORx5j_i#rajyPx|+-{|1oc$Hly`QeEhLnIk41qE4k1|Z6w`_5_oR5AR;Odkwp?4fOr3pjjI^O_%*W*jx#PmuV{ z7)w4xl$s|#1dmCyV4{1Tp;WLY9ih40;j9UOw5v}~8q&v5Xa{Wtm5eL8R_wfj3X+4< zWvf=7(~h}x+PGQ!h{3bF-+0{>0HmZ75*-Yu-9j!ms}*WMmvak(B;jJ0K{!-8G=%M4m;XjOn2iStk`#CsAb4zT&EQV@TpEUX!bN}r{p`Q*m z9;5`A{?pE5N<+9bctV;fh#S(Ik1f>v4TR?M}qCe#M2NgQ&nR;Z(+WE$A;eunk) z3KSilk%xU10oE!nz9>HrwW>{!-%0(h)ns z2aBEJzr8z>)yhehQ{NzD;v8vD(6P6@2ox}F-qZMHF}X7SA6^oMBUx?X_EEb8+#Rr& zS8czY8T-=}O0WIrFq3ZWM^9=YbfhJ*^qZAkM-f9s73*#z7{&odgFC8xnvZ^Eyl4nP zm#zc30EQrq28XGM;s2^UVb_9n4RL%$EcHq%>NVC&i}tWekMm1_3xCPa$HgW&^|MFL zv$D)(z)*Xb`n!gFG@pBe{29$JlKE)D3pRLkrU7J@TcL};jRX4bMxnvoO_MCWqnG3W zW(6(N;$ds%?Yv07-_>mJkAZBxB`9oYee-vIbctT7J(=v> za=VcCB?+^+DdH$cVlu1s6ccMBBXQPrB6@ZBmOI!_unEK1?+ZLh4zFxY*rR*K{IX7f z#7sNeFpRGGRrgxL9S=2EyPZ<&e%vxC;n|+VZ&-dT0A4qCV8&A8v~A7Sc_;`PvwPr{ zOO5sGeE48Vi68%ka1>EX@W^}73=BoJd{@TV%>wM%9hg#*n?NCJHBU^BPnC6-s=UAcmtx3VYfl*{Xbb> zxGiqm8vEZWV!?r`cCAYk@E3l6pb88sB^yCDOR!(X!8bM0kw^acmY4RcJ=_;VUikZx zjTH^X zf#r6TWHVvPbLn>f>=$-qAF$iKy0sfKTSMf~CH$1N)&r0>s{~P4-n5E@NCHQZRzfOR zjl2gFML-IZ7xP~-f9#r#E&c`9N24MMvqCIAjF*KNg~k!{>pVhj$@o&Wi3F>#-mR-Q z(r@eZUOZgIsYjVlp8a>bZoo6P2SN;)_WCSX!wPPt5L}VYf(IY9k$n-K#Wc`O88_C5 z3%Y&{UONvh8Wtn05jA3x-FPXudVJ!($cBP?KBx6HxCz{nnxs?Z?nbtBE+P9=Xu{pN zr0QTRG>+b$kQ9pxBmhk*Z_3t=#qgY5P}g_3T7QFMKhV2)umLMA&YK$j$VS7Rrxw96 z;0S749qyc*c+ZA<`wjUOV){hAW@}&)Sq#Q4AGHWno~q z2&>Qs)nXlIc1+0lP?v7SC<|yW(H#Q9x1AoH4h)qwBD`U zR{_@AL@3BO*5YjK^iDHIn+?vga{(x-JU(Si=uO)AF&L^-T?`BRI&Bk$5HWD1wT+8d zYE^6TBoMsKG@s1J+_qG?^qmkK>66%m+%y>m{|~5hXJjK%d3TfiEnxld_n$fV_rYg7Y2%UIv+-F09 z8o2npVdq2m=^?8~zVV?p7b&x&@J_J#t*U;Oef|NNzPG_)zDCI|cDOzMoJ$`Ky|O1k z_Z5^=sq^a0jssd$Zb`1!TrtepxVR?h?}SyyG?c|Zf~|B1h#7}iXL@3mD5w%g$O?c0 zST^L^g$_w%$V$rRd(3}#l2Zb*fmF|Cif8uUKo&^1P}Fi$xP(GQRUr=C9yZL}{zhjc zn(Q?xLFOrQQGUPqCXf$Oz?zT;f5R5I)&k>*jAd~OWcOM006o$r46;&!&=CspJ0%59 zN)j*1+MN{YUhZ|P5Oi3uOkq3ye9xzRn%;)~)W20y4AY#8G`rYNA-OPIE!qJWP-nEm z>-B?!=7coPPu}X!UCUVA*bkrZR+byKc^XCa>2ETz%VZw1X~HDUWciMhkfM-?FY+wm zqf+Xcxt~R$#%Sr*f74HA?hg5ZCj0l8(Vg07yxoHmJR%TN)RVu8P*A{K!%F1Clsi4r zwFWYXxcL1gm&#>j6vMolY3!!y3!0*b055$vlIvw~u@KAzDR7BsYpa@ePsT)(o?h{V z(N%m`k9@BMzj-j1U>@RXV2Dus*aIq-h=TrFqMj5l7vJ@=CquRk<_c@d86<2RxjqKW zdp+&e7sP^3F^#0$U0ZX%oR263;3En=!h04;v?%MDPCvzT9^1qMT)S2JgVQE|XfjMw zK8M=rP+Zcww-fQvZG&sgP6UYfzQ2v+&ebk{6osO`4C=TfE5C~I(q@F|x=t_(iGSPR zfQehLetL5+qv-O3&Aofcg)a6(f(egcJR$P1uUDqs>S!9(CPJdepR?xM8&Tl3g|Bp`l5d_0*6T~p2J~t{?qN` z^qBW8812RD-S;24Z#R2Yv@c9 zuYJ7P)U1{6U_U2kTRRU(O)aQ$!?n#ViD?F}?4O^~j^nr$=#_tReN%wHyg;pE^<|A8ib`NO@1$@wsR9sX$I8yXMAf9?OE9b$0UP zBN^{yZ!GUp;Z9HFc!+`PDaLI;i6FGne;8F?9F!m<%;Qf^llL{8{ksRd?wv5q%^x$8 zHvL0muEARmriJ*v-0!Lvb!ZlDcf{Q?uJZZNtEn*_DyV0#zlzB1W%8X==B3OFrN$&GkI1$3ghlyCntGQ6xEb8V2kM5eP+d{snptL znLG#mcs!=;?4dL8y!PkOOo-D}CI|Iqh6x)}@7Og9V12Kau{_YhWu8vyc3E3}+pDPU z+cEKX{^9I2B&}q4S*R$^<>!D1Od0p`{{SMyH$b8);DtR!WPGUK`W&>CESTq)$e~@D zdh7)-V0bF~3A#T67u*&TsT`rt<4<6#3HKUvoZrhsLe!ZS;{L`eCSu>o4Ps5dF0Xt6 z#mCkwsqFS~z_^Z52@;QjlZu#UpS+{tV{1D6%by0ca4>rXwkxuejPfQ_mYHsI&^>)N zhcP1tAx8lULQgI=yZMa|du_el_GlP@|1CJ#p0fv>g9pcx3#Bo}*_wuBS2#lX3hN03 z6ijcHZHGK+0v<>?_Q@G;rf9AK0tY6DVn;LDp)Cu9oy{{^#AP&`qrspP^Hb!W{V)af zx%BRtcR266Q>*tD*6>0qw?UYn^pYIjRB(`;2Wcx6WO=KSi`MuMXZ^L zn2vZ%8Psw0ylHtIA$o$gX5!EpTmi3Zc`CYWN%&j4Z4o<2ej2uA-Fm?lqEXoi)Ycx1 z!7t8Q$cdsr!n-cFG!}GIv??<**_t~IK!9mN->$}^qqmG;%DVnF@6W&0&RF)poAWr< zx=Ifn<%OGA@zxql*Y6yTSy5wi^{bJS^q65+OEU#W4ITel-C?S&c6Z(gn# z-zxkUa6|{2X*eE}3ey!%6aBl4A~$7DyE;*H?=WZ_`K8dc?b43L(hO61Mg_*j$wJj} zNX*;y;W_AaT#P`lpCSnMDKsn8>S< z$Ahs5{VpX!vq~qD~PnnRyr-}GdutDt`Y}a|3(Gb6xlWVw`q`grNG)|MZz7be-hG!oU z!z`F6`&InUZ|_L0$!;~0vdCk~GgWJ38gXi?{;V|4jd>iQdiNQe_wm9bgk-0htzxIb zozlEs7#SVmsI^wm)`mktL$IsbnU2=k0GxEg_98#53lA*~R|RzdKOme>8y_aTc-(X~g2F=$lFv+WbV`2L?*0#sy zrLDDFVq}BaeZR6%KsitzwKp7t=hY<+M@9_@W5VH1{(;n%Ymi0QnlgkF*vmeF0xAmE}xN zJiST5NLCrt&ayc{H+wc2_Y;pweU%%1a6svt>FYsE^|@puO_(55Ch_kUchD)*IbB7WT+*`9`q?y97l$^1CkU1tg(kzdaI?I-Wi*m;AE3GIfSY(94(^E)g&1tX{1=HBk^b=wVav=|ND2cqSf_u*{ zEYnK`iB1<&e{Z;=qS9`{M$MB3r*9ScX!13h>_s(?+-^fq+8fN|HcxY1N?4%6oc6>F z4Tb(1gsq!i2>UV?z47hix&)HNR=zoX*0|oszVTpK>SK54DgG8oP87aaZp%5)Tm4wB z@pAWdAAo|{daKc3ou0=L*9}ZaT3N00p7u4rX7rwL%OOk*?J*|IDmMxZ^-BDKFkGhj z_nTYZ{BXZ2EqrxFA?Wx%3~GGM<-a!S586*M8lDspziTN*pKtdQc^Q*S-2(4cSHYyV z4as}1{??@Xe1{QziqHSN;Lq*n1Eg2c+-i>U=k`&xR5b9z;p_Go1dyK;EiR{eJT z7$(B9%lz!LNj%N_8Ymr;Gktr&g}1*MOYM$)(UHQoMU)%U^&!ai^)@YR946TDpq%G> z$mRrND;X;eh?udqa&N8LF5(W=lqmjCfjfU$*H4KPSAZ~AGS$Dx{)1hXJ-tM6>cc=> z0?&((egFbe<*^@-5~0T+alXa4f4GYSWPiHC_&;HPm$#j3#6{W$Ee8glr7KHfcZMo4*flH zyr?QkdbH6x8@WlYYgWW(V#-9iaYegViXYHM?nI!!sAE+a=l%JC;yM#*E1mxC{XOaIJDOn)eEY|kE+O@A%bJPAQD?6p(vBv~gdsad2 zHNP2?9x+veo3VuhwyQ7T=~@oAYn)@9uNcLZEI6;_D1yWh;NY`T=~`7!kw_11^R#EfyrXfcv>Q1wWrw-S7I-=v-#W6PZZK+h)Lt9#-uyo@jj#UX z$8q?9s3;8G$s}oK%38nDY>R53n-p5gU6M>J9I5^v5LY_Lj#d-eQ?}!^J2~rVes~Eg zhyy;!dn@f?8HOM*C8oN?u60&l@iKk7X-kN<*+J@um8kU~OUDh{QYi7E0l|{(dWH!& zB9?+7qA45RuRqGcWzUpNu%Ac>nOd7gfCb2(~pGkg@X><6LXL^b2XPqRPHVNkf zp;{Hu`r7`SLdw7IifX!DOCee-{zDv^AW)C^nsO+Z!@_#$ux-?{hk8mF*7`^T`|#nv z)dxxDiQhKxHmrT(Ha(9t30w%H8!$qY8;q3HQ7-fm0Q z5i&1xrY-1)@%E|~jmd}7ITtjA2)1`;9#bnWN@$w;PV*Q$UJf+s#FQuOOrv@7hW-mc zFy=CFh}io4rsBS5<;n9tp*;u?hsi#u&Qx|yaq zHnrOJ0eu0XLgbhD--O3|26fi+uMobOrW@X5Ok=JZQBViD|V4eP|ah`%W(Ov z+s8b2`T$j@aK&1yvTLv*xueCFP@mmTEBg(Xt5}MC3?f!SAVBr-a(sbpi-*YN*Mqg; zj)j*O%7T|9hO2%f=>f_Dww22=4KML^h!!QMG z2lcM8+hIdBRCr9d-v#*Y;xGO~Q`4VT*U<~G!9B|{%M zHxbAkd)w~gb|+YC)U5;$;&BgzB_W|uO@wt%eD~`G1|a}xQb>AOy;zcIQ#*@CZ;}0b zUFWMUeG(K4^BP6tNK_>;F(aO-Yt-dX&A8b&uw@<-uCY>LxBd=2;BESEqJAXoH|8ZE z$$PuUah2rAfep>ei{(KMIZA3k8eW~lAXy*4#1RO42%A=6na z=<=HuW}0g?c-}SP3A5z=I}~=qpVo-sXjEnQtmc~a?8#RXSAE~F@2hEtzb~5@$vI~H zjBQ~bbv7D|h5BO3S#K2(TfCc5z<50Z`(4Jn2*tOx7&~ktvqDjzX+z+LTg;ScTE?ae z8x3YmNt(W7&_P%6&IUPQhtbaID2K#rzZsijXMk;oNmP%U{2EMAZi1Zdmq)rfoV_`m zRBQNcAI30VkyxKEm|U{*Pe!xk)}WTP_-ub2n7(mbBU!cXrt22|v%JO#1|$(bT*;R( z)LTqnV_rfaQS<2Xj9KmUdkRdy>#>s}362+IJdfaRntb=4GvY5y+swf9uO89tB+rg< zL+DQ{{fpwnTb~C5^$sU(uYG}N{s{atNGxK1U@jgTP2Ej!x$jwnG(9*$U}?xxe3+%K z`g=`zAdbrLQI>=(0qwTZE97_FL_3%r9AF!xozaH{>r)I9fr(Sk) zaSwc@BFX(pC7|a3Jb3dXqhK8Kwj|T(fD&{v-1RHXWoVA{e2JDhpr9Jf03E7NX%H*c zG^iCWmt+_|yzcK%6=kiPdL#$?^P( zQR>o^-aBE(8ISZIoLE zTvQ-bF{w(uC8j=1#L-vfT0bszzlY_?7liNt{+_GJr1)3zQOq(bsL2B$bWCBL1)sU8 zJp`*tqtd9@&SCtPuQQYI?HsLHcr`sV9P~e6BSw+C>24YWeP%5yAILB{4xy7Jrnd$; zJI7WH=sAOKv}f0cB0|Cy-Wrwf(#%kc3R~_jNfr8-@$e^~d(>tIsd)g~$udEBBeZ37 zQxM*mR-N;OiPWS-yK;=pdQ*V1VDz~Yyi~O=eNf?dgq^keuJwf@U4koQ8Q${t(MPQ0sI0dqCqMyqpgj+lUD-?`ztq@R(wMXe^gi9lyLN(B| z@$|IV<5sFoG~74`dIBq6XA_NlX>MsdLxAi7r7b_3vN;+HyyiQ&AUBL<*nJ@*`vc85 z2@F$pJ>5QoWiR_MfkUHj-PDY}8uz1Oc83wW&h?~ddD9TN>XaEE(_3{>Fa1SP@|G4u z{pGx=_-XLx)ArVO!77>KC;TudFuxwGAw36CS`iA{-Hoi2DOxUZ@}Ht{>U9#Q6EqDN z?huk-(7m;Cjm}EiapSssUyIExdUifd^THwK(EF#*b~CUblDvDsr{2wqPwn12(FLOm zhS57*i3D*#U>+>!;PCn_mYS1_4%MRTX%g>PJyA%j4zbF{4zk-;!r}w8}y#zJP zImjpW@jQ}yRI&0Z^rp*w&_84&(@e^issMt=x9Ju>;rJD(hrg+n!?(sJjr0tuZ+=(O zhM$mmRBIhGP;nl9v@Qu+=hWW1_#uhhFol6?Ir8HQ0%S1Bght{O!rewz08JWaEg*mR zH*w0=BU4-Jyx)l`U2&RMwvrSt!*|ooS!vnIv8{1}2N5TZLt{D2Bn%`Cy|V=aAP~SO z_smk=i9e#vx3r;km$J+1LgoKzNfsuXab*mM{+*wg3~xuG;Nr!Uh|6US22)d{C5p4k zG!kPTO@5aGD&pOqyrKC<;bIo0fz}U3JGWZSY_y2JP`o)cyf7J?v7ZKK+4*{bL&5#RK98*~lh14oO~}WtQ8HZD3s;>ec{UwmhTCG~hdHS+x@!H)t(azR z6~V+xo_N}Cqt*K+>DQrce^*eE3J!4`aJ5!<3HuIT}-;Qv_Fk}pm6Mc5WY@s zYffPmkC)vCk>9GP8&}kst~@A_-C(|5%^dkkw0Ehv`=$u&CH3A(!CTnE&h|dn1yum; zJLJ33F1`J2oRpsm0Oa~GS^w*rB(IY58j`Ag|No19Lp~8(@2}Oe2__usAk^O3tk|$7 zMcUC+?lu*~CWvD8cmUam3Ynfpf){ufzq~n#<q@$9k8EcP@_7^e7RASw2PRL$(rn$m!^XAnF!!E^<@ZO#zH@2~!JZU%iJ#CAnbx>JTEj4J4Cl(I7W zCoB!vi8r4ySIr6;b?Z(}XgX0&-x|v2IOg}(tqN7Ze`t9H1S^NE%2)?VT0%EUr~yCR zIC~t6XAFNcOTQQTcz-?X%+`c#rZmPb!&_e~B$*+XzU-$zIugf0g{Cd?@o%roZ(xIP z5eQA-%+NUbe?V8WRB*~>p!(IiX(O!PWOV>-bHw|vn9=foA#+Y2PMToKgSMG$`?v=& z0tsDKav>75uwCAu;C<8nqNm}HU)c0(wEHz0__qHS7!~xOy8&{Vre;?j;S&by(+H=F ziT}VjS^wdZv{Mm?$C0f6O-ym~Hue8W>{8{W{i95*AK|*O z10JlxaDx6OO0-3F7Ru-F-<;(;#Z`oVbH2u&72Q4#!taRWwiXe$l(1~2!XK|#$q$g% zE}l%rSx%8;$a8UprkJPe#1J1e7LdGLK!`ADdO_?No*yBRvpbg z`{g`ell#8$g9EzSnZ|Q3Xzn0GJFIocu_7JjC>oQm+jfk<*R@kqnw<}s^V&&gvDJ1O zJ>kX)Q)iTeCjKinpc^WCDf&{7IOjDl>M;M!IsVGxS~yEgT77@9B<|0B7Ufdd=_yhS zBjz>@XN+&6m{afz#f<>ypbYr=@0n6M#_*nN?c--`jK&yG--$rol~F~KwGL$7elQUv zefEA-os~26i(~4F^Q-W{A9;mVZLV!RxMZbixznrS{#5CA`YbO`n zq9Jaq#<~K1INM4`1dbcDJhCC|4Fv8M@yXeZel40EzDJ{{2-{5H4eaWV(p|2Nrow{J z`eW-NiwQNt2@ii>Vs$YZ|E7JfZtSY|$-tuLe+fs2_yzXar2%|ZfEiC07rrP0L%Bi7 zbEnv7+6+b{xnBzAtQ5$i!}L!L$;|CYBbYHt3^Hq>@c_MZmF+GCY|$OP>~*lz`zz7r zJ*_oOjptQwo;9gaNZ0JqTQd*kQi8B8L(G5$-pAj(qV(NiLc$F}%uSL84V>A=2f-Ff z`pqa|5S77JyT*<*jit7zLy1-n%jTY@O&cHBO>4VEwh))cr~KLwY+M# z($#HYfpuxXJH}B;bLjQ^K&lhDr^8LnnB>&2A znp-JtH21U;4{Ki+)3p6clI6K^O2~ECgDIU%d~6~33KV8+gW?>nW^A;-$@h6V3EOMR zWlR>kGI7?vL+23iYsUZ|Q9%`~RKfl=jR6B&+5feTlWAUs-;%ZjtH%8sjRj+&-w4~C zb@I-NQZUnD+~0LSO4PvHQ?=+NkpOfFG^RG-t6Tp zJY*Iz7@ye>N}VCV`r#}1@eWrFP!k<_CZk{L5PUf163+Q{uLQ=XNGPHu1p=L>jl9GE zc)<9}IRwFUq zi}tJ{`;#KxUS!`G5e|PHQrVW-zoovT)mel(U0y7e`+K<85AhSZrH_j_rM$F8tV4^Z zhStH}iBe`zb00@amaa=97zWWF%ik8kQ!a~yd;2E`5Qo6_D4aM%&Y1|0&!}x=oX6b0 z>=s&;Z3PbCxND7(HZPGyIyG#Nr{OJ=rXr04`!E%anSc2g0x3L$kgRtEd>?7m^JQPXqb4`==DlTqRuX5vqfYe4BCp)yi;uy(QTMtEoPW@p%|t zNk%(tV%jf|E{#3PJu}Sz0o>(DwtaGg=t-DHxPi zB?{!MaNn0RFo(gM-|m{R0&Eyu-bx54o>=zX%Zdbo9rf=-SO$CxAv0U9zuT{J&2-rmc`VW#7t>)b@Mz!HA zGG^JAapYxwfKBKM;6J5@qp#zlsEney{wv0*+QiHSsQ<{k#_c9^&bk-DbCTzD!Z}}8yrWv5~*m!WO^5Jm_y<=UQQ_LR@RFH_v1UDu0 zAM+kRVScyFTd%^;=4VmWBc!`KC9v14zODHpz=tgRvC^H5R_0(dM5sjhoYu#jtBeG=Y=`MM7i}KwCUhz9y3K=y_qdt?;6|WzTLG2;Mskihh5BX z0?T&A+uC^#ghP&UCWMRV<395`DVodZ^DBWtPZka0`S5`6nbgX{#J9_!F8e=LfF#IJ zp-=bDHu7EqDqN~a2zoT^P!8=~jfOSw#UL_U4tf*mgfw15!&ecv&%g@qG%c~ElrWt* zGS*w~n^yW=&^@#rkS4yJo9aq@vt+hfhRL2c0peL5OQtVH{M+snp216Fh>XIvWp2!ggyfiHL7D0VQ$@ z@2aS3)T=CA!Oq8y+E{@piyB@R0x3@`n|1}4lk z3-k~3aQ&1wlW=y>*1>5(dSD~iqo?Iszp+78CzFEd=5Xbi+wohRO4`)8Ep@asH^x_ZDp+gQ5DG;Aoj9Oo}U z3L0{RdkgEIzBDMyKVRvlv%Q*vOL0Bh%Y`lJ!2epW!&sbcLMo8ds2>IGlz8`2YwixB z1MATiWeS*aOw4*L*WkSNWBjazF4wX#SaQB}-?Abd(F+zVb6b9dHC$5XZ_URX2llt< zb6Pn>-kftL zYWAJorBg2_8v)?tXqxPWancn4|LH8Ikx#rS>WCj}`?^xrd1eko>j;Q$GCC{r=&J7> zL>tj!NS9?&m?Y?A)KDDi+}fZx(}K%jupzJxASLt`U-%4s&fTMfP0qYB(jut1EkPn>G z`x99i4X-%)I8oPav=zf<7*6d=XAPA@17-Ke!imd@CLxlpaUB0iyVK=#QO#m`lg7$v5MF{u)jyQk z_8r6CgxeyPa?95{P~(fSi|+10YoKcS(&O~@J+LW(ME`QCDY@p)piwmrpFqg z)LC|UqG&Wt3M^7u?ksVD>u0HMq)8%%#Cxu)GH*}vzE^MJOs?~KNvQ#nGq>)(S~13u99yS*Ekm#(AqJo&8zHx=kv$3)XBZ2F0EGIr!F ztAK^?>}v?&&Vn{YVDdPhn@wmLbHZa{su~PjjIYKDf~nB&zF1^R{*_!6a0}_9?v8Lj z902IBc&-+7wbToQZeCL*oIIN94kBq;=GWk@gL!)QYXGg0P}`%Q>L1WvzHZpuUAhv| z5hVm4q#JC4=1OT6uo^hk@X~+|OCqGHT zuAkFd-0DC{U z?YS9?rhfya8L9*&^4&nrK~ym)_KQ*6+9lM-P^T{*5EJ^r;kHY$Y`u~XfevR`r`Cib zkI{&c;lX#Wx#NG|69_+FrmvZ73y2BDx*qX_L3Y=K z{B3v7Z1BZLiE4da+M%f-!oD8l!7IE9U0+t!>wfJ(EkBR zG*u^IiZ|9!&6$TbIRpYbl)cGNXa&e{UZ>+Sz@z@%emhkYdlM%FHL$?vS@zSWL^fps z?{|4QYaj;Kd6|q&Fuql^;v;_h8G9A{VIg#2&-X%j8YvTMy$_`3K^Q*3GP*ca>2))? z{d0F#p7=AN%L(0*v^Huilcn>Pjv?RmV|9o-);6&_Xmv?_H6v=gXkJR~XjXaFwNF8KQ|-*o)<-E$ZZ%W3nTwv$q1ve3ZuYllpH!@kBVp^ z_0$^W;f{qp`rJr+tn7y4J1#F0w0b>--e3pk&2Q&=Fa1O@K$RG(Gl8(4Dl>CrA8#SDdc# zr$bREA)%B^xt?CK34Q+nr0lFB8NrdNbAS(pH5cYXriazz2T=&?&>MfaybX>5g`3RP zIL;egtrb@N`jtcq^nZXgQhu^FRPxz_hL3(?fc>XM=@@*g zzC=H4SWCxHNAAgkGx0mYo!ag@rcA_C9)f!3a4CJgCUO=+iqj`KYtyoZ*BlTvyqE(2 zEW%!Vg1rbKr~fQGPP7N(9{OGj9yDm%1ig~3L;fY- z3!`zoVgoU)xh^1z_&tY`u0&n+Fb+1-J%Ct86WjhZK+zUj^>h9>k-Qdw9&c%v;VI4A zUvL3Oq;2sXmi&DPtv6eJ0(2Y?I#|FQL~9T>h8dYA_|xnO&$@Q2VJK58mA2~^_kYcSCwmumdqc4WB7F~C^EF@YT5K2UqU6Jo3+aZhGI!~DdbTO1vn^LVFs*k{;dttp7{4~MHxhpr{%eSU+L)YOCV_7d@Bty? ziIj*Z0q87q|rGTmuU(tiyCLVsMB6ZlHQlaX*NXh19+b2!W@J|cxR zAYY|IPF;!MLLW+Cf2ZW;spA2M4TY{leOX+w%kVeIb_5o$#}WBePpFUv?gt`eRMqkM&|@rY7Jj8R_(*Fd@0M0mBlg`Hp=H0rakdd9VmX;*A-5Xu=wSRL#H!WV(SKJm2M$Sq_ zm&E%r8jIA3R8Rk3ft?4cFzoirn{%&Vy?6CHfCj~#U7q}kin8;BJ2cIZ!`M|x8V2B*Rl`4uPVbQaPX%af}v)m zBB3S2U2A8rn&#l|$iwXJEwzBfVWAW(yMULQRhj^-Hyv(4Y)OJ!w9=LAn0CqmxFzNX zzW-*l#9F3#mM>27g~BuwmSl}Pt6}9koD2gd8?`0#D|C^_v7|r;H>q8FK6Oh-9>;ev^6yZxhZL* z6D?z~$46upg7zU!trSHe*mf#|4GEKLt@1RFU9b(hq&W!11o!tc&)lqE`(L)>lt=aT zmtfO;(FM&3VyKeZlH(zYE+U&gbtfYrxr`2vTAx8~r{LHWadJyw!Px~MTiHqarn^6l zTWtNyvPugf-dLlckJXEcqvp*E0{eKp%ZKSfc0n1AMGeSiR>G}$)Vkd*?Ya`B!l-N~9*iErua(e8&n%uGlZBfoROvIPgq-Z@?|SQ*kLQUo)8-P`gU8 zX&`^1hj;h>e1>ZH`ldgMkQ2ewy)=Hj`v*pmo;@Y=ljeSK$ka?7XZqY}Vw-h_juud@Fd_~%Z% zZh9(_Bi`5zYCQO}U=};e%qhq@9!CNF3T#G;UG}l~jT}BG*akNhSoBkva=vf7@m*2z z@n?Dx>2z!s$E4Acm&f{~&FwQ=stcZ+KlX|j8jZ4f6ZVxgI}$m+gu-oii2UJSuqRLd zs(A0-3BSX*t~vfrB9m>DD~&v_0$W7-5Viy_Yl-J!Wb!xfYPZ`*m`{%k)6U%DrF3nU z&y%=~rucyG`3@eg{9402$pKh^{4%}3aPSV)6N(lzeYVRmT`$gR;sX#-_Nd)zM9Q~sDysPzlm-@I|1~BH1Xct*niZFk}LSha`>`+OB1SBFUb{mjM zs7172Y)@Pd$t>Isr6Nfv%l=^^{?K6O9~uEP9Gf_e4O~Fhzb%uPBGkyDKn>a_XD$OC zwD)E6nqx``Tk4obtJ*&wxQ+>R-6N(QdLvo8P41SgM6D4@S^?Tg%We;?D~ZhGVB=#& z=@(B=Y-DVCjGu*}j7_$&#F}}F@SJE_;X|ucjfIO=B?!6SCne}~y`$7f$wDk9hi2@U z+Ey=Xc9B5L7qc)-FOnL6S{b0V`zU^Idf6SYkAE7i1wKfeR*Xj!*05Vw zV=FslF3$B+GMF?(^{$AF+ZN5lWodpxBUhWYJXO;#v%7_eP~m@@g2f|;^Zb4>CoYPY zyPq>IJ4a}L11|P!1)nELEz;BNrSOhiv^qLEcNt zn!kjta-%bDErT$XxrRIgm!D^HN5|D}|qt=a4*X z!$51gie=Yq72gzSeEBv)XT5R5h}=!cVPAccFIYDoKWf-}=KSk^*lW{f4150tTlF$y z(I4UljYyN>L8x9`6%JJ{)$#p@4p+mgM#1tm)H7Spnb$c^d(T^KyF8Kz%MENLi*1GL zNny&%+u27NG0!xI#`_kqex4q-aQ~8@Sia!Mh8?rMO-#rBXG-$xWdK}3k~~KT5_@LB zmhW`(kKE;^1u=YY+oi-2hZ$yEqerTaRhy2j3;VF%!TsVWuK=RLY5cWP&b*5Sw9&;H z=ZE9aLBXokTV)RR)EsQ+reN$S5E+-}$W!GjTNho8}rge9a4z z)h!|8NjxJ_Ona8AH>3MFEZ{BYbUfi21|J#dzXWlOdY5 z?g#I=xrc>dmNnChPe-V4lgx9VWXETUG?7LHWD_l_Uk=U7Xy{ZmlfAJfj(HMQ)d4Tu zi=!OuU-a8bxJ+A2%YLe!D*Wbtt%Cf}aeibO z?ypq_c$S{wAQA^hO6$skm22MqOmXDkAIdM;aR)u>%US_ zoVLqRd8_f_tPX%Q_OBu0tTWf6ms!O@CAWCU_4R4@`pVxWGPN4Lxc?o)?s!2$<|S1J zYn(js4cw@oes2wymwlE6X55rwSs)o4^E&v6gmI@W4H^3Edwzk2n`jJMZ+Rt&%H^DI zQXUbr*JY=8_$8q=Mi)-jmp!KQk|DHE!n~x$*@@eCUh+Km+9a0SL?n{Lx)FxKp%k0h6Z2#oQ8p zQn;5p+>^IPGUWzIFRbXgDM&{5MedWdZ}1F6C8`?LoeJ7FLr1!L*6KaLH)7WBbWhdX zA2LC=09@L7s|k65kw57I(yCMU!f`3Z{O0Vx{^`#>UxguZx5y375oIG(b%^1}e=#OZ4%3oemoc6yv04Qvkk=3->0 zvz-}BNuS#`o*EMLX8E1EE1d&V|^0 zaoG*OHU{+`MyZXa!*arVXD}HQ)sIErSQfq3vTy0wIS(K7UZ6zvYoskXdAc|$9Qj*B zu9gnEL0k^km{D$s;7)iTtRmf=N#)NP+04e2vESobyP>|_n6BbvxJ~I+ko$NRYvLIx zv?F!nE9_&hdDDcsC;`x)Y%MAn(U=lYN~1E%s78Ouh=xFaO2udvf_8~vrPRP(E@FdP zltfG(?(5$;RO^m7nf6Q7mg`s#kjAGa8k?kZ(VbfxSb(Xems}UpOK3;u|1>-DZq-ct z$z}l{(i0ncxe$5@phlahD@lyS-N|>4dxHrB-%H}lg3UUl*F~gByf?IIm@w>$sTGiu ze-fc(?%zxOFJE^L6=MgJ!HxaM4XT(YwFxoqCq8jPh@DGXr}+!o28XsU#@F>mP{$K& zX5GYie7a>!p|M(60R0aLPWScpFK-xpyG!2cBwFvRZ6q>2vyxAAJHxreYvRmDfNsiK zS6en#lgAATF7<)U{I3&X4TJZ+r3K0X=M6M|Hz%UgFv;Ly!^X=;iM}ZVsrPwZI!cpu ztdYmrrYA+8kBA6GlWh=}7wj!UNb)aYUIMpisG_+05E*f)vbWJ^yWsVYg?LmiX0K;M zq5J_lHx;OS*uFQHv1X0vLmFu^PwD#rgHrKn$VVPxcm%6!vY}Be_M9}{lUxj-&7 z~S5vyiP5^jf0KApBs#sJeXNX#`;EBOu)mn zz|9c+C-_H}k`+O!{vYt-mGU=KjUP|GCj$3r@S=271-nGK|8iKnZIgP#iG4QntAuLSFtpEly9%9ZEVRF_`i}B#99?C$k_yG zfw$m^r{lA>oQ|CJ zrUTqPGFzdzL`^FUNK@=`>5?4gFe9$-yRKd?^xFd?g2wOjYS<1@-|yf8@b^`Lo{ zFxO8D9a+8=h~^|FQVfH~b&}E@RtlKF?Ewq;1(d63iN&<&BBpU9cAI4&AT}{SBv}G# zc4kvrjzBk-4Ww6Ws}BnCyJ9k~pNB;-6!1FdkU?@U7We;985Nd<=uLNSAo_u}#kQC< z^@4qhMzLOJ)?y|bf>ZXvAl0eZjelot7ei@P>lChD|TB?e4OBU}k&*4QL*;Bj7kR{GXZISzc5;udh$A>p1l zIc7(G)rT-6VVS470=WX-xhTUP+L3$#s4CScx;%Zy>!fTz_WTqmz zbZLY&V*hNgV0=QU%g$3cL&5@mEe`hvq4F=vVf2g{e{(G&Pvbw-v`M#C34~3!Jz`}E zSiar_WYQKtN+)a-92P+Zay_Ym@EQWSN0 ztucsO+U{)i-*L(4KW_Ffo^PP42lGhXs_hYA2)WS45( zbeN%=_xjy)NW8;YT_6@}!QqHyV0!JV3+{Yk(4IO%<(sm*x0fM@5TbXtc#pc5yj=e@ zv)}gB=i2K*evibtcB-NpJd|DVjP_K))RhB+{zDzJ+h}Xa-KV%XXl~9Us7mrv-|d&j5DPC^s_9GTZI!E zcv;KQ{R=Aq(%**@-{gmHge_^Dxy#q=Z>0W%Oo#`d*fy_wa(e^X{0Ws%gRR$#Vf>RB z=xpdhc=;Sgt6A-uOl9|aIDTJ+;8V@&Bc{bJFF zUr6BwpD*6L`NhauB0jFz?JCwMDyOzy4qXGcJU93rLeG^{I1&rS)?rJ9qnelcf|#U7+35ai1PiwTE_Q zwVd4Z^AvkAMv&2X;4;%-RaBwgJ2^`Y&#g1W0u6sSL?YY9Z;WTGcc^#WahewN{4&}+ z;TsZRG({*>I)Se#E|>3Xf89wyJr=>!v2$IxagFCmGvk`3Gp73_9(VG@W%Z<)fdN}j z2u6e|_`t&Ewbqx$O%}&{y z2S&^CVIl6jrT9WiXvpFPlfO~L4R~0l(mZKz)XAySWPo;ugw-!gimcjYr&d%dL!?Pc z%exqgH|+G1T}{s2>LmW`Pru9v2rIVmSSxY8hM0h7>pEbMagjlgOXI`JFRNK_nRntS z|Cx^UVSWWs^Ek-BK@LD5}~aP5L%MY}%Z_rSHI3TMaNOpEFGC8XLm8CdVfdbG*~)~N=pAqw{N zF+j_qkhh9a@J%5C!ar16THYL=$-1bODraeocyGux^$tTwRb39#E2+@9K5nOPp;ra@2;&yCe&k;C=V zYcNMpP?v|M^$@Y2UO}tQ+hg|f;Nw^H!S6%$Ry~)0ZgxXfL}_osfFj-dsy`3MqgJPA zC503l@w~8P7N|#$N!)&WQ^k7Mcq=^f2NO3kr&%9g3B|#hU^61{SOJr^5xL9net~E- z6F{C9??J(*zb8qI%;c+1VFPAZ|M`>d5ue9J+y&e@t`;_zYL3S1A1W;vQKiHko`=z{)zweTjoLhGwVA0hb4xtFm#6E^o@-pTyy>L zxd!|9M?mT3yO!Wc#5^!)DE_+_CD`D1xNHEM`56T)U*7& z$%2{PH)&-(eOs|dq`PBZ>92<8IU*gf$0Hx1waUOGIb#OE7*{48yEb;m8cDOJrg<2I|^)-)4qOOZQ&nJ!O0p zC7tC->*DrLksmzPsh$}xOcc`_-e{q=FbQX-XzXmIe|V0>55-{5=mK=kKdIE$;^ttN zeWHSw4|se!6VD)1^JiriTld{?rJkmXUyzQn=4&!vjmFs#W1%)5Q+0=&(?sIhS3S@$o5(?C`L!_U2>z?ASLbu^VgC*lO@d7 zu1{nT+j512KLx?s{e4$=VA>Zu3t9(v)@}LXTU#1cZXbQqSb7m@U!2cxr4qvZwfD#q z?I75uo)zJfutTLB6}mZa*8s~Q9=*+Ipm=3z&6QGvfY@8Se;0IkPzzS=V{T`yy~WmE zY#|*cdmid0F1WH|Dy}?9^Q5c0@V@65Z%XjAY2x5no)B}KrvKzl$WN-zz~}RDowx2| zd?@1+@pS>ogfzmfEh#vi^7Ev9T-z7zX3lseZuYfNalS?#0v!G$-_(S`UcY0>r6o6{ zN^6x&HoQgdNhft1>wPtzL^N0H=$b*a`^H( z7Vli|lGYLn-ic}6>~QI&q`+Te9+zuZriIYKZ?}ifcwrj)oyWt+!4(xHWsCZF`}<|$ zcXH4U_Ehz2^EFs{%_^@@1P?D)5DcrGyq8^{7*>~S2@iBNnRWs(8yfBs6_|>VZwBKI zykPwQfY1iZqf;_47wPs%h(4%|e{wL}_Fnyom=?E+PEB3Htfvv9VjfM2OR2eNOO)_s z>DMdsM|0chRNqXnNXYKgYMzOS_(S)h_y_8LvZLu}XSv2rFtx7McKd}aPTKpiWTT++= zQ$df}lhBV=@-`F;bn%zmk)Y!WTU%ajAo5m3CpJd8d*}iWcHQY%u9)-oBRz(=n{H>V z#hW5Hzbb~!N;Tkv?Ump@hxGkdlC^``LdH<3*a_yI(&;_x8qnF()u1(U#hkw zrY1Q)IW-S{4-oG|uV6NTavQ7XYZw4wo83Hy0V)sE)hC^vd=oX$+O2mcny`8Ghc?Hl zV=Tm!OJ?!jP>E>+eLd8Fvtw6Yf(WM}J%Rib!ds6juiEyx){X+I|JC%_rZALJZLA>o z=X- zfc`xV|JgLI^s1qu#W$$D@s69bC0s939ms)32c%a|!rQc<7+GQKtUF z@N@@l@qM1OLzN53fja)$EvT7x7Y%>6RY>U8}ol$^I(pAfdFd+Z}4RPlM5x_~Z=TA}PjDpe*9*4#46KOFsmr-NiP?sC8ORW}R%hMO$4S0p|iPsAlJ__AJ=CW(zm)gPto!2Jf>+75d6vLFm^a z$BrXKbbw(xLk?WcU6V#+_E|y-{^;GgHWQd*O41>28`G z+3<4~q>GC`uwwiA5F(ijI%~^dF4zYQPUV)->3QSzo>k5Gd;XyQBFM8-=9AaQM$Jan4l{U7(+Pj3h}mzY zn2fnyEwo7l%`|41D#`|l-={pbB(tX90hoJ&wKrR!h!4t^k>Ho!R9~;0VWZ*&B z`2=%IWByw99cAk=C+eC^{^-PYmBp?zMCr`@-T)>Q6X698xvpD6(Uva5%Z$I_Ej(nT z@5cT4kq#aCch&3B`d_c8m&(U#`0vII=E)YSDp{Fqk5?+sP&xlvvPCcJge?l7rm@b|e6Mo(@#fk+X^HDW-hD|jn#SoOI@3;j)% zE`Rk~*_|Q(J)UFVNWb`s`;~LhOYA?q?iBy9K^-|;!cZ?zTyPqEN?9<^tn_{5d;>WCK?xFsWoE;8c zIWsF>OFI?{9GX7}tepk)WO0LIxy<$=Vo00`29zsm9i;|918=x#%?VK8BYxAD2twj% zr7K4?8EuV3ucblYlkSp0w^(0EAR9THvB|^FK0RlfWQQ z8~*Z-EUQZui5&vb2e@xGV@bP4(iK|kPKbwj^tYS5nCR~Qyt>pT;y+E2gFu!ksej#M zi%RdKL0xcc+}|wdjJtb-G;#}sWf9UKPRB<*toEQi@o+vQHd!5V$^R+$$qp5#pfP;i z-wV3l*~+dz@r^p#rOei&Ed4#^3;Vvvdo$f)zEDqEDj2tf;KFgBBgN<3q9FwAOo6WF zqNy#8A7{)DAjj3K^kI%mADFj8WBkE`P2isR-XeTc+ywG%DH88(eY=EO`8f`7+z?eG zFx2dSO8QMmAb3y0o>k@jJnirQCtP@ZrOC2Nrw&&36OA~mJ3ZWZE1rJHR&PkN;@7%E zJW+v^9Cz=iHF`~bHU6GG&5z(MXG1fgDX3a^2h`wNbLq98^}NGjGjmQ;s}I0WW>8!f zo5=Z5O4=A#?n5kpqo<(2XV}-M&+R(Jr1;Ru+e|vyUSm^;7ydTA-t)sa0LQG~0`+pz zcB)&#W(88fB`yoP;5b}Eor;FX(%@Hr9FOWUEp^&GXRx9FpA8N-;RZMCVb!GCd4sXP zm+Dv>W>os`>!>&&M@DbWHAo`A)ebK)^(c-1ccnB6gpARa%}lX!9pr>gPr9qUN-}2v zhMCN&IPiNisNmEGB5K+@P9t;PF;Qmzagm&^{S8|j`icu~Eu6})kcthCF@bl8CC9x7 zMW0@B8)ss`p$?Xssc=3?J*&~Cb-Wiz$lNVWk0XD=7op)+5)ocRr&cZ+c6eO;qV#so zSW7Qz8Vwr>%T-!_iW!hD@^2YBWFfVWP%lp95cL z_1z%wWG{{P-Tze;S7>tObCN-rXWf#RzRv>X@;A*gY_#%|Rc2O^#5H~rI>gXux?g>s z;La90yNjw`SxQ!4SwBwzb57Q=qgqrR88ZeI-YSCKku%NU_c7!2uRQ73QrBIf8-IA@ z@pF-M3VL1#hFQkY$L_oH9dwrgPG|e$W|q+my(XP`y8UXH*wY$c*~Y{~5}jMZ^vp#4 z4TTc^I6{N^n{J^+x3{iKsIRacNLpo;kQwQ#y?m-A`zxoU7WzE45c?z@yWvi}=$<4Y zE4(llEs`4OA#J)B*{hTxP)CyY04(7k&N@Cw23m$xis_d?P4uD@gRIKs_KqTHaZ!!I z5o47@D{|T7<|WE*zN?erop6343@j@2HZFxy1WC!B{{y1$m~l0a)ZjckOOHIpHJR$} z99jrVzoW7mSwhN=?L4Wl$b>}$zgPw=3Uk=os z79t*p)gxp#Gr-6v3%dmT*)MTyc69%H`>h~wb(0gVtM}|yj{TV6KyZSc+@|h-K%8_* z9;RfxUNRseP6}7nT4lX>h1C7phCO=tcwo`|QK<1CHsA-3`?{n~(FonEbMU3eD8dSy zGD^#sw*vJ*^#x)b$OZLEIQDY^blTKBwn6hAd1t05DPoK7q~_Xj=W`Py&_|)-U5lE> zr=!#M#?wlIrxivC0e+vn30lyfUdAJW2L5^OLtcIQS$sF+4X8G?|8&4yM%ua1rrMCqH*>_t(|1(6M+53Jh{K4Tx&QmJ`XJ<}lQxckpz1+Y!XD&{2 z-85rVuQV=ESLKiD(yy#l5qSJ<+L#0pWE}!*s(K^ zRA!U~&tKKo{u)S$tQ!#!Z{zv9qbJQW&$nL8nb+7xgD`dJAM2-#7M$&cugy_r>aP#t zfxec~vhls-4t(kqJs;PrQgfID`qxQCabM( zai=rI&2Hpku`u-liBes@)0 z>8$}Kg!FU?K!W`n8i+wi;Fgu35PsAJlt7n3E*UQCXz^UvbF1NkcTF<}uZ3p*n#Zg6 zHv=n0d823N2HEQ*Hrb@@x~=BZNfDewG{p}hRF~@q6=AD#9_G_+&dl&jgd)S!4{R;V zWl^Kvo~K6kHZ49?MM#deb+1mMNTyxC^0WX7Nei<&uqIpd0-UwGfgBPj_+A{8S6MJU z1>45j2&lXc5)aVw^J2Q8pa|Nnf{^?rivQ*H5{oV07m?kwvSw4#r}S)O7TWsQfQJ6M zwd_G%cdQ+%g$kkVI8rvq*azu9ECO6j4_6m@F0YBaz3h=!)bZGuE@1u-!0~UVI_>+2 zenZn8g?U3j4h4zlmqYP-!h~(_vj=L=os|J40H^E zg_Eosr?v|vy$9k}cxP2sR*m-%_0O;ue=(qbG*FESe9LqW)b;g-+n>G<@HTCge$a`S z4XavHGJo)AqP$9Rp}&}cDO-slQ{$-bgwlSC^7ueF30k`$^tHwUmg+-l4QkAWXGOV~ zImQDI?+}NQ>qH};g@cG7Y2tYiaJ)lJez_&zzFTX-ckTUmH!>V(uwP6&lP~(0GezpP zv1tJBRW#);33;Zn$=)t9XDKSQ#Uh|I%K8Mtnmc#Ot2S6j*}4!vsngZbgf^zh#>4*_ z>_GE^7mZz?IG`sHWlTrgYD(k&W-tNFX7#XC$Zb=I#U$ZvcWhcrk2Cnec>Yc&;cYt- zNNL{4cvffxq)~uif2RJrn1Qz8@KRWDukIS_+yU!7NwF!XDt4w^ur6=ZsEksA_%zSNRfKc^5K#%tDiLU# zN3ouo`OxZfvrc%7yEog8L**08A_8zJ*Wq)MS(oQUZpAUkzUy_H8^NsYi zG$*fAUCkE<>HCZb*!A%lf949!d5z~rm%;tJ1_E%`XQUgRFQ6gDBfGUqgY&if3Qe2; z?pm`(hfZE>d(d$Wh34OHnJUF4ykX6FMt27=<7PV=dVkV-ssWDTwIeFrSi z;>FPrywPDn;SMg+EG3xdDdlN^dM;`NZ#R7+gH;P7tD}dsD@{u*NB(U!^1}^}?eKGm zzeENQ4lzH9)_n<0se9{p_dSAapaI|JBsn_u(&C3el^1KftVKOKbv8CmN<7EuBt+AR zJ(R--1)~zQ$v}D&57~BPASH(HLUYroqVf1Mo?^HhZXl*c-X2Kw-BDnq{1j6eS9J>w4VA<=8YWfowF!~+F6A4VPAw*I~t;Zk7Hlp z`51G=9oHiwT^!x5zL65d;_n{xXP#W9eg6|j^Q|lxCCQ9^9mGI62j(p=Yw69}VLZ=z zkFAYMqX`_{)Hjx`@uZjXM78uR-eLddyu7mKAHzO{C@hYDoi}R_;yr5gGCs7% zH}oIpUOq<1wp~*nRB61T;2fS$Gy*SWMExH_=i<-w_s8+iuD01`bDjG(*IZ}rrEGJ} zt&v1YGuI>yT`1LN!?1+JTndS%bU|uLeTTWWN~NM!UnG@ENu`T#zn_2MbI#*)&ilNd z@8_#K-|*fpz3Oj^dRaxr{%dOW<~Tobj&+V4Q*OdI>*hh!8M=gOAf$1f{-Qx#Z!z=R zu~D4=cg5Myl&6j};DHUq0oP(d^{++Hle8yhRsjT$qdrW zQGdK*9noQfY?avx^rM1}XoM*VdWD%0)1_A*@51_3Anm8DvKC}sTknC5UKCsy>oTNb zE9HyPnT96xfSC}f%DMG}jeg}#&W*Mn&UmU;+Nq~*RpEpXDD2SAuSJ%^4O2-e4(YRy z;XL?%RRkPd09UVctOpbFg=gaP^D+r9)_Ij3W+MR8Poc72qj{~}ObgHtqU^txIGp=u zVZ0sO9M)C(L90k%;?Ibuo+#;I9oKP^h_GmdIs;(y-i9s9b|YF(1Tj|IUlZBlr3wdC-<`yJ>tTTQMjY1X?NFwb8KqgHUI^rPalQWAY^}5YA$R-wzDEx@;7#xk zj&WMcYl745t#&d|{WsXG8wA|0C0tUq6vUhyfz9Qdz`3~EGj1T%GRaNXKBeg0JJs5F z`!dPCalE(1z3?J4R~NV3?kf1Uhsi$@ZmZIXf=@c!E>mRf71HppC|!Idnd2`Q_xQW~lyfGf6&Lo8q*nes5nUkrS$tz=mr3kBf1b2>Ao0A-lwV%C ztzxF(G876H@e1#JN9zwsC^@8=REvLJ(qXw^%6GG04goh1(AEa|Cd>2z)f`4_j?6c3 zGfy@Tg1cTOQ}AbqdS6&-3iRMrb4l2TH{Qvwt6!quic@wh6L@7sXLtJVRIY9`=R_Nb zinEv;_0w;17xTnk5`=*OP@WY~#4qI4D+Z$n9!2KwP|Fz3JAAYO1OAVu%y&(H?pD1o zO2oP9p6At)BpF>igsZoZq`pv6h~QAH2)dg7+X@?50couyI{`%FjI)-8XJ#h3Vx*JF z^CJROL4t)cfe3jcmWx>`Ur5+tcivZbE!rS8b@*4UaGh3^9u5s z(a!(CgqOsa@m*2hBJ(~v6I|4AO&}#}Cn8Hlbxz;ndBX4GDY)J(k;1!(J+uN6X0!C} z>d9K5(W!W_iNgBoh;-qs)(DhR?^O8f@^Mb`gc#Q|DuixT!ekbzVqRS*qyjSlO`0(- zO%fAHO;z5n#R%kgEJocD@$N%(-;oP*=VZB_dSIjyZ*j~&EnPw58WG*-cM^(iFGd0{!8G+w!kgD=vj8%wj~Nozr-zGYD5h5mBB)S@#t~V5*FZ8PAzI zE!6YGs~A|2p`~F<(E+Y5OidVkVwMmKEwtFaM6Dkue*mUzXlP|v4XcWvU21v-hXUGv z5}gwcq+2>ouRf5&ct?6=KFUoTJHqRqMO$J!=hd4B4PTiz*gAwp%TNe+p%wSRF)27U zu3h!;_Waay-lpo{_1VQ_%LNp??MYff6-D#oZ=tMU39Sc>)cBgX-C76f*E0k1jvh;M zWZ_=qUh-=&ely2F;WzzC4GEqSQq&1TPm2-gqH?1)G(klxN1WS>WIT&Pz#yqvQyei!GP6%AgV+0u_CZL=FB#km;{B}n+M zSh9Z>R0(qlWJhzEpx7R#$2;1Xc%ON-WWV7|quXkRt^WOylzU;~l^8Hb20ndegeJ#+{%ZqrFb+)Ng?osU2Gh zyd>%5QFOwI@90ifYpKix#HlZd+Xqp>slunDL)Z7`J$%clNS^8OV)K?9)ep`9!*`|x zh=mL6=XkWLoHVv6f@HvP#SsUR8NT{qJ#i|yQ}$=$j>Qj9VV$TgqKt=n4*qk?;%k1; zu*g_x1I+^e5dDNMy0Njw@IP;;mX-1D0HF2No6kq8xw^QRV&L295s#sR9Ye&9Mw(f!+DL z;Wy_L^y3BviuTy1qW8PQ?c!gRwDV`oE+(+97Eh~UAn5dx!MgtV@0Rwn0+;7t^^MI^ zrp+^7?Q9VDbT@sZXXNORbf3=p!Ki(Wz(0k1zzX#pfASLlksz<_-3&VGFMn|AjER$Q zB^Y29@Yhm*I*TVej*{ZJnxppIqmLTJ zWeUB3?85jgZqs(*t|UrZ0$U$iDlmQn(^gXeN+OZg*!U*UBhJ+L|(*G!V~`D zp6D)FGPR0$g%nG8OcPk^2o0{{Ox3zqn<#4d6BJu7g!}yG4YxNCiJCUHF5A|*jb(rjnW&xzmj;cZA}^NOl&mJZg&hz%vMWhVk|#`)9q|Z zEbxh%#`d8_VL}YhmmlfB$BjnnF&1a5DB;y6QvVLYDNA%>%AS?9nCBk{l)6IwZ{a4| z_L9OeZ>Uc$TR>EWoa=uugg%-)o%Y92(&@qrQdo3TLAGp^1zFnxmWX0cW+2c^jYsj>i% zuWazxew=rsCHcbmNbb+ms1vg_Iys~Jm6k=*(&~`I@pllzoy{nT;M)5dCaswk4ZbO8)|^| zI+iMnbfG&n+8mT{-KlbDJKtsa68g8tz3D8j4@mK=G-KLWD;n3YNY=CYZurq5}n}-s)%Swu-BkOese&ygh_!Y z+}x-@xzXx9 z<3LPIDPje|r>vhkf|*_)2e?$ZnX!4or#+S)yL|e1lbM#Oug)*ilvF_lIno$cH5 zL{A-caIW{>_<~;hg8#QVEOzDGligF&SzAj40Q;{`RcA)OCB}dZHvx0>1R`+kl^?9AxV3_t4wTF>0j#A#S<5TU z9f_5YxWCL(jxk@RKg_51J}$Z4(|xL5EV&(YKTg%d4RG=M4wD;x2in&aZ%+s+m0`rD z&=O^0$cCx&vkexDmhhIhe=6?MN@Eol4o7=b`H7_l(Vp+PK00FWNE2lo9YwVi=ky4g z$+pU^I~uqF#(0b#P-ZdlQG(u(smEHMg{X=iy z!GgPn>;@9e;!*%pvs1$~N>a8{jxrw*r>p*`G=I^h(tl(S>Lr9AEK??|QI#6}5$!E+jmncI0>usSMnE)2NDBM7T#-nEiwEINgQ!hkd#< zgWPS7DIdxW!?r98Idt@U_(qn4@5BlZ6n0VH?Nw~>5rM6h(xMrxY#gdwRTt@k|2Ecu zj)_?~-Dn^<*ZUP{dxdb~1uqi?el%2NKvI>vLyyiR1eGN1vW$%1_Ow}lLDP-giA2=6 zN_@F%BSq5m2f|5`&1!hNgkm6PzKVu7XGF6ED66MUbRk7J!79bq{;mKMV~8MVlMhTx zUl?E8oZN?ot138*4wfVdjCb1*hnV~!SHutCJO>fxsAgRFc97|^)86C6U#lT&s6$1^ zpO8j?UzD#cAEjT6`5O3%pQoZR?q4uc{|QuzYMD}%eSicS>BDX0pN}}gfC(GohN)L$ z$6V@Hw^98kyGA}zJId>(ORN^LeujK0pbG8^7)<)($j|AQ8~<@AA)KJE>Lp24rQWG{6VIv z-(p-M8V2G|rz3S!oZ16mZuAZ&B84W@fm1}>nFbxgG?>2Yq1&nsmKUdI9Qv**xdxvP=haG7zbNif{>MPAMjgli$lcjlyk>#6-+#%)Ov!q;4%ZC20yFQLG1P&iWBY%SOwIJ4(jIq zbJiS!%bi3YjfHHKN$R$MH95|sv2!41&(FC~&nDdn3R|a2GJ3E7;R0pY2!o3|lx8Q; z@*QukB&&b_nRkfsn5q0h5^@Kp#`d|@H0Sg|RwR={=^2Q>@rZ?)nDtCbpvvA!ME$$unI+)j! z7z-D%LO>$fDj{$r4RY0!^RZtJ-n3Ved`5DnW%3&azQI(a2$7)=YE2yyN$ar zIzgbGORhd;=tp_3JUdX@5#46RN9h7zxh(6ELlwGW^Y0u$Ez~N?=yge5+eeAy1ap|Y z!Q>8Fwl|p}SOS}?;k$kdG<;u|XRHL=Em96x&Y)O3ydOLRdwJKn zbn0R}NDBqsB-hH_`wYAcev(V8GOS@D>LT43tOJX`ghbODT?ovz%MH-FxkJqSo(5ev zMa$rl!5OiLDj*$5)U6K&N)F`?+$@a7^> z7XBM$B=D;rO)nJC6Hvw=qD{Afwv3NF)hnRv9JmVsi`)(EHz@sgmN%WI4dHxlETe(z z;acj>CFG1;+vm9(HDN)T8x81(J=jUk5D)IZR8iq98ZrM&{w8L>BiwI3ZX^5EdC&t2 zZ(nRknY|L+JC7?}>;e(jeKCK20{md}YIBGQ%)N}B{pK!cydoy^-}kvBe~oqdxgpUl zFH*2=&5#GTSU|>xkXwtFX9#1Yz13X@=Oe!llDOy@+$j=wdLY;6Y>)^=RaHLUics|H z@z!>sPQB{110R2=(K8rbkmE-6bn~=$^XeeWc!X^g04uvo zx!S83!>N#Q>P6@dQAZ}`2kFryZu1xM-`YGqNZ6eJ>I(=5SIZF@P5Hlndh66B43WA_ zZCGiE$Z~$e${|u3m)1RWXPP#)&%aNI0dOgm>dR#Zn zqI~N8AAWD)AKfIig)Q}ebO&N|^SFx;%>_OW68haWC;VewfcaVjKWjPhnh#H6W0D9N zRW@Bu&-@_C!f%}cl20lxb(i`wQJDvvh4LeUJW_7;kE1QzKcY(Z2zkQ6s?!$fLST~_ zT1M8rNF&?@dbyR6lgm_mlo9KXmFd|{lA)~<|J}-Kmn5+A!@@DfK{Z^jn*`Z6^0W)I z=d{pU^(U?Af+)#-Zf4BKZp(GJ_x9p(6TT=D(j3R6QI*82ZC*zH^h*s=Rg-B3xRR?! ziPQb9G+F*B*tm>d-*lFBMB?YJ2GNS<^p5ziTxBAra*4D zNq8A8?z;~WGs>0DP@lFLLMu00y4T5MaV_gD*cKns2-{7l99|TF&Mj&=zFWe{)Zk_f z$7xasjy*P{u%Q|2U_By&eA(f-uSmn67g26hXGy{jbob@hv1f(CQps;eY1I39=mzq* zX5e~&4uP7mKjXVfr~0U~8%V?}HEaI-|-XAE5Z*SjTvBSYWt#K_! z^^#Qm7E)RT=m^&q1iWUp$bCmVzeb)8yxj{`$ta%Xe=1w2+rUO!23OGZnWek^vI|aC z>Bi^1WL#TX#+Fs2pP+m|6D*o-gE6vR&eHDcs+}AsYkIjB9|z7W(#mA zcapbJskB(KS)1PZ-7>!kJltKIbWLUeKO~BRtQ8b9&CQMo_3(3OuTv+b$aCW%ht7=3 z?fw-{>xTh8PlkTWTXIHSScu`M{ZJW?ss+Io$moA56`*d?yu!S$+fjBPSF3 z`??hfE3#CMVdR26lDtH;gY!f+(6FFp`zyEbF<0y2XJ_YO9`-!vwe>*+)h&rr810^Y zJQ05HB>di_WS{oxihqZ^?k{;9-N#_Kq~IXhi$KBi9CK*_f@PFOw6`-cK`$UEu+@+m z@Bw-b9lkpxnptxY#=5tFyY?{%88>ddcQYyIO)rCS9^O>Q-iv?Dw*eoW(KH^wrqaSK zn?(egv$)apU;G=5GeNG4aig=*_fd=PL5piz%Nl6S)#aEE!g1>obEfrE63MH79wAu< z?WY}coGuja+p2iC>eu!GDA6S1HR5Qn0B6ae-f6T&BL>xfsihC8hBX6!%riVze3=jf z_RfEPFk5`R^%e=79xpO;E7WB}^DVPA)*O*#TYr1T{kR#5mhSAQ>Ug7Uhi%*Pwrmq; z={p8~Ewsug_BWv$g5=OXRmX001Z1OH^KB`dz8F}wsK}^#t zC4zKsBC5)|j(#F!>RxK1gM1S%xOPMknR`sbDQ!OVI%!O_geeORC3ZOCJrO^<^8Y@A zKf$uL*mb#;!)^;lt|J91W!2$VSBdHsIMYOd{&^e}H@>FSv`y|ve=xR&?t4FIO>B*B zekTS!R0!U3IKR@DFmI1$=}y?6?pFt_W?mleou#9h`PZoc8B%CHzili z=Z1NZ5Cs0ULohLFKUOslW`R3vZPdI}&G9}?ZUEq?RdJg(jMGbNHe@LJJ!WXNSKVaDpMt5OOF54qZH?qD+4r5Ek}7yx$X*HAI=+6BOhBBhB;7&;_DXT~u_rv$^TC^|%eC@QgQY?&26qy`s zM^=T-NiB*NqNr`V$gnGITZgSsa=s>yN;@RkXzI2Z$Q!0`wU*Sp|5O2Ev0l!}$E2bI z#|l~Tf}@FW{UJ*37~z14EgNKh3;&5fZdUcWiLfBdG>F?)(Kgpy(s@$8z4l~{AE|V> zj!syh%nV9rw0i@P7X@CVB#pSwKC)LRyC3S=eL>7z z%HW-iID4|bm37rz3)|4x|3Up>QcuXH)$!fm6*Pdopr_-0@b|t|0BdZFt zN8Efld2IK83!9@fBE;?J?SzfL(vc4JlFfo=N|vEPfcF0Ys?4=-HE(V}>@U3Q-&eN1 zIy?9IDs1502-Y?w-fo9{N{iGb@w4(iwFVDyD_J2t+`EV^fj*cVAA)Db2*-BUkw8GT z#MT_)NDIuLDc?zOMH1BA@Rs^#5JrczY}cIaj|$Mm=-t5KYlb0orh*v z)tjem$9=36gqYC`9|!{+49-3yij2xMt#o8k>=ED=Hk#%l*NmS=CXLc{Y&hvKht2S? z{rm3q`I$reO^FX33y?nFD4BZP((F_0sg1_+$Wkn;Wy=O4j>fH9k3XJfh-?Smrp-jI z1gcsUd@<*+GBX<#s@jcFjQn(&F9976r+`L72B@wt;dc*n@F$ZYJ&Jy?>NmbB-m% zsST{R3$go@$zuYnBpQ5qdZ_ScMcX}E=^y^?Bo6TLPthpzpV25vnP79|JKmcZzDit9j-D!wyO$+ z-LH2LquN7MfC9|tkVf0L8k+nI-yd}68x04E+-R%KM~U`2^+tKf%6|K}VqQYKWcFg; z;_Cd>2&$yj1F@os73CgMf$Q355ov3-Kfr~~)mcu}c4}pmg4N~$!-o9$Hj#Cmpni3H z>vE#1X}UCS%_;fyyAE#vokask=(RN}tB(589WwDni&cuwMy3GZp%%Y0Rf2%{(u zyzEEam0&Mub@b3y@Pv;+aMh1N4)H0P2puJ%aakp3YP7_pSo27<_rG@LOkDah=Cz<@ zU(RK)Hmff~L&-VwFbiuJs!OL!5YwH)FjW;BI<6_I$SUj{kshNY0ZU>Q_>CrZI+wQn zkI0|hrSjg^1f+4(vJ^woQF4DMvO?kmz+?|MoHkU?G4AYP23c0FJx#B9PjZc}{U2BCoD|U7T*qy>g-Uk#%`b5&Ilk+>(ljmzF`(1E+q{;*Ukj6#fpxVyd@o8~qwogX z^r}1H`_;p3*N_l9a)eAUSWsmZD0e=B&Hiy@Lxi;1@aq8g#A%rAmf?BOh{5pDZb7Ql zX1aeNgRC7bv}&BUI{Z?$DnzZ0ta%_VfZP?K9m57n&F%XfMYnxT^|N`rtro)7*EJlN zCx|Mo_|XCr1!?;n4+I@_;pEWzfAO_fyd&XGZ#H%Bv+Eb_*+vS4yZ3J;JpUC+9_&<) zPqLA%dIW6tmYj{Qol3zE)bgIM(wDK}bHlEZvC!w-LcW0~p6)fn+S>hW4k*GBF@p|c zF|1dq!4DNvzAkTUZdFB+6MTWk>lv@_I?%VhW8{wlYlhYlQmx|)S zBQ_NtWsd7p8=>g@5fG^sxG~I$ulcR59sTja+UOIw+@=@8pgcBW)3is@mjq4!EhG8B z<{Ma_Ke@qftrh8-M35wx(Dt;U$n*FEz$jKdVqL`m^5rQ4|4q7;VUu(Iq49{I>n&zg zmM-=q5-z{89c?C9ThQKNG!0BxdGz7xwo2C;oKfzuCVFk;4l@p1CmUMgzmmvq5AXqt z*b4-dS1}LIQ2!{j2hSA4DR-nrsjnreZI#U$q3n+DNPT84%QLFdq(szr;*_;Ha)?>h z6Vw^jZR$4-&bn{1Fx)vbfVp?#^IU+>!g<@D$`aOr!e3YjRPvUOP*x~cX zN0YG|IA>=xAat+DT{P`J=40vrD&x9}+*bcr?mOq!bSOf1>=1wB`BIpS7607;eMb=1 zq>-WCT=}i#3&@&H(KsL9yRU+dpwHZ&4s&u77w_mjKs7(#`mkF#;Qc5Kls6!Q96RX> z3TqV0tV`mkd$x0*+mwc+=zV$cwZ@R(=|OtA2#j;M+i7gK8&E*~5h)t!ts<1cuX2sgI0*^B4n^)Nc1qG7cVDwr^0ma<}n#oGjM zV<_5%$$xTfWO|Yt?^|oH0Pm$Opul;fzSH}xHUwMgu~YyJzLGe1A%5^qB1JyerTDZ{ zY6K$Ws28IKNp>>pCA@h7o8@04Ct?pS!4~j0^>Vd?Et6PNU9V4aW;dHe%R|>!$NSCT zwyQx5xce)Rw(uAkrI3xrhs+a8i@J>|0{AfqDEJW$h}Q_ zz%;9pH(P0s(hSS(g_gy(2z{<~wwC^NkGl;wwq*>N)^~Fo{KVC9fLSm6CNC#)Wd+3+)^^ zy8qoLG40%KkDlkOr`tw2DtHy)M9TYWTKf_KILsQn{xtE;r-9+6DwuSN;qs37{=Ix* zaE_3qfCU9VL^{jCS$JGOdqQ9n^q)5xcL79;OTR|K)2~!}zZ8D{(d=81w$@?CVagE* zR9}=izmT!J!a{vPCpCk;@Yb@o9X_Rr3=gaPN7xHmMiT6`5E~5>leI6KZFj^?tkVMA z)YlIwEVuc4#m3olCQU1gr9PS?x#ssvx$m|raS?tgK&I){9Pjh~R}|~(_`Sz9_A$`J zmoI>OUgzblZIVX@w!qZYS#RR!p4$wFIh3$I4$=JGP6wAw*ry6nAA<~0AakYpZc1Wu z;%@Hr@DC`Fnkp>yUJ25Ya zj+mF&SaD#JL%s|&xz#BZk@m}LyH-g<$z7deV&90hG58qjN$A`l8{ z+fRODkgjixQzHt$gntxcp&vwB2fB6(enYO;hFQX)+!z<$t@hu}en-+_p`eq))ra6c zy;Jn#)xj!?M`NQ5c&2`VgUD-wUgSq1#ao(){qj{bI9W7Yplrz@{5qPE@JE35*AKKl zd}_RMZ3VF;f1fW-)_{s&t7*oX#T$jMw+Z&BH3yAY{3=55a~K~tOyev-3))W)i%OuY zX-z+9S&9SmaMb|~1Q_jaws7Xi@tyizv-f%&tkE7IH_U6f>*RPI6D4@yZo5IeVKf!qo%I4xcg}(KCr~i=C z4%6P$N*BFxbQj^KTjeIBDY50%cKa*=Z(@apfCpRBPBb&(`whjfCR@v9l}}Do4~>Gm z@kkXweZ~Oz#m1hQLTST(of0(g7zGrohho5CE40cF>=Dmv!mjbu2#sg!Ledhn-G$&R zC4B6*4>~j8T9-}k1DfK4F3vwxomIL7p~^?A0@sUapy4hIm^Rp46PgW%8tjlEH$2>V z{35ptN@jUTqc!r`tXm4^i*-}Uy+xyIQ~z__OsQavW-qh8)t>k zHCOj<&Xr&TPOE=>_Kuyw)_jl4Lrg3}Eh+-rf(NTs^?v>#_-L7dS9hk?zO(g?9SRdxg(dbBhJv4^ZJ*FThmVo%!(zMs1``HNMMn%TMp)zRg=fXgX zi^7DRV)m8{e9!*T!ezoiiym1I&Xam+{GH)=Q|Olp@m&X@Akux*lj-06Qy42nVZF)z z=Nk>)opPM{6;)CjjTZ|o`m{sZ@IrXw^#*khPhkpj;wE1||Jo|a=SNBEZrPiGOZ>8g zq~nq^0Z&T4az>{#k3oRz?qC#{HumluO$S^RE~z;(jXuLX6FA+l)pxIg=<}4h`i|Q_ zcK&C5yw!)lEv7mIN7V3Vg~aEg0ISQ;^g8VO&#)Zg<@Lh2`%0(8(Ew>BM^FQx$Hu1J z@k9-2-^zEWQFY~}Mc%0mEVroY)`c#FUP4YFkeIvC!`&MM!PjCHu2I0K`u#5?m6AI0 z%O{D+A89V3h-{(B8*e!J&asy=5RbY5b+OwniWq;ARJb$JJ>YA1Q6U{W7z>9QwNN}c z+hqlTY6>E?ASDIzirn70h#hdbcsLhCn+Fr!8SDe@imz&v&;3d)lst958-lZp*(Ljxn<}5d)XzhB zjpJ~~JBjMa8oKdEW54JMa{r-Nzzk(hX!iqsU^L4WdThN{Q<7U=>LKKnvAI}qUXz{o zO|o;NfH8Z=dBx|^*zZ%plS+-KO! zuYmqD@4clMU<~;f@WB7zuy8b_;{vns%?v2y?7V?9+@qFj#(2n_?3*Ti47?Qw9aTkHl{1a z!iiT`0zhWJPnQ$^aCOpa2;m{S6l|7dPf(xDN8bl(!W|Fwd3U#Sif+r>+-t5JbO+5K zLQYVU$6DYlw2n3a-7`3QsoHN2KK-V@R>!fYCe$}5Me9`WR%8ut-RWpYmDBeXTWG%1 zZvFCvph9of!^t~uP+djwBXX8rpit*>uxSv62n?A#i( zY-2T;Xv|XqDExs?92`RU>8!HwM@qbKkAB)-iADQ7z7zLS8@=n?{RSu(yuX@{kU4JMR1RqifBuVK7G(8d|GJp2vb$PUq9@3wNJf-?mHEc26}Tv zV@F`(7xtZo2_7eM8nNMlGUfK5c7&ZqJ!Lx^$bW^#{Kyti?h27WoKT{@(?F5?Zg*?S zzKXHkW$^bR?=OqMLv*{^kvbds7yCtM*?;E32PBr&V zMf;iZ>(y{@zUp&#{gy)_#sfkDtw&NFH>yuV$ekWR+3KM)qjJ!-_e$!zlU~wYWpEsD zCk2SUc*AIzB9}V~#yoZBvGki9{HfM@3DR}r7KY0O!=|GNDS(=^ z>^kwIRYB9Z$@VP>gtLg2fFxR--$<`{)zAXGu8woKT^|IkroFc*!}T(-V=Vw_UE{X-hZ#sc2|lq{Nvs4}2k^(#PQgNEw1?2oVBK z4jT1x3))xjk#lajkqyD1+xO^QdL!*K@p>v$uATO9-t*#bBpb>twiAEWrWc`B_=Pt( zbm4;Il;a{6En`ysV*>Hh5%VA(Fs0d`eY+QOfc+sywn*`A>4kxRl|&_pcX3s&g|+uB zq)yC$k{B91xpr9vbAvhX?d_)b$S{$X(tHgM4&0FwQ`{R@ywlfu^x}H!aopTkqtAc1 z9#oo>r5BeJU}yar4Swl=Lt5GQmR4NqR)kK?><$7-8_xof>T0hs=G6#O5~ zfoyuY|LX64hj%jVRC%;!a#(2W+v>?UEnLi_+HdVhpR-#e;p@2mTU|$sfSm?`X)5hm zJgbj6!BlqYZw~!-|HyGAK$9p5)aEb4d1|5%CM-PulzgSQ_0Fb~mD(s+`s^rIG($JwyWT#5IGz#Qb66@VY*sDE_ zR@0+4Emv+c%!JBc#cGv}69>*Kkg`~XZ3=n(opA5Svb7(9)7RvWvD`PEnW+vl;xY0V zbXO&y5*jR0={?^!l{?WInAcQTb#gtqk(73jm5#_SwYL1~iVMR70N@9> z!9oB-M9Jv=4?|s#+|Mwd91lfE(%U`Gn3&>XwO6@IULQ**V0A))V+sClOA#A*Cfw|^qb>XF}_W>8jps{rXb)ylGRUI z7D+@Icc;~Q^l4vj%nQ-g_G(V|_R21(w&`y{LoITBHNGowh8I!lh^$kst5C{FZ9#gh zfAMZ=YYHNJQF#1Kk6(eL6oi_OgM`Ww*7t_&L`?1cBEHLZf6JV)Y-!5p?vi~<#3!ny zko|321dp=4aI?-j^lc@RUA zeIE1VmSG1FXQ@4Xjwi=TfPW<<*N3%3;~oM+HgIm{gfGRMIdKq~^-$^j8VCF3iv6$8 ztNS#CS*E#}Kcai)Iw4nnBV$@iX+gMU@Ued@J>9)v#|H%p+ccwJ>&a0*H$2a5rZ%(al#9zf81yf;frf=1qB zfI#>9`Ha>Qa#K3^Q$i5r(r?~6SLDg(kz<*9SEOJCVH?+)6ARfP`>VCKqf?vS_E6zb z;~|?Zl3&fp7QQ=8NVfkwl5aDKmOAJ(p~N9%%Gp^_eUB0~wIP zm}re=0x07;B|k{dvB=p;wc>SvqyH~j18r&@4bW0*Q!7~UU1e^bxZIJ-s^?dU6OH1w zaMOs)Fk#AbPWo*IEb!r6wn2bOXm}*2bbP{Ujc>0~DxBd)UiUU9lubz0w@2bNQv(#1 z)N+MsKYj}qs89BamurYnZURAh-Y`Bh>!}@&LR6V&l&FU~2iFT9^WAdweDXt0LcDiIo=amZ~;QJ0*w2 zZ#2=%eM8!UNmbbSUl9+e{o-*yI}-5)$w_5mcl78pb5iNQh4JGDGdd}U_~!Lk7V$vK zIEnjR9kG|Wh}!)l$#5PhtgGTvkl^XJILzrpQrS%=(v~NJgv5I^s4rq6e%BiwTZkQd zU6mU@#14|=Tc<>qbMvC8UvTx3jfLZJzFpYSxJ5Ua8zEOC7)k`4Vn9(Q-P!sxk>Jwe zK8lu;3jUR&QeEw;ywA5e$SsOVnGa$9)?OJntf;z^Xn7)C&lpe2Mek}xe@CpvNP67! zrf8}ZNOGCHdw_5iu~iX}ph%z_wybd~Ib~f)&rkqkJQ_*T?(aTpPsWs8Co=G?&LxTnuLEs+=6lT`18l3y$?>r_gf=8X5C;E2IS*R?;2XzmZ zx*VHV*K3uy)7=C1ysE>oekMJ4shhsW@0DxogfSX|1VIZ8!masG9WZG|@y^1-}$c^`h9XXVaDPI|!t^%v7BC4NiEMkmQ=GGPA`T=#78XkUg zP3~k)-(C*CVbZNvW(Xv!Si;!}AxMUpTz3b6ua$`@P+t1$`hfX2rbD zVg*S6hs~X0TzpnG%3{4_eUInsi$m&pV%sGB_V84e+;`G@Qf+2}KI7oKj|A&{rp&5-lWyxNQ#siB=V`?zer2X1 z7ja3cJdZqzCn|@Y!Zjf4%MLVBluZD$XpworptwPet1L?>tF|s!RFA~l7IfF&7Q$dT zBJwOk9ABmbZ{cp-x5MN~axW$?{M|rt*4?fGiK0h{3vDorzDK!LXZt-WmtRdN%%-&32bJr8fmye96IY85*Dt ztW~H#p;+$Ttgvd2NnktEX20fGgGQY6IKT+7ep9=O^8XbP6mkE&&a53+SYf0!ZV*+XzMD=MLq z96n<;S1lz27V>_RoZ-Sy~-X3yOut!`C4|kL3=nGG5;CE^g2vfI8JN&E?(R<4M zpwGwn41>`IOTvuHw}D0wQGVR$sbtqdm&J9xs8*n5tBy}ws9Pa!fSu^O%Xc)bw#euG zg8C;B>fPfZ+6X^oEwHp&UU92TDYS5-iH!M@_&&j_@3Whe!?`!Z6FRCGq7Nw`?QyO~ z`FVQzKKZU?4UGD3myqZo9_#UTs7>EO5JQ7@#m!!!fQWf56)*~BJAUnxEjOn#Q)YUG zR?U0?F<4gjWVX+~-P&@N5{k{n^lP=SHHCEe$|#+82nFdzu-CmNw}D3mlt4<@9v>Ze zsI_Lm-pTfb9^KN!2%g_P{qcP}{h$z&VG_2ox<7!$(yk27b$hX-j?mdAiPtrH5lDfq zDBnvA8TdV+P7xd<4%^!&u0t1G4Je1JEmGim2FZYjSF3p2Ihl{ozp4dW0H~e2e`-n^ zQa9TAo(fsD zh!YYur-!b^Xr!&mY17x2=|CJL?lo`ZBvM&;*jE#ZJNA@s^p8v2wdJJ2`OEb3bV*l& zuA+#Og1SFz0{?H_cdlbu*`eV>PtaKE+Oc$bY1QqU8P%8dm>%|0KfjV8Re1fqo7F}AMy*6 z@{4I8j+Hob=|*HKr z7%V_hw5Lx`#O?S1WFSq$&06m}CwiKIdn2^eukU0kM^OR1Jh>}X;SLVB#J7TX$s3f=cRX;_Cl7JwxGO$Pg94~c$@@n=I}?+d#`yI9OO54 zqktzDB&b@6%M&xMmLgVU7=qVK$(Q2G40%F7E}!-6Qk&Rjk5A$ChKv8(FXt^j$%XEw0VyATS@m_{1TTsgl=UwN*X2?=bwuvzc?qInBJ(O$^n zs=*64r&Fca5EL!KpXbw{gl8?!i53nbV-E2*wPox(6ZfHP1x>$t=WOw>s&E#GapxGv ze%EkxuX}u2N(mV!WKFeD$aZgzZ|Q<}9O5FYQLZ1l*pOBoj~)>`>$xN7(39muN|iaY{(MmrMX^bM^*ez773uG?QI z^!VH1M(;y{r@UM!R-}d1pbrXCy7P&SFk2(}h~DgQBKnmbt8k@DwMPb=u!pf@ugHC&n{F?;sAt?$&gf|REML{g{P7=ggK03^xvg{ zi?HcH<;M#_Gn<}rpw9<5;)0u;tUSGwBD_hR%wg-fmfmO?n3}1~`J13Iy#(lf-`5^= zUGTiG%yvkHpWPe}66bdF0Ogqjm`n?*g;%^zO&8#YY@Y{Yv!}<9Z$M{6$;`m>6DEvI zjUpqJ=5hTW(xe{PNxCut25tCf33)h>VP+JsmS5-EP{~i%VO1$UVqsuIU4%q%jML!k zqp6}Q3H=T+sMtheWhgFXdXf^b#8OOa&^^6=?t(ClfZzTGrDMyK=9#biqyXKw zR?gn(9ty8T*^fl@E#uDo;6?wg(KK41-Yu~$Pre(m96QjEPHzxpR zy-(VXs<*kN(4PVaE1_c7KVgU^j6*wUsb(nHoUK5d!6%15P#e^7{NbuNr%|G*+ZeZQ zCOM6{BW0YDZqvo3{fCwNue2PDG86@@m_DVX^ znn1bdcY6<%YU2mN^BfhSFNBJ{H0X=;pprrSde;5W*%eUG?#g3_#<9IKi}+m1b=7s zyRQ7|C6fWXEFtD#6)-i$wKL9Q=yvOgpGao~VPeQAoY>ma7MS^l$#&QoO5&|HsHUG? zRO}v7nM9XWmKMCo#)~@p+iMcEbGf&75Qpm8Eh*W`zqyIZYA$Ph2$j5q`o!Jhx`cwQ z2z)T}-_Xnw38geMZz_WKo`I0lEmw?QhwsLB$m|fWyVThTcPDUqIrBOXqVl0cLX}ayU;mhBt*$acMP*LT}@cTwph6jxmtCn_lSE zy|S)5nX>oX#iz$+iG!ej#%vMr4Kmv+a*dy5-1X7caoI~A)cMA>3lW1ll;-cTWc+Wx zt>cYxsG9pnOsUaZV8}hS;wa~dLZSq6wlE0sakTa0NZOM#XgS(L#OCGKj$;dG}Fz`eipBe7{l@8?H6?V6h*}oX_ddUBQ__ezCSWC?#XkSEMRMQZ?*lFdCKz8VbZdbVres`dIh) zrT4fGnoU+1;mjnoDz3!}PH9YG;y340eC`gZUpL&z>k#EpkFWBp0|wJoSZAFnWX`6c z*$UrDk!C<{X=c}BuK6-W+Aid%M`(V-u;+ugeu$9xle0e57KpQ=}m*aZtT5%;TG8uuy>tezOj`sEOZ&MBf9cl-J8czyMTC4D;3 zdObfV>(qhryUltakRBWDZiWi#eQUF6aA$ve#ZDZuX22}sb}&Ry(JVoVVqIaQCDC0vq_Jl_sFpEi@n z+P|JX$hA$`F5Ku#nw|AqrSpE%hLZ~8Du%uja1-2}YSK4HcNN`eH^;K6vkh7DXj+mRa=H3Z~Io z6-@Bz#@O|dtm3!>Fw?zSjq#0As@qA(Ao8RUMKNjQ5e<&I! zS4`g_W^DW&L`NFh16A1ybtUooV$9ZJKi*RnN94qpR>Z1(L)@Mt$-Zbjcgt3`h4Bpa z)Xy>$Ards0(-GR7OH--0Uvp{UW!TWq{_XWK|HN(EsFW7{R>{O|@Kow3pPhRc1pu~* zF66fTA`pa@dXQ&-AhAL@1QRa=C)O(hlLu|D!b@pN(rwHXyo4_FAZhEOW@+R^OaX6owVC@^Zmm<^s zkc;tA_vKeR{T?6_G0G5Dk2rzRlhX?)v+gQnb0%Mp)iyaCAsPpY8J1bEWgW%pah?M! za$EC^tPQB z@hHEj+1BrnvT5B;l=3fE@S5~TKLeuI&W$P|$q1$Wrxk?1P)2_dgO7 zoYpI5bz`W?2%Yw^I8F(8#3RY|@nlvlZU-mPPifme{Ktze+uJM13w?Qf zxRb=L4^lvUf zaqgN&Ldox$+$7yVOm==*{?EoUTU`*mH)@$1T#DYgp2;r`1+Q*)yNs$a9$fKpeBeOL61 zpA@RxmwGfm726k&UT-68c&K6)-cYH-Q78e+_{G#v4TmAIEnu9_(~;llTgr!ynt(+Y z0@|MEtzcCtmZkuD(-n1M&4y>2=JdwNeFDe>e8f==y~L+bA!$j2cEx4awoMihn_68C zmF9XK(GLP6J!N2#*uqV*wY!A!d6BqvFQp2Z3j9M$4@sq!7q47tnCP4_SsV?wixVX_ zi{Zc)-3AS1ABdjS;D6Z#a4Xa7(Z;;GL4M*<)p1gDPm-pSfLD`WX$M+b7+T}1$;Cr9 z^nc0r?wqU@t7R|QS)&C>Pk4hR1*ThEq1c+Nx{%Izo=`uXkIl7eSKni9c24R8-c{#6s|W;`t7Z)Lh%MMHPkH< zNV$mQ?WZG(bWXI{1gb#rE`m$UCu+Fg_Lz2_g9C(f_&UlMc%o)1w^Hai#Zt2?MO(tp zgK|G!4D$7a>!REt=VWr8UsEDWq~>ZA)z@Rka*&#Hr*%yxxb~YZbE5P-tf9kdZ3hcw zK7I=B$`~>##TN(*6>Vcaux2?{cOFP63M51(<7k znVQkdcIuym%^#e3_xGwnXH04zu9x(#RdjA^1j0!{Ti^pwFV>yJ_W7-L5pIr%5?!Tb zj3#)@qBtffGb`S>CNm_q&?hM7i`1_>Lvx+YK~~h|P<`xN2=MiIEOsh^LJZm=-LJfW zeHb@LaUfbEq%#C3xr8c=nza5!O&sx`J`sw}`?q}np**upIVjD%*QZ2;uUNyPq{N~K zvGLr8QlA=+e%|a8`?!fgTl1@S?X%;->W+*)%B~ZpKuJZA8FzaE6QG{m#>q!?g*1gx zoG=1SOq3f764g#k{4Wj`_fY0icj2zcRk52KKefsMRNV_vJlBUUDxZtmhQ#Qx$Y4#DHTPhT)7oXfFWYvriSe*C4 z0z}A>_Ts1uqMZ;s%NfQWvRC^X0n2Q=lpe7mn>C53r}!V{CzF+^&qQ~v{t`ECEZwr3 z&QpQOwL9jy2%LUo+tjksu^pM*2KJozf?5dqCf{JzW1<9FvA_MnCS!Jxw8J-oI3=^?PXWfz+!3?`JEkkB((uIkLccD)yScj=IJw zz9OJ0{Epb8#Z2luc*0-+Xi&R5OOI1Ki;Y{xK9peP>gqmCQf<9J2#dV!@Dwh1SPMa-#)j&NCHtp2#vYT zlPX;zuFT)HT^hE?>O5^M7Inzlz?+CPLq~ zXsbo@;iB>lU{(DBs$m?7kTOutUG5K%@iP!D!RL zGi=_eb!PMUcvkvr^WgXs;W1^?Eh-;Xq~2oH9IJ(p*Yi9`vy5o7lUJ0eC%loO8?j3s z+Z}i%0T{v0ed~V}u(iffh_lR&WJmZZN2|ED0xWT+4Im34U-Iyw+tvzQ3FQ?VbsDkl z>!$G4!Oa$dy)!2N^ce)~fWMw#YN}3A;ahbnmyS(?U(3QL1NBXo>_)_yEa^L4=ZLWt z9$D@5IV?wLlRzU_)g!C6`h{3SP^<=u}B`$@byvF~BQ@Tk)FK@exT3jX1 zT-dYKrbP0DO$xszS8V{* z9HMZA{F2c6M+^hRjPo+p3VTWChDG;c*GfenY+#lGsI2k8wmsV>YQe^2Vsm3x*1v+u z7t2_@R!q@^{i}1^BgbH7-NQ+lU84_^U65_x!YvL39VVt*M7)p-TvUb9@c)dmu-d=9 zdV=hzYgMZ}LRplxM!k+?mjTj|LK_3+OYjE0M(i0J*=U_*sg=E{op)24!v1LElc_|a z{P?!HZ1+U-{j!~NE1!SlyC)z>u^mHd?d*G=NX=FLGG}#Dd z5#K@FE<-p#+nJAFnqpl-Q5&`(c!N?qYNbx0#dsDpI*d}VH% z2do>^P2IicZ_%utP#Sm+aefMm_TIOQg(pYdSlSO=bwT#Ke`vRr>NO0$_Cjw{Pb7~A z=33rWn{wP#ANa;kjMu_%(PsSzcNa)i!B6qgh=YP)4H$2dnDeExL+hLF0cU!8d~}}P zxbbX!i!W@6fSg!C|L~w5HjoXwds{y%fw zI+XWJ%RvUhOpYWeivQ3u=2!tvqILC0?5(nor&F(NOdYV60lqw=nyf!Xm*S>ZqUM~M z`^#vL2ZeR{a;slj4zRHWrZ|Yqylb)&;}&36qXxX z%O21}QtXBa<)q?PzeMo?j7Yy0$?k>{Cs;D%_CoWmUMj75v*N9`zq=9cahBT;P;ZY9Ls5uYG|!{4ibI9*FT- zrED)B+s)P$R{!XLs!A$awo4m6`$blB!_n$9Tc#t^4m3fP(_o<+vc!evLO@%UrMX&x z;+T}QpX0qW0a}ue$S@*I1is5uk?unxy>^OUi)h)j&$b;T#wOouFH{i;;eqcztWG6Yf-%$!O^f2|02 z*AVQa<(C>mWOU+GaR#0>T5w&Ct7Uc~Vl>q2xOx*;6Yt$vK@t7D;GNnpzCl^eH$_yF zdUOIh4U03rzKFhKK$vYin$?4dCGDCjCB6fhul)}Q#rv~rWg~mhRWUn|R%u#^XTWf8WU{Wv?jGn*gJsN6dILY1Y8`Ae@p{xur z6dBQz+os|MxQgk_j%tQK14vW5cl4&gB}?AhqBvo>&WzREt|hI{Ru)FLL!<8nb-dVAj&p?zI=7Raghb-}mLe58!)FutIYJ7xS;M!Z^S(>z>unXFrkd z^diN<0_yq}Zp^lk8P;>utR}3(e<1#ipgqDl=&x1vcHp6|yX8^a*39 zRsf3Us*Thtfy{3z3KG_yKxMDBit-(8X9SNPFOgG#^q{6tv*0g;gq>N>jbhksIzLdX z*k5IMz){H?R|U8D>IZks6K&e_tGITvB&j)K|+PYGA*4lb3?9O0$Wx4Zr8s~V*Hm@R$G?{k+)=UD9C7wxM!>~xLrJ+ zDZlaPsn4%AS?>CFNC*#rEUJf1$K(6ye;=-iNX&DAETh^^)#+Wmxbs69c=~WaN)@qH zDW6}i(Wi7G=j0d;v)vC;ra0CRU|IT=cj%JxEc^@I=z}frRHMJ}FSZ*9O`v#bW^?^! z^@d%?PfV$?J2XuR^(PX5pYhnwed|EqZV{gPPE5qWfTd(ST*yJc!LXfb+bXtNGrp(r zyjdvd(4!L9&q(N*WML+cHN3@hv2xp47kv-v#(=frBW>`v9np%E!WpDJEQ#GU6jZmn z4zK6x?+1yA{m%cy#KSOwnc;BXl3{oY76;Mf=#rZ+9KA{a_Mm^>_9Wa|1m* z7?zwB^Rwc`NoE-m+v|8oA=|u%c~^t-Y6N1!-UKaRg#Td#H|f7YFb}UKPFlu$YIVjYy$o+*|CL zd=>%sK>#36@^E2J*C81d+oY2MRZ>+3ps{x?)Ioky$wRo)(( zYPhYzLC>r$6I~=08{~;F?ujc}*)ynCGIX^_TVhsAGk2?$vm8jDD zp=Im^7`N*-Cox5W+R*@wPC$z_HBc$77pWhAd*KlhQQyp|m1dq65voIvDUH$}FeApW zkCyfvU?U4Z7X}<5^)hyJ5-nNk)(YpFaTmv-*o&6QB;n0wuZv!G;{`4$TcGz3iXWmv z2lbG0iX-R8&&rxbux)gyBZn!pe%Ou`^p3k_yz}-eVl@y-7aGab{YTan? zs3Sb8z?EHaSxr%Xe!|!ruy2cC8jXmrFss^x6}V%h+xgBLatwE*?kdEZME&klDk*F?#aOFdF+59FFQt zon~PGm1JaUtZ#Ymid8h-LjU`cY8DBFACuZ57Bve9E6%#P+NaVm!0!7&K1?A5(c@OE z8l9$mdJD53a(=a|%YZZ$o|dyKokGcnE&wZ<7AJJbcKSyS8LcH+X4ZO%qP z*WsTm;J>y+;|M=O~i^!x;Eba0YTIbOY0`%ydxNf_8>eeeqKrP zPkbCTai_Q)uR+HpdYpnHArB)9fX~(jC=IU9w(ws%Qq8(IJ+8&hi?7xH?b@&On0C-L z{M_dGft0U}EJ_?4CO4F=qxvi_m>*ABvG*iB`m#t*9(y47cf1%Ml^`2r8wOm+N)Oix zpX1O6n+O5<^p|HYzOpwGT>K=q2~-W;oP21oaK-kB4-s3Bn5zc&0n#>>)n8nV_You0 z)OdX2&!RQpyv-D^M(A*c=-u@_{Tsr%zw)63J(^*#o^hXXo7w<9t!uNukv9x2o*tz4vCkk3BrY{+_mUibw zrU%qA*BTrv#$mDEh0~knqk}4fF=^o>rzH~i+H+>X2dj}&0l&TR8sd2D7jst1PnK8w z83+(xVXvS6N` zskekQV_S)iN9(81^Oar__HDD9#qY_aXm>7o-0Ct*cy5nKr7A}43hcO}E?hx8T4-Fo zP4jIyEeE$$jRuHcFe!wZk6rQ zT9~m?k{XO18aXR^7OUAgvf7Tj@h_IP%GH+tu^bO!91fcSTXv>K?fRvLNgO)Fms%9= z<*irYSvc@M;jh*D<12xj{E_i@@$8iUnE)B>B+Ba zq-#nSimdx1X~TJ*Y zm2db7gq`$Dp2Xg`5*)`k%^?*(=JE3cOl!tmc|G0wbIESni;l^Ks3Ru06p1_1V<@>v z-Qi%wiLJ+7cr*C*#Wm400RN>awIeJI0ex-6JmG^$ZqVngv6R)jd5;XaidPJ~np6%= za3Gx^F4UBxZ|W270@4QbMdzfjZvqu}s%b#1*P$Lf6|V1!9jenlRIwpRGWv$n9-XO_ zspU1&>}3njgLNUWIC+*MNYmA?f35-CY$+f-U$mB6_@brf`>dGm~& zVlyj~&$i|n-ha|hTPwsER1in{X@oa04XiEG2^5igrG40;!&{j;eJk{S|*?nH{`otgXvrTa0cRJt$qge zh*Q{QWf!J=5Z0?uZ=-hc?=1VBHvU7KyvvR;N?;=}GI?79tz8BGIOGd;MzM^K;VupA z=N`uvqFyC<6u@{<@b6LwO?X0e)>QTiCMlXqM7%r|mz@nEVBUr>{2L^piMzC$+Srw? znt-uZt)NWt4CZw>nQ=3-+~!Ng84X0m!IPf}nMMMyopTCd-0V0wd>;o5{PAYM3);D} z<69lKPd=N!H>8_m(shf2IGT#O{3a9Szp3d!eiOBe1_?LuBZXSnSJY~AF^#ALo@Ry9 zP3yrTCF{9vLqTN>rRH%(kaYJ;(ypenq-+$ladF*cx@wGOdw@IjZO$xpZboCQg48xI z3V_kClU;voGclw|R{vCf-C6 z{s&;~rvpJFPr(VK4=x$XQXrHS5QpI%uek`nlYHhWj;=m6K=m6OAyu8L%C&I26gSyi zXR8W7QOD=3FErJsshxSdq7*qQk-=ZtCLH4(Gk{!JHh@BWg{dh#mJG|87iPYy7>DQ1 zI1gu;#V5_|%Pt)r;VLQUC%I`TImL+G2*-*cch*kU4pPLLU3aX(P=8&pE;id0o^Awv z_p2F`c6;1m(|KLTZ4Hp|&+!m7gITZn1%%$9?pJ1o6zQy*@wn0RK$x|w1QKG-+M|~^yAVLGYR==>U|P!PXf%mn4=pY zuf3zbBn|aqVF)PceKY0#29jHyYssxc!FHcyp3Nmz7^M2>P)e8>YvHs~7-2ulo41Hi1=& z%cciw<0?J$#-6YNbe%~%j{e7|i=$!$N_vjt4fBgfbJYmhr$_SLPITRv$mBqJ6Bn z>z>436(YD2T*t@6rfjl!s+bu2+b@V-qWh1Xj>dSgys=0aQdR7{hh%urYV;0kls*TYB0=2-k!1cig?d~fb7T;k!Jjki@Iv)CD zplrh+#S#d;YggDO17|sJD{}4BY+bT@h~#i@4&AJ4uL)3ch*A(Fmd*uw+U>fMy#B3j3IUM9 fbvBrE-R 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

      MZ3puB`C+%zj;>ZN!Xa5md)}_!=3h{1X7 zFyy!^O~^j9E~&p>$#d8U_KBr)-LCGB{f;#J75MdVyYm3#aiJ+htePlnXLuLZezOAQ z-cYL)WLedfs3kNd@6GK`OwzqIU$0j5bBR?%8fHK^?YHZj{Ry4avo?%_b#-HDBeo`3 zIJF4mKGY23ckZVYkUoFheBg?4t zLcrw}MF{V9fM*PvN`pBr?H(ybRE_U=)_|+>8dlwr9{G0dl?#&fpFSf0?bjNh_^c?1 z&oGnWSuat(K22am}=?ui;S(WPFmNPscsx9pXQO{NFLwhZKPvJ^$QO zjY(!2Xof@5$#EXpKX{*s{D7?hqs%(&sG1Ay)w!TqiTwSpUcb`^{E@`}a{N=6{VV1_ zg)kk_h+Fa=1)~GoezD!;<4pNpc-kqwmGJx_6m21?6F9(05(`<+?sH?=GJmD}KTg^I z-TWgp=-s^ZWF48-!`}E`fMO0OYg72(xWr{HgAl~5Vy1&<4*GG!b>QoS&{S3xzq|`) zT=^FaF3- zLwsn)oi-p1!2JM;Kdddc&j&C)TXZP5nD_Kt%rl}UhN>{5| zU#HO(a|9ZX=EfRm&YfTTo&bQHS-B!wRPo`k_o=rNz!x3x9F*V`LLG)vX^cC8Qxep z_LTl~ylcH|`4_Nx@E1^i>n$setA)o>-eLBB`_PD}L3+twk)dD8Ztpe$v#98qy0`+0 zg*-aCgR*>#5K=fYTji!;EUGe}C@8+w3=waE`kiQwp0gl!OvLlo)D>Aa9u#qocl=+=o zaHRKvN7PCrx8PYzc~s=<67bv%SNaEJ#s|T zyN2)SGAbFL3_7P4OHi%J4qiaiwHy}mb-YTGJx*_>WKJ`Qk|K^_?M*>YtV@&d;4W74 zSPmy5=R?PPx5J1J!Q6vE_a>s>@vxrIT@P9KwUASY-FmEpkHI8XDl8Z05569Y52d66 zOE;IcbMiA_?{mV7e1p*o#TFy+V&+y;T?4x5;v;(F9po~qN83~X*~bg5DBq#qT2~dT z$i%#nU979{7ateKbeMwR0;ibuh7{^=ui9^h5yS&86;Ul}&HDBGiW=({(!=&Xckf=s z%si%?=7w?$P^Fnt!A^Q#ckhCZ0xw~328kr+lxkb{G9#UP%Wc|U?AAQ%O(QCwXR5U` zV#4{iX#bZ~0J^5>>Kltu`q{aiDZ&+s<6Bu1H11?CPY*zwhk$q1qf~ zY|FY_?d}J;f~aJ_%Gdn0GuN&3Y+A+}O~?cJ$`cW0 zj|+lPw$`uRT^~vUn4L=mAKJz35{)1H%FAMl)=9PQl@n5;*JNltY+~3BRHdVI32Jp~ zqv&M2EW=cA)%&*+lMsxjqH9MF6&bE;6;~IOSz6V)zq2~4AzL0VgFC>w?{nF}-Hz|9 z__T2df+KMeQFfZH0NEG8{EWH14=3PXBs`y$7l(`U!3!j()%v$G)utXPcuSL*upt?E zo^9!Yu5y?-DVsI~3s2ob^SnMuA{G-~!SJJHCeAYzY^G9@I zy1Ie#H6P9|t419&!B!G8f@;|%i;X65#LDjJRwh05>*w4 zb7DjrhkuK#=V$CH%@FVcP#f|M7dhEQT*JXujN}RRaI0;@Z~^YpD7_+TRhIHqwS;(j zOAN21UizU97xk~>o8ayZTC;=EKXmSY0j)kylX$eTvNC0$+HgYV>w+YgiWzOGz9Cq~ zDXkJBCh;q1@=K|LHq;u6)Su;qjY@7=CXEuZNtOQu+`R+H1#YLp!Hz$1zDmJZXgoA+w& zcsgD)h}$va2@&Q!p>ej=?hFy`NVg#e!gn|f%@hR+Y`&U%_Z@JmL6(^;5HC#4Rx^kB zuCg4$pTnUU`4Vt9W0dx4!jmd{gK^G`vyl^nWEt8C-CIeh`eJ8hwLQ&SEoIAUy7L2I z_x2#WgIcmp)41z#c`#uu9$B!pI{b1vK_4gj@v@8o(mP_YeDy_6dm*73eYERzGGh*?$cIoqexT5UP zdF3fDVp%c=losBs!@A<7yqc=FxaWj+x|XH$%4XzLdVmi35yjPp92+MMHa_sNf7mjl z^W}tE1LWAIH&t&BC_uU?c^UiaRp`4c~XC^O# z-KDim(CF(<^b`W4i9Gtljt=wu37$3=?A$k_%~vk6ckgjO1IC{{*twd019 z%4^VPwGk}kAVVI=tL43DE$)7mYpqe&pB5Z7M`KpntXb;D__jAJG34Or)a+`!Rq9t* ze;Btg@1Y(=GSE1^_lInbPNf@kg3p*zt3lV$xuTb3PB`b;9&mJFdWyQ}bah6kaGZVXj`0J|swRCp{vehNw^m)#x)T zs79ZWbd+%FyAZU0R*R=?Xd111>{=Z$d2M-h6|pYNQYL#|iydy9_M0ehzvW#H`Iwnr zRxAG33YMER5YrxOW2|hU?YfQKa7{d{yF5QTiEi~T;Iql~6A`t-1DeY^GU3&9=-e~>}afB}C$Uw>FUqJ37 zqY5&tP-2?*AoN#A#$sb6Asy>_cc851d-rif%Zd&$!qP2f9CxR8MwoR9#&#LYQs~Wy zeusqOh8Jy0hN?R4-s(pomqdRGUF=e?7!wyRlWc4|Y-__zW4(ehO{{i@n#i)E^0!Z| z2xem(aB|fWO4r~l2^|?lSwn2P)hf}d=gldDM84V0w`x{$y(f$TZ9`|w9Q^Sn;)_)z zC)E}R5hFB&xAV@*Sd00$@f_l0Qt$O5Vg6L>n_0^ZOKHY;?qra!r&fKCW2I5g!O0_ThQ?1T2x_NERxv{&uMp1Qnw0K) zhFrfbD=j{rw`Zib{^(BDCp6MYt;dFy+hH4!R;WQ)Di%pBC48ESR601~H(OV9v>A$y=k5vthBr$)xlhcuu(J^Oka&L04gq4pJsy|;EZKIhj>_ylrMZ!qeE;FGbW$*6%5UG@WDC!%d@9}Cvwe`-~!IiCp;K;p0QeS29PuYr6fwD)i@=kOo5=zt~TuS)IWZzJ?7eVuURufimM(yeKXBWC3b9R_{nvdVnE z!EXawGE!5;)1vbOb24BbD+mVOoE`}@TzKvO1r!T^&TnzDvRJ9on#;k(TxX>HMSE+! z?AorZ5sVXQ)*5b&1JZ`tmci#u9ah5OoJlcMhPIp}>fY`UKRixSAwh+$)S$9`E!VW# z2Kgi!d6;dbyo`mO4}aMvWwYeF-wN!lXBAc|m=iw6HaAVN>&h;Cu)aa-BAM!lVohLb zk|MU2zTM0+Bl`lwM^|u~GQBmgndeSD!q0@MgT*~Z%0@uaF=1Wf6-m7sONRbpB|0l8 z)V?RuzvUUXyb@_VOq73JIT_9;X>(Slej-NL7ezeptNoK#T{jCy2GnH{^XfBYBn7jd zLc)0mJ>rQsd7TpPIWx<(`9~;&Ff+5PS$)z#IkhqGO2&p7Z^yiSe4BqK8k;^%f5nl% z0Q(NrLoJ842bQ<)I*I(%RHp{wQakC#p``u5iF&ixGMs+7I@$TC$TjABd)U582q_p# zKcBQ9Wu5=tsQfr|EW((VnQ_^tz1jiCb!QTHhp5jud8=B5Q$D+rQTapuy?P_|Ribx{ zu+ePeI13M_SvFJYN_4BF$*c3r+5E?OAN(6&;a3V4PB2Tstad(fM?z+4wKUjxpx%FG zFSy-$bd$$OXkpy^Ql7Mj)aWuR`|0UamBly(^eZoZ$6!{^`4;;Uenj&k9aq5Z^BZ69?-g9^-4 zTYn+`E(>FGjQ04t)LFT&uLv zxp$aTkuX#9Y$N_ItfeH`#_5G@6Zo3*q z+idw-ZtGZicKg$Fg_rOLP3LyKTVp?$68^aR@_YXrHK^KTl8&ehk9@4`RR~Pmo39$j zU`8z`|FUoI50&T)4YEalZ?S)V`ChROAq$4*2u%p+vu~bdv>pE<@`;M zDnja$Q2Uu=w@SulpwmbP9Gnar7>Uueeith5lka|z8yt4T(!YmYyXBf37wcp%3DkFk zNXw3f-5765^QVm|B>NwwIm&hfhi^wWoY9XQg<>O7NJVWD{%0?q!xF%e&rrGFiYL6q$NUe!HiJ!4LU*CLxGEDOR3ypwA z)&qSiGl%uAn2OU2ctMPIo9^7s2o6t$ct5RFaoMs~=nRWG0 zTkE2%JUd>fePSFe=&IJ3JwOtZ9Qf9`Qrz1!&@r zYLwlq@wlCS6WGAcj^?%PIdS`%3whu6V3FT;U)UnrmM0^+(Bw34qaGFE#5TWHnPz2m z0#B9_pOW6N)ofC-0N66Rh0SGh1ar9_Zdxm#5G>z5DARNIJ4@K3+QL*`L4WBkMn@~+ z)KLAH27glbcEWs?MNiJ#1hq4HP&hfM3)dmK*ceeZcHaJOua|Qza(GRE)Aez&uGzNv z^NaK~lb2i0Gn%Ct!!w*bL&dK>j7IQk8kaPck+mz zE<*Os;PPl~asLvh2)mFhZN@ihFv|W99R*+bW<72D&pwk-^2U^$wQE+bIYe4XlM2@o zEVVHks}AB;cu+F0CdF8|UPr`wF`Y+Cp8POf-V3RlX|y~^&Fq&RlOE)96a!Zq6-0^v zfzg>P*DP;YOW>0nuQT`=&2Cr({Y5?|dq3n_z5IAH03A9hOLmakUlg>z)owM`X>NxZ zAI~oHduPN@>eVtrN-&qUWK!ZYU+zY+YG~W*^6CC*HU0~5S6*F_JUZhP<=vaLcGS~) znUb~_8zg@YLAv@LLVXur83e`ag&kQa#AYnwFps6e$I5Sa7F|Tt5U*UOW1Lf28f}4= z+VnAgQTw(Q-kSC5g)6xve3S_9Qt!)Lx8jF)*3T{O)YqO5+OnH@+y2eVM>ji=p`WhOiK=0gAccWHmuP%?Vvj&-t z%1q>2-%(0otMkzlfrYx*Cgc%5F{rw8e;9#kS&y^YPEN1k0wTCiizP3{we9=ugTtU^ z<7rt>^n4@?n!1kh(skvBUF_%g#(bU*CYI2>ITNgDik4ugV<1|JI^_H&3Z$NE=*gqfifBLbA(~1Y==r* z#mMq33_`tOq^vekxs2H+q$tCD(GNLioUH)vAm5aL95K zcGQ;E-jDO&+u%_{6JEGpL_Drh+%W&mm{rAj{Hs6goQ}Ky15;psns+smxc-tk* z`SKghhQqER4Mu0RPm3=LzuUGi)f*wK`Vkep-_9zdEnRf#T<)uhm1o>YFtoBt`tgD1 zn#w2Yd`qbo6>kDqAtXtBhWGN9JG$EIUN3WdOn5Ht(S7tNj}b4v55!`|%F8C5^C=qd zY{li@(@X1K<@dKJgU!z0ks&Ny60UM`(Hx`{=#5V_%SbrMI5IHcRKJ}N zxGUkUnXwGNupoFuNg_DenpTB5B6ySyx>PMcIlQ9G6rBc3()Z$}Xd+i~dmFa-Jhewq zIe@e+oZlk3hRQzh_sFg^-$`xAIZeu&0CM@vVGzCi(H0ir~wX zblA%}jeepgoUqwlaCB}yr2%$y6k+p{UNT8CWo2*{U#*X}U)y=r$^p+`07TF$R6sfC za4kn+tHMQv%R^hzf`yqvy2hHbcbtCdrzs=xd5T``NEX8J`_df+Tg3|bfIn@DZ0(3` zv*n$%P6;KgRPve$QzdJYzp?I)3kO$9;c)QQk@>?&c0v9x)}n90wLU>6d_S@HXy~C{ zoHi@jwAbF?aeCFn=2~CJ&o4DdvkQ95D@UVM@Rpe=k+`x8FkNHNrsA!c(gP{jqvB=k zP&VgFj0#FAml#jV_=SQ%ncUs%@R<}k&vw2v=ImCiu|c&F?d%@EH%&!9ayLLNxgnPQ z+sDNMjht~+bsiq`r$B_U;+TI`D*leW@wUsYu~k8IiI%TR*_hi*LuEKunt+G*f{wyH zxcSG?NmQ^LWG)5=6it*Y_fB46Kr2Fqy9#f4r2gu#>MsCIK-Y`Q#amn=sg{>#XA*u> z8`Dc_C1RulEL|~%YhF}r=_N=x>$`dh3(N_AmX!03JUOPFP(+mQg6j%1>)UIx8&UhD z`%kDd$13^W@q}h`%Ae6*$X>>(w8g-$ez5i3WF2<1FPF}yx%ZXMG!CDG?OLkH6wRUT zsLvf-8g@CkIw}}ic=puYU0AoWhxZpC2D}`^Xz71CI714|!^t6^fm3TU+)FOGEkvs) z#(TaazRJ_IJw~rcU86>z_yg6DueMH1M?a2qd~4^YaFvM$D#KRt*DYkZ`GCQKRpWF7 z-{gN$0Hi-p$_*5iPP|N^DEDG%jp)c>4qM8)EN%as=3G~T9UZxcHJ%z))(^8$b}&?Q zcQ<+FY$_yxnH*#>$Q0?y2=t zm1Bw_6cyp}tY)r94=BD0E-L}PiM=CSJ5Jp}mh(=`>w-C!S_1Q#7Pts>{MM@@6zBqIL$t&l|+S> zrLXa~&wV|7CeLvSjcK`&`3!vTe6_+s0Z53K=|2$fGgQDcuhnF%KT&j zc5}Q}UGfS9;29b01^tFqZ`qlAhMh0KuIwf;An_pplvu(}feYxT*2PVzKkq--FmEyJ zN+;URWMBbyd#rzNhs1`Vb|%KKGPU!?=z!|Gbm?b+}UBLzj)5O zqx2tI{iLAMd%FqPl?_ttKg>!2WVAvWhl|Td@e8nr|B(4#?+f)+ZylRRXZ%C62lZae z_WtKie{nCZ?D^?edpT!-@Rm{9&#K9Y*;U&;koH4>K|M?P+R%e%eE zW**Xz4E-pw?(e>sZKrRi|D@e8wbYAeT4Dad6iew7lBs$NDeeAP->$#HAVz5}x^TXK zXwJ3NtxDtSF96H_loe6EeQfOhuk?%R5E#^!bbHg>^E|8Il-nH^^2?4L_O7+hkzeY~ zQLSw1yzb^)>k}!gI;NBC&tVyUi@{k{V($6){?*PDU6h;3%2eF}n-s)wVA-74(K9Fc zQvt?5=HNwk@&fr=fEBkRJ8oyf&$H(E%fL|CWJaC71LQRxU@6SaHW==rtd$92kWQ-i zu3-KWJNJ)~{$V=MUuam2_F2fV`%%_YWIH@-jgQ#&IhUf?HwO;UJCGD{%0-S=zX@U ze+*!P_g{M>T?QsPk%}uc{^&2P9xAxhyE34;8Xh?ndbt_;^6Fq8wJ;m9TNC^$&vo%O z<;2I6Kp^%0mwBQ6ACCj1Fiyk%oT(ZAg3P96^jzGMv<>)4Jsps$Uvv zw&M)Do=47HAnB1zv;XNVYzHap9}yM$yNGtY(?xvS`pgvvohCVk%QZbd7FWD7^&-jU zSV?Mk@60t9*1+l{Kb39me0YbBkksn%ODbfzpZY@W0hnDM z*qGi{+hK!me#d*Zj_)r3|2c99{o9QHub6Ms)2kpESi$y z$QPQ{(5)f7XN48>rpqx8fcNoV<>CO01^^nMi2tY#Mt;nh|G_=C>$jfzyjgEeED#79 zOiPMS_OI4&@{D1V9{g{!ja|aTpJC^ha*c+U$769C>R$Oq)K3emJa#RtxK=NuJsBLfqbrQf_z@1b7a50&5P zEu?Usf%Il#93&e0VimKU=3>#5WR+hc-4s`JcvU>~qh!N0f+GHuJr!DiEPL5J0Nx2) zR~wg`0tdNJyzJd8`UE>r@($-0meAsWUj0}}3%X*JP#8}3(~ujcmaR%qj6cyqXywd! zCUWb+Zv^#?Nta!V#I@TeCYeq(E(D%iMk0QdH_Y+g9$oEFard3o67-%6GriqAWum9t z0G-soe9n;pLg4F|he=PU(^SrvsW)TVbI#_yOWHG*Q}?xY>5=JDZUa@7p97nQ0!DfZ9%)GT)}BM!e`!H(8L z#rSh8(KU9iTU`c7YYZt4>>ad&y?u==KuH(&qcT>FC7#x^FfnAHku&rjxIEK$RFdku zkOI3NJonKfUyIREhyDdTXNfj|a|26FYd`9AsCo7wN^mh9=4(2+3zE0QrAH-;APx?# z>c!rRUB7*+&i-9InUwn9zaZIUMjr6?%4bDRC%=K(dKQGo?_g4-ukXR|%=$2oC zd6I!Fn6kkz<&QG>l8x>u2mRKR)f5#$%HPAQR3bGRy#=ZLfYct>h4wE00PyH2eY&|+F&`R7@MFSzD+^>& zO{x{?x?f_R$RGtRN=lWj0n1db6xN{%Uti>>f7LunE{@3w9~$uy{64A>?^h_(mEmXZ zlrU>-UW!`CQdYHVwo87RCi2#`2w(Lhn5J=J^zMlG;;9k*D(tAL^9W`*NUaEQ*?$r< zV!%?=q^M@B;Tcw}R_$|TV45|d$xWO;+quFWD!n_RK6O%~R<*CXtD6&!6+02aIr3bS z93)1>VR2KmiE(OBh^(3a07a9TcvkpZ6A?O6J2^O7y~OaY(b_yPkBwDCty&@XRW#(q zty)Q}+7+;uOC*Fx1(201QK^!m?kH=qRlTi~g{?}Ck9BU%{B|wJqs4NF`PHHtrKw+a zE$19dMAh1ixg9N6I@(r_7nOfjA>b#08-mooq2_R$C(f#x zG_m*8?X|dVTZXDJml0~jY5-%0OMxk~99D@jc^ODZo>Ezr*ej*!eO(nj(et7Rj9ACp zT@!}}MeOCUyq=K^cxe$De#fLruHq8x;GD{f!e*qJfhr+lL^FhRoySK}e-X>NbPfzh z%8IBYScl!wu&lPaZEwPK?Tj$7z=)QmTJ}l_Jqr=bnOP*0Znf#c@VAt57lL+%aGhQ( zM+EA}qpftF5K^_Tg%x5%;jiEqEKfo+gOM7X+^)9bR|(XgjCk%6rR8b?Qg^nUB>HE0 zj>;$M$;j+!-y)^#ZNL^GC&HF510D3>O!X&fNq9-gtM_Mx}kx=qECs z3gm`u#Vy=NC{@8EOERrr(p7{t7inCh_e!M5lBB6Kw;m8tAiY!EPjAwx;;$8{P?TCJ zL8ykMeYF8mIm4jYttFl*sNmluETby*{RCl1Nynw_99`7e(}JMizC_?(f_+Fep|l)JtN)LQDQR74OE zk2mRgqSfL^oJUlvVDS>Z7!ejL>$O^@NUmI%tEo8EOI#ZrDdBOrJ*~c8E5z?9QludX z5*MjiuDAhS8_JT3-br0!Tr!2rF0R4o+O0(^ z#1>Hw??{g_l#dAA{{ZvS@=3(&irDJ$Q^v83V+==#C2H5v$ni`jGAUImmxD0it$HBp z!Zxb$SYaX(m-Lkp9yPVrmwy(#m@iTJ6}0UmG6#x{j7Y{9$BKy7zQ1c<+c%nzIOkmG zW=9NGML_j9@!dQyj%SFmjABhlgpSCS5cJ(R(ruEtDc$MG-qP}On!OjNSC~gASjIjW zjczsd)i_OUaScZFmx@c|O3HAvYn(bbtCxtZSdkJ0JW7TfG_n_uqy5MIB`oSBk&C+i z(qzXWdqU8l-(t0^B22U7~B1Kjt zeHLpZS+0F4-5pB6*~0Q-!g6qd9HV423$YOpf+9Tele(M_b!&<3oj+cuM7i31)b6F< z`L9oD(OxQ%F(hvni5QPGkDanPbf>g|70Ml@*dv5&b1{bw9R^5=2ySISjKoNh zh(@DY<0rM~t(&h=(nP&=9`R=h_N*nW2(DAK>G82yM2fap+HmTcsKktXGdpnPU8(j{ zb}AejctbgRP){ouELp7T#egJ2BuMcZ)U0ar&rU(dgv`i<!asN#-i#w zC0ay}j-=H(Mu!5`aH&z+SEcFg;tAzgRqej4Rft%Sc%)YeLsq?Bw`ZlyqW0L~5t2f( zIUcSN+UHg2@{1Xc;$^#W5R7=)L~?{FYqP|u;v>_{4P%K_qY9)fNIo}fg1C^k37AE< zi==Z|r2Q{38D;uUw`A;(goTMzZx<9qM~zP!u^gmC<`atX7n&2bUXeOFDcn(_l}sKh z6~ivqvm+uTZAIsLO!AIvq~b3kMTz)RghL-GID1%!sR`kgVj*hWi^RYEk6=@YkSu<_RhNYrpL!xk9x zOBmi=IGb2=T1{+`u8F`RQcbSO(ktUDd3q410K`RJ1#=!FlxmTb-I9?Rmk)1fksOh$ zmG_F3mzLjcIg1uCg?Xw>mz5m2dve5N$gE`Ux<1`RoFwIs6(0%Pq7%2bP7DhPRs7W5s&d;`ZbBRAD`<9iIrVhN)tt;9ild!q;XdY;$9UKLcD6UJ(n$PTq?6 zL_}rAxKyjmVbW5#c3QRZvEsaIS%jq6*q+(KDn6QYRHRP`k~a*1$W6O#s_K8m&DorNQXD+X-F zFKV%m=;Z|@LcdOk;-H8}I$mb1N*C@cOCJjOdmB~lB6jkHoD`(#=A+|XknZ%fg3d}y zvq|>SG>GR)%9TAS)d|>HyglMQp*x~-u~eOFMwG{lD;db1HN|x*6N)*Uk>;c0W4gH2 zyf>SZ*+Tsj@}ttYS+gE5C2|Vwlb#uzCCag3IpLM5UMWhkQ>PO+#gJZ* zk(?^_iRQk2Q-w>g-bm$QaYC1vjOC=%n-yL}WYoUi)zFV;MCDR)i1A)y;X7ED8>70Tftgz)3Czb@QZkeAM6HTFCFF_1 zCrCtP#qx^^G?*jBSn-Y};dR3^fp~~s%Fb%RA7trg30$425tmnGPGZb%BWA0F?9+L0 zuG(}}dpypOJ0U$*rPYfQs|@J1Jk@xOrF%xwzbK zZF30dmsm@&X3bURD`GvWbi9kp6<&u|h`>ZA3*{CpM>=;1$C^(mG9e}uN9vOLS(U)C z^wdO}OEe&?&uPN`q3wBbn}RtFcB-m)jfj^BsoAYcLI|!L5cS$deA$Jg07oQoR;zc3-6Eu3gIEM?i&7C3+zkUnpYEUDU~}%ZymDVlhXe zxO$1%2SUYkOT*jY7{w!$j~$cAJnDv}(mlofOP5QoQUo!_{H>yhe9!&qn853R8)ngBZYe}Xd`4!5KEQf%%yBcI-M^?Wl)!} zuI4;n2xjoSTvw-v;!~oSmla|gN+*K3SK$!oMTt2NWU8auEmC%+X?kANu!ZU3&K<1T zj;oDM$Kg3VZvtGZt^?Z4rSpc7nqD3wYAdaXojvOifhHUw`0+ZYQWLjwxipAKuwa}m z$cxhUq=Y{&9-^vtY)bAg2jSusTCPsbdJ}c#G*-i=1?3H*GU8K_-3#Lh)Ohty(H;UR zCbJ%71I(L((|j?(yF;avZ56^jW1yz(#*K7apHDqP{4%bbwjZ_ zj~>MB9u(~=PFxC3)KKjj=u@F$7xb5i^jNcEld(E>DO8oQP@GlcgsbF=o^?37l(S`r zC?!W?Jt6~BsPXE&O4WJ|YeZxxYPZv}Q?y4%o`Mm48+= zZ_-jWVO(K5PE=PIM>{9l67sG|)OeoWb*`|an^BQRWw?7JFKAwCfn5pECuXoAF2`+p zBeJ*)!%FTvR>Zi1aIB?Iu&1nE(Z(YP-mN9#JV%Msz^yWLUeY#&@RhF}9%bSq(K}*X z1i4q4sl`e>Q`^SxDj0WomxSojVxwtUVv&qTJ{UYsp{VgXj}#+%OTd!UBe6J%Qncvv zZxFPTijGo-73fCB=)6+&ROwb%iRI@~qpHH|RT)#IGo5%F**cE}?C5x|6SDFm@{>3_ zBBI_k)VGT6VGd7-;u5+mE}AS4PaO;A6{_g)5~2+Ty}?gqDeOWu*?T%3E0=P;B2Q&x zCv7K7nTW-0cUgeS zqPC^t_MMz5X{~t+&JyEj@naTn@hF_acD=PbcLc>)3fUAOO=&Zr;F^=tJ#Hqk;&QZJ9w^%TAjPRZs}5|;>>hBdpuQS1a>;r4#HQY zn@aRw7>GrELK(s1+^C?QU4(RdMLWH`bt|FRPc=FtxTjK`r*7j;zy;YI&Wly&+u>e6 z|HJ?$5CH%J0s;X90s{d700000009vp05L&PVR3?1fLy93VK9)7DiA#SWJX9?Np(DR-bQofN6)?iR0P6&vDR~xMC?6S z;l3hI-IFQli$q1%C@2Dvt-tPRz)El&lw6rok?4a4fTj>>A>Xrr5&{vsKFfk>6j5e; zcw8*49#l7AVd(%tA$|VAv2JY(WWR?;(! z6H%rgHGN<_Py+G{9-r=Q5EQ+~N47vM4%D)7&N{jjvPAlL$ybrcq4QqY6C*H8iuL?^ zV+3d?UYbk*nF2%#;_*wF9N7*Zw}i?>m?mqi079ZrOaA`=xPX;q2mq7UKG_7V5)aj2 z!q>jX)87S5LJGD#Wd{)~Y?ZuStzx9BjEv89%cCYih=n8$$E=kAq(m3jma=l%LIuaR zyVd}NbkOGK*PI#zCrPyXxWJ02o?YH4AW{`DK>5ayYlYjd)-8y@*jOv_YXga(cj!96 zq$m=EANKGOEuw&5>x_760dWHk{{UYZbpcDi$%V@a$bx-LAw?i4@kD&$ibbVho%-Oy zEu2hq`J8CFjcq&03BcGFB(pylf_X%nBI+=SW;R4{@7k~tkS8F&Lx1-Q&QF9KDm!L0Puwwp1(OkUc;Su!7QMZ9e*({3M8!~_q;+uQkLCh ztpfx*_3kjFD?$+;+_?h~7brW%q{1fONp(!?CjiMnHRSyMa1fB>e}2#73Y(%hCCr&> zMoO{l;DlrhnH2Hf3X%feAt07yWb;2b$vJ>{^84oyg|R5v7|=s#qY+eBE9VU8 zENDU3&-aKoJQeo%xXqH-gHd&t=SeWizrXvFV~gaG+0PiLSZIN6UvJkDp#_1F^!wg1 zttm9Fu+ahlIeNc!kS9ca4oQeP8Q)RwlMo5pWaFwC5)er=ylBJ$2oR?Ge^?b!6$(d* zz!3A+MZdf`LQkUP{1{*WP&sC!nEtbknUy7sbKXiMIOtDL87(mc2fK_H9n=#YdtgL% zOVMlk{N>n7r%s!|6bq)KpWYH<4V5FTc7h3;Ls9s_vX-W8pB|Btg(3v(;{y>in2zcX zoP_w?xohIFEn%pNo@IRDHF^D2X7J zLOB3vz3g#{5EO*L(D_L1>A_%xcCJyAG)+Wve!OBc-I9sbJmavzFyMXtF-#M;YwcnM z9M~mD`8mK65@pfOLKi{+gm>+{U;-AXjbH2ah1QX-$LE}pFaU%$3*!>PM{1s{3L+HJ zhMqkzn3=|BcmWf3m!tW~NXSCK^Z1X>2_yjYMGK#w&RW)Kg;u|Jfu@O25){mNtPtu0 z*{%JI)nv#p$=~sii?0aZv*QDCNt038)#j%%SS2?a>m&#qEzDQ02`mQXXQ$&YE_rN6 zN3~??Sy*s6_rysOj!S8i7#dkbd7t9~Y(aD?^@bEuKmm9>PS~dTtWjZGTj5SXhyx13 zP!>IXJVTI56tfQ7!i69u0wSv<6aqk^@hPHM(7Mt2$p#n)1iQf4Bn_XAxia9lN)&(0 zjS)RNVPxG#pYCu2!UzP8zitYNV6at<&Km?(N<>Zz%Rr|t?IjZl6&Wo}02&C_jEE#G zM4Rk5Ff3}?Q08&5091lFcZ?#C9D(Y<%8N1zM7sFMnZTJnboal;9E@Ft{c$YO3=O|r zLMo6-!5w2DDGMcgMi?My9KPO})!M;?L(hyJ1IEnVo$-M{uE}CPaB!&$EPZgqz!^&u z2lvmMl^~#J{PX={6F?|Elioumv0&T06qq7A962E>2_d+q^2Wom?f(FAPysC@f%wKz zfJC$$d^s?dWF*%A067vyLM-NQBLsq_LOz{fYKK#E=6qv{rokrgq?2`GcAmy39KOzGUJyz z`OQXku)C=K^2`EkmHWqAl_V?#)-oqt079RxvBIIMP|f5Z1d^%r59a}+5N$NTK$<%y@rL1I z&_FzYIKW|?h&A;x0yA2C#wCDeN=I`Ucq#>Qf47@NzIEX~^MH{DX$}7Xn#m0kQ*Scg zzC?nE($IM4X7ZMZW6{rw!waZ@d8zH^EC}ucPp%@}B(f{l>5;4mbRXJkV;mwCB%*kq zIIC{fQLlbyC|YcLCMRH`9uI!9#DWn~4?W}xgvBBLSk$6Ul_91vlRJ` z^^m+2OvU*5z!;h-x;gP4GI_>_K4SujNQpT7#~C02lWdRK#Xtf^V~&s3N0@mMFUBy& zLdiAbtU*BJiKFj6a7((PwbW*VF`$(D`(PER$bxSDG6ICiNd49t5RY;j#f2<3*-y2R zBzB)>vfv;?E4%?Dk13bJ`2KN-aFuAV`EZzIQV8FEnHiWBg_VD-2WLnl>DFqpgXC2(m(=V8alJ79=08 zzA{i+3jxnw7XXDIBoS`&PXv-_ck}#VAXrBboj-fPoQJxieC4^45J36;;cO=|(=(vn zNYe0;f^mW1Xj8g6?<1&*3br5J;;8{PWN(Y-oG%K{#Iw#OUfQCV)awIyNzahPryT{o ze>ntAcQ$&FjRY~PK8VIii^5La&Pb3J0$}Pj7&4StKgYH?N^o#%ewgtmN$?$haRzGq zNf-ORas^{C1M?oZn<2qA`*G`x;k=DLCG(J*2~MtXszg%Z2b0EHq!ztD!zBu8qU-m@ z4KbG!x276cX@v6Yk2p0cg5ZgdUF5vb3ctS?i0&o1`eC?C2Ke>w9R$={`CG$;0T^!W zpNwW1CO2Pr$g0foSfEUt4aDo57F3!pd`|OW6abCjN%WL64P+`|YoxrGQDje-wq9fg z%Hp{D&RUeBSikooWfT(v9v^JxrC=t$58ffz2&DWx;u=YdEQh4$~*VSlS1YLoF#0keU6`;t|$eT-&|^xF(@R6*WR%u$Pcsn!6I4~ z_r&~U1||SCb-u7&A*Kz#I>Rd)?{8l6B2*EsV{hk-5e6Ow>vi_9>7f@feerXQQ2oaf z5m&>AVsRy$+$3w!`M^R7L*vY3Y;F_4^Os250VE0G;}#|ZKzG&w72Tp_{xKAbf@!Y1 zjMMEh3w^z@0#YVIgRYEdgX^2JJu-qTne{b;63coAnfR=|Q4%Jve)_=$0R{yuj{EcD z1;9apLq1$PPy#R9e;(P%pyaz>_3w=UK)6HW{KTMTEYQZh&OvBdx=Y*h_`o4&0x4|y zU$KDz5|adYRwfEo%T6&NhgO95>p!eGhFFMsI`NE(Ab^Pvx84M$iFn-L}R zgIVYrL4NrV%P`BszrEzkpal*k;}BGJnieCDvL+`w7XJVkE`U68L+yCNil7=37|@qN zpm1*Wg%Fw4hm2xqA~j@uY}QyHq9EqD#0KolsJHsoD}Xdc#1%XBF{v4NH2d9n^O|A_ z1cY`N>q)>Hf%o&59Ev%;>ly$=HZ|w0nH-FSO!<$y$C9L!mZO6vA`-Mh`@hx_8qmUh z^vOhl0te*8#4y9j=kGXx!3ndTaHKC|i`E6QY%EjIR%#lltrf1aVgM4C^yeB0jS3m> z*BaE3BeGMF6$vj;laP(wTOqICT?Ttgi}Ew zEH^chw}=-WYrIro5eHcCJmg205;q>1ArX*Auzqo-2qc<_ee-98i;;?~3DHE#Vt#Qg z49uv_U*`t4%IOTm@%qVdk!TJ5{_+@@6C-3^IL#nRA=Li>7^1Y-MRsE?g#;j(@Ar)u zwXVz{)@G4M$%KTo3`m}O>li|!l9!ml=#(H9&P-T4o;>~Wie4y;GcP`45Jp2a0gh`~ z2@+aJoqXZ}P>ZJZ*BxslL1H*?$WK+GV<3Ws7sjLGBmqDLUp{w`qEH}`pGUgF7RyPc z{V_6Y)++QIegdyJv#B$k|^&C!4~WFakBHAT%JSjumA}YFNeRJSV5Q`e({j70f;HCe;CAPat?dK zTXvxETZEPgB%-{S$4jMwNbB#6VidrG;`f6RZUr({ym5;FSs;Y3_kc2+DM7b`1Q3YB z+`sb#Y61l5=wxCc6kI1?IED({CN}i{0C@0a0FcDGmGkp}G#f`N_>JH~K@D{AtayNg z1U+BO-~<`iTY1;cAt6-|cf;|9h+PPnigBfDt;-#Lail;XDL&lc5{hMZn)LC4QXyJR z6~9b^qsy1elbVv5P~obtX9PX5oMZr3xPyN8ScM5>SafxOE(vhM(*P!s=(Eyt3Ij52 zJB*QAe+5aLsYP+p{22rc(q@RBelf`aC@Xxa=A4X)B#9r7IAF9CfZ}O|AT{e4NMWQZ z8n0fmTd?2+=*bYWi+Wt)A38l#;{c;cGALofRDs9daU)%(TwPDD3}z4}{@z3aO5)0& zjE2!E11PorF~qt|qWpK4C_yKK*yAODECghiP-97il52ut_ROdbjtR zR)ZvrqxhUzOiMd|xKNdt4i^!`^NFhDs2S=CBF`uQ~kWm^FzI+;R8wj&BN`6D0ue4< z`|c3(JECvt_pJM4o45JS|KgUi}8_#Mju1VfRIcZhCuqR;m z-U$st`W$2oQlioQ~D-CgCKNRcE( zO!wy_!xHVF``|P-S{UCMJfM|EJYU^sDhfon#Rahd16<#K?ll8MpYoRg;8Z|RVP+wP zg%|Jd5s2lOie5eE7{}$WPwN76dn+z-1_284T>5`_0NM@+)5lxfGY?zM}w@3NR+7iIVhb8nThnq)<7T~JN9scJ1jDvnbsC6l28a& zdc^<%ksk5RN2sYHU3l;Jk#Zt}Y4>t)LeLK-{&EL}(KTP^zCb|f8e8<^8)hmzVPLV9 zL6O1s+3WAIZ0q{;l%rZdptWy=+B}c04F`=3;D5nu;F)2rt z=CX#7AhP>88ZZ!V+OoDOrlJG>7>HfSQ(^Y-L>?4=9x_=30F9uP zE^coN6_S9aUgxZlhA0#YJv?DT5iOt7s?8BHB-#(-oB}9=Da*&4j!{G)Ab*Sx6OR7Jzc?-iu2!?(8q z2-^t01N*>U7Er6#=N6?v$RZi@&LJfw3o!eb2mqLZ&mN!NLPG-K%XagYXbDQE#envPwa@9eA7t z(t>hDk&r|kV4q0HqLJ;`(~S}kCU}|a%wS3ud>&W%&4fzOndJ1rN(9c|f80{aOeDw^ z&Pt$)M3AxP6m$Tx5a)biC={@>(_Wbb7dAvQ*Ta!o2}VzEZQvyn&~xZ?eeW6w9P{XN zg4jtYgvlKB9buB1Y^&ccqxr&&C;+TB*RD#zS!OIxm(};i!HEwD$ik#y923_$U}qaa z^ru|l42Bl_H@+N1D<(N3^Iy(D5`?33G4Wu!%^@Nw?!DUGKr(MTTXtY3~4Slu1Z&zig06B8;kDcjxhsK)IJ&?>7o!QhDYp z6%zq`!Qe5M4Ag@H_@6lqa^Mn2iSZdJK?@KsP4|VCp|)$N)=uy_0*dR~1G!ZN?EWxH zNE@+VM>znhVt;sLXaq-z>&b>W2}By*Z<|7&fGOmo`6+#@54S&oK3deFc*^zuHTnOVS3ZSrCgv}x$oxZ)~ z-Jqc~Pk2(2K!ZmA0Fd*MnMIN3{K1eYBFfXa*4$!9f-*&(4}4*1Xa+~vJ@OKeJlsJa z=jF*69kT5^jDTPPVKi|$2oOxkYbiNqb`+~JFg7|R`#6j)6(UDJsKN}9A{)K0-DK)P zm4rgZEuWQ7y2TKLH*}u788(_iOXq)oSWT9pAyd{e!)WwJ@rZ#NWgriywi5{k<$@!> zoB}FPsrWtcMJ9=uQ(`>vhQga5=L}3JS3i$T6-@*ZpJNon2mut9vC$N+LnhD}As+{( zDMj0FFWAL|B3TH(Oq47kM>9Wljdf+IK0UFBibNK+^?3ur1O)@%PHh6j(XKqyWR?{v zB%g=ZSoLPPnrh<;L`Z}s7}wjzL5{+}aC+s?A*&x6t#2F*n+-D-t~peK%nA9(4IA3t zo5?Hcgm=zLVJw9-io#)1=-Dyz7zseMu-}hNq=_8Q-$oMH6R~;!0GNg%!&-iQoQRCg zoBsfE1R;QxB1))z@yJF>6NNOJgV+4RV8JKG5UeR91tb1rK!624AKn3|EYXgP(p4bE zpKqMH!tb`8J+e860Sn{T2^}Q&86umZ5qm4`Y`Q8Go^cUdw$?TGn zL8e)VOM@o$ljMXCATcJ_GzB^*&N@h)8V2;@pb$jNBdp-5Xs`9o zK^;C0H|Bf7vtktoJ>=*?C=<^;cNjYqk~3sK_X2>iW5@NZy%C7Frk}m#0I-LN`{N?G zMN0*490btp4&wFJ@N2?iH!lAG%tCTU1?|6Rz;1-6r#hSjC}&`6&+iT@C?MGj?~=e3 zJQ(T8l6XDw2Xv!{QLNXNV3Me+@q&~H z6)a5>XD-jK0#KcR+`PCE7E`sr_13WffhKLK0L4*KSCPnKB1wWNw()gy$k;o`(1J^1 zBd-kO=|@Z@JtujjCL|RTe{UffLqIuyN9zdKK{Qp|-Vi~|$g?%9kiE;xi~&Xfg($JO z#gK(Sw-x-fV(8U?S9*QPMG8kxEO z0JVz*9tKW+a4bZ0Q@%0*CtxrdXDu8Kt$CQqg9x*!SyjmbBC7yT9G&4nOwuZ2(LYi7iXr;BsM8i-jku!*l>g4)kD# z8f`8sY$;;mG8UwWqzBt21WRQueKBq(k3#F`E+7L*Kx1TrwRF#%6gi0<&z#dsNtIas z{{X)kD1w+KYRdc8OPQdOwbf!ra#WEGV(3P}mYz6r3KCE|9_x2M83j}Tq&3{)O{VBc z6ET8%Oi60M227wSj!)+S@&KV9IJY3G6GwIJk(}z~@=xakLLC@vQCRdqK{EwhI8MD} z?%#{708|1AbrN~r0c4VL{7yg#qVzS<&hUc5t$2IK6}Keq_OOx|h?iAAToDTc6ijgX zUPy~5+Em88^NB>LvNCu3z>b}gl=WJ}MFL%?VT_m#O}TVWt{H-edM};evTg>Q6PE)t z)6m}AP5O)BahF{DwVg)UtQ%nktsy|-boZ88VA38G$ci3@6JO;%#&{~ z@Z~s%OD8@(y|F5ys6+(!j8wD}eEIJ2BGFh8`QyCYG-yh7oDgYgvUlLZ6yE~_3!I5j z7A31koQjw%cjyK&qI#1!)PO`O!OyO807s{@9C3|F1KK4#RYhmWHAr3lZX<8*!TI!fSOZ&&O!=6%fC1P zkfzCe3)b)(}7;kwps)ub*9e|iuzX`Qg*Y?sfWcj%E7$P#lS7dDhhMy4pp;QBh&jVKs?kC?#URN7gu?oF{@^l9 zOb#aNAag=bhmX`^O{&UybCMJQJUR8eP?bUzc-{K-h$3Q#afkrBh$asX3M+WD)2aJ7 z7BeY89r=6K28kwipY|~72$gN|ziY^DHA1C9#lv1;w&M*_Ap^Hv{hZ!WjHQtC`NcCwp{cJmgdj;(164;(B!)yoY4Wc} zC7VJ5S&sO`GDTBJ-=?8$5N8)Q~bfW4y402%=|;$PyrIcFZtf zfP^ZIyUD~*+3nJGo1h5Lu5t{(NYHfu02Py-yYf9hj3V7)Re5?~l%4`3cQ^n)MA^Ym zrGXoLuvt=&k-!;>u^|d-y>O0ev#_%{pl}d+7}_@)B9ouKG9>_e)%WKJKu|C#AMwH| zq`=Cl!+|ja9uP#=wkK#Tu)Z<`P*!=c{#8SuZv1L%@abQ7< zl3I`6K@5VTKzh2?2uhAd{{YN409yu0UffY~g4*AI4s4NSget!VX+m-C>HK3?tOCQU zz5RjBAG*5T|5Uec^r^W)*HCYtgzS$IPYlOXfWQ0VJG~C#{;=&@zb$)xn z5`Y3tf0<|}7rEyEK(m3b*BDxg7#nZXeCHrnp|&)t334YD?Bw~-!{5KY7==MLt@jxK zCxHjg#pKhn0IxOtWXvHYvQGr#*CM1Uz_&lQ4pKz|9r|Nq(hQq@j1qH0BDjm*X=W`> zxjmyS$SLSC0g`s8+_vvqIYvNHLv4r|0_plG2U<`II3ym$2HAQ5Gw zD;&?q&RJGiGM1t|U@UQ7@&ox@A<(=Q7*PrBF0L@ z8f#`S0*EXhyx@i@8zNcf>4L($33-1wkTBT}ez+V2DuQFyz4AtgnTfe8PG2qp!?mqr zjtMX*(eKCmn+y{rr#I`7v;>S)h8Y%NldZ|l1d4&d8hJi13R-SS7m!6n5)2PN#sEn2 z{t8DoiCv@;teziS3q$7pdvTkkR^Y{P$JmT&rZG@5css#~9%srNA_N!!zW#7f*rW_T zyk)W&0!iHGBm$_={k-OKg&!7e{_&WMHX~7@esGlpK;y&5t`Q0Ce`e#1QXzpwrIYR8 zC#jMR_wR#Lh$@I=@9~L5$XTzY;O_xx4Nj}`fvkBd)}}dpf(!n+<+*< zBV5*Zb*XMZI6;f`Yv=3M4`jUrzr3%nM`yXoJ(|8UPDGvwh$QM4@1ihzh`v zBoI``c`+uyH89DV6>inPPkbdQ3x{4G&OnMXOmekYyGc^tPu4{s63~RczjcG7ZGnX5 zUr2IR1+IrW`Na_+ic9m&W4w(KI!)J|)-e*I6@1-&=M@kHC_f!!!7(&OJR=OrZIV;l z_{h;Bj6xH0j}r_=;Ga%;#AAX?STom~#70IXi&rZQB@!JgoE1V6x}UG_CP07$?mhB^ zMQ&N#<06uTEF4GPaEx9_SHoBaWR%dr0a4yuk}C*7JRb(Js7I6#o+GSen`0yyi8;Je zC`^>Ic(_OmH5WBAgxR7`d%M^4;)^W^4%cz-h6Uz?TQj*Z$Q=UUnzp13U&nb6D9{ji zviQv{W)a|Z`o^eHRj6|MxPyHV>|XjW5{Lm?i`!h{(}qP=Mqj;S#nWbr53z_%0}FRN zPu=B=pb{kN`?|oC5yCCjza?WNFl2vo{y`|Eg4 z!bOG?uNVSTB#pNu4*hWw17Uoah)C`IHI5Jg2oiPu;xQC3AzWXK2&j@4EJnXrgh@fP zpBXY>CKEyHiVzer6&@Gu;X#6!Tdl9li2+L>4V;cJNSZ+qJp17@7)nTtOweW*U@MFp z3m64=fuaf*kF2CEWv8-4KP0IZae&I!;sA||PFBpCqhGtRI936+4aOad)(JwJ;0!qT+qW-pwi zHs@l`IN?M}5l!V%0w#~k7UKM(f7}hx&_e}2-wvf`TXK&LIU7?dVg6VWRwX~VrImPF*r!^fs(C} zNOt2WRRrA={$3&g7Tg^X-T z43Qu$d-dlb5=@r!1WkE!z0v}FR+{v66Z59;!kYSN(54Yiork~A@MVSU@1UA zSM!g}99o4>=e%GnY%dJY-+Ymr6=mQt6%30dP;lSAL<3hX&%Ok7WPlSt-8jTyZNo1W z=i4PK8Pe<5>|}%hR1Ry2z>x@&ewd*l3Rhlu#OIVINi5?bk|4kNyfF|EO9RU!P=V2y zZeaMqq6dN&Jg>HBm_mZY!Kv>50C-4mJ0wo|$x}9HMRWUob5smiVmM>l42j~Y6tx}V zFrpzWYoE?QLM#d1rHn*$gdab~I|SsWi{lxH17PtUnQjXqfqCG6xZprqA>$)}2|4$UcUc&)=+p7> zh6t2X+UwIG0tlLNb?<~g5|qI8dAwVPh~D$d2t+gM7#8$~qb$%w5?aRc-7x@#0QzDe z0|~T)-V$KiB(|`b1tJdzu2S?sfhl}^WF!-XPrqCfBnCSpf2fmwwm?m z&45b0R7`qeN|GkJ`#3?WWL_OdubdMRYIc;2NTQgMCwq*VcnUJZ%=6Ar6JljVe(+>m zK&rmR5=Muqvx)+evL!+97z~^#4tQToNs$D&kH?oP*8qs;xykMmNoqGZNsIzREA1I9 z5rl?~L5WlXW=ow;NMOZ=T77aAkOE>Yz$6w8rtI|INW_C7WNY{QuoXKi8ayfUV0O7_mKivB4OLp(*Py{W@tve z@Tw#{texVJ1)H8pgB%`|B+0$;&Q*cnho9~^z(PedE7|q@f#%&1XE-R97 zibh(Gs(AsCCuk z4A*YY%Oxs*CyzNm7Em8~zzqsiv$>ZW4$wOC$JZkODzs&uTgY3gKs)i}%M$2iqnMnT zvMjI@x!zEKq$tMg0U8RAcCt~15;9xd4ai_6^O8%bm9#ZKycv;hIv%`#xCTomUInx#8ygbY700`Y%3_ihunL}{8|UP} zn4K4=NP$}Of1E3`~)${xOsa43h4?Fls3RaqBgK z5ikiG^!wget70o}d}N^p7MfY!qbcL_R^v&CQ62Y$fN~vqgBf0qA+KDWu1%pX@`TD# z3Maozj78MrA{j(%zT*h1LLW!zoVrBOMxtPt!bAr+JL(_2WK5N`o9sMfRHl;n?DxbH zWnr-I#xw>923SuK=O-%xB;Mx&LWG7Pe)WO}un_d`+nif14hQ2a(UX`%Uz{dD8sL_& zYc(LyGrU6die;BZNrWU7MxW+Q{}}6Fz^;j#G)1 zIz9Sh0TDfxPK;If5WlgK5V1>5{<4=5Xq1|qDkT6L^!upDIcY6W%ZynHArzT9`J9kq zm?Io7F_votbZmVzRDWXMuMfPiZh3`1j! zcH|-GDo>fnh$yH4u6x(@gDMk3!low%lF4DQEXxU`kpu1Ek`9T5zf6dS&{v+bx}{-L z#QokV$~GTOVCJ@hAb85M^ed-#KYnl*1R_ZhsQmk680Uv#boyn9Vj#g=6+K}}DOelf zfdI-Z%`$xCR%0%M@3u}vC$xvh=O7J}0Wt4&7=l%zP`~lU0SH1^jTr*SIkptkiUChi z=LIkbiHW1B#Hvyw-&5&$fnYbu8Cgb?+r&OUtQdhLLTn%R0@GTC&-;-m?6I$-ii)HY zQ_AGwK)6KC;ymQ2e1goFY?CAiI9*RzA}CmxkWT*q?iZ9**kk}83zWwQaUz4fei*?p ziU6*~@a)S7QPMAmE@7#)eK4e2ydgfAks+Z)6^um(OJ{t3u_l0-+4XUVkr+t2w~cdH z$qRr=1@_iN#0Q1*_VQ8Gs%_o@Adbj}4SZoyB!nI#uMFaI%cep8iz(yvhoJ*&ng0N|2%!~xT>a}4l$e14H*MfR zg6nQC*A|tl<}1!J&XmX_+3aHNoP$h&M72_i)cZQ7Lk6%n6g0O--vf(F5WY6mH0vPbwcdV;5OGb|W0A>?z2+|9Z%#=tCBwYS5 ziXu@%wy4O;R1qG->xwi2(p@v@U*X zRLZIDki*7kSYggu&gTeG(XEV_Lq(;VN+DA!Ns^Gm_qX34uxr<@&u8!J{dyiAFNlP5 zkft!s;iW})Wz*-F_?=!IobZ|A2gPDm`ChM+#2lI2S8A76vPl4xncpqEM@0Q!?mQbW z>&;waDdfi4h(}Jx-40(4K#?%+`u)N2h9ZM5_9wmYH;b#{{3rZFhJv`8^=dw#mGIbryrjZ0Sts zuLh#aPLtkPKNU;(nAZH7;@HQM1Cd?oe`;kp(f5zsl_wVn>F@Rc5r9F2B(;0#4V!rfx6AyE)bfwYBiY-i$b0=!F@Si`D!c7>bB#k-Kd1hYgt4i<{6OW)^LfWp z>VHRRq9^$&tn04;h;@=xfa5W0O~P=(-M5G&4z-y^4{OJxMlf54Qdvp_+R%2f!i<>v9kb|f`j~g;lr1l%8A(wH8;;2xT8N=Z)mrS&0R^^N5G;Y zdtqZ>yiaO1D`I@a^<96qbHa_!S4T)`CG3Xblpk8v&;Z!nUhmlxZy&1kPnm#HldcA1 ztn8@&zFhI8g8n{F>9#Riz9oQ2^YHBrP{#f3-y_OuYG9$0f5sGra6wx`K!}52Ap!UJ z4=M0;y`~k_(53fpu=#DZ#v?w>0k>@jlWzm{O(QIlI=W)bPP1gKq-=-%<99=$gBark zj`u0LCm(+lzoz?gLP7sEM6NrB=T%ngpVR;`Jl9oj7#%-O^|`bz^gz$!IcP<0A?Dr- z@=WN&xbudm)YHfg_8?Bp%W5Dv8)G-z$7#uZ?Ks^w9zAkaYSV?FkEH~@Z>vA=2!WL^ z{`e&W&8(`v6y#1tKlSMN{k#YYO7QtPuGxiFj0^S=ifP21N?!XXt0+fh{!5cq+wgq~ z-L~k!+#c7VL%KrjN_?2xTZN>kH)x-eqC0#cJ+flh`BhGV?dxcNy%whS!D7|N{{!%V zxi{~Rmkz_Eq#vEzo<%Y!L6_H-3$U&Aq>BwR*w;G$DGKzkBRWptt10nr7HA?INiZqQcV7LlH-653l1;j+`TH*CK@YG=Y zxD2-v=tx;g+%x9U_ya9R5#hNNOU5s2q#stt*!rM_^>Q8?R6+yx*vU}2o zcGIE~K|Ca=_aWIf_E97cT*-PWM+)@_4;uEIkC9H#zH$2Ihz|X-gzEuTiS2bZ?&Ri3 zobBB!%WPokAd^15o}P*Ja2`Cro^M6{oqJ-P6rL6@pLZCgz0y){|rax+nb!p*I`NY`=SHPPv=j z3BGWyB}U`W9Cbab6nd$Lkg%S6V>1hyzds*Uy8?5yJYdq?WL|h`i&$;*%FMVtj~0dS zTHf7nr-dq@;(w2BxU0$bUaQBz6g3Kd#dFw#6q=Gh`p3cl2zSH0d=!5~p^*??X5W-T zC-GuX+$_?OoR(|b%^>R#9o~F0rT%O4#8r9mLm*DCF~J&vEurWoSSm=TGCf7=#^L`1 zxXk`_7M89J8Lc_Fnrz@zrFrIJM`k6uZGHV_zR-&;fi-cv%V%ZO*NEv92T$JRXSJMm zO^inPKlS)XQ8YIH_UNZ0NG85c`)7a<;AZ&;1&Pk+`-giy(E}&go9ndZsQ1hI=@g`+ zL$1IychLV2W%{QRs^(2B^-o;JpgrJiPt6`kh*ssQXH+gke-{BXo|>W-cXuV4vXog6 z>5{`1#EF2X!LvVe1*83+A@0rFIfvJ1Fel^XiR<&y?8PAK8T2;lMdGsPC*E}n9^|@> z*>qZqK~??2QR@PlI5r;tcnN?dmnztO-Qr%7C!92095^+V)1!DRu3_uzJ9(uMuIp|~LTIaOi|lZe5( z@_q4OuPaW=jE`XTn1xSt+LylvOl$|!!NZnQ7^?7_D~mj0sV_8leH<)P3OS(XY#&g4 z%5teK{y!sA$w-b9?DVDrV^ICj%1ZI=H{`92-7`##Z4UCF`51ljkmTH~q?aOYaxE+T zbRqcHqI+U3@bS_d+}gT-Xc-mo_{G8QF(ZSFi$|1Yy^evsHdZ3)q-eR?7#Cjv^XMMeKH&_I_pt)1pXH=a_KvyaX8_@t|r9P?oGc)vlgG&x`-(wSxaIrdT;ZrwfI4Mm5>s7#tDqD0lLn|}LUX;z)s@zIL4UHvuN?qSg2BGSJb z+$Dv*?BYrquQD(DZ|(yh(W4X@6L6#MklysTwU({S#?^i{y-K}bzT+O%QE0M8qL*lB zp?^2G`{0?0@@N`%4Ex@)Wd&$vU%!wP14R5Y*RVI*__{5)^U-dwOgmhusX`%u@U>xY zC|t&@)pL{Ma~&~u{O=NoA)DIuGj0ifRrcvtY@w0ZW&ctDN-dcD*F~(-p9{9zFc}4# zTs0VTgPEN6tMoyE&c$*2uQDZY9NVuCu0Xrj38aXx1C9Q%2CL2vlvb%xolp!DYBURyYK7FrLjJfr}L{lv(zAWkalDFRx_T zJO?jdz5Q{7It()$!4RWr`ve(h6&k4Y)eme+thp#RXB2T(^o^^kLCYb);j0@_OmKH5Avp@2 z?;Fxst{u0+I5OMEvB@X@gNvg<|Cue+ezs5pmN+&t1?OU7CKOqj`i=-}(}bpv&7*81 zp+C_}bzVhrLr9+(@8sPe@DbaYBfCo%kg5;=EGhrGsoyF58DQaEjyJ@s-Bi@Cwz|Ey zuWt;N^;EUSOQO|`)Z_kvmxYZ#!J#$2K0ky0B8YV0tQZxWPtp;mat*Ke7{WrDyKYTf zNk>b0-saB$Sau)E&vf_kjy4$)vnSSWYMc~$FsVij33RvyS)I-6*FU;n( z*ZC6t=iDaK=-gLL8(aNqe0u}THNQ{?v@`vX0`!8A5O8=cEejQ9k{`^+!{Dsz=v~Eu zGiPCEm*Y}jfUTUJb^|ft_p`4)zWW^Q@*%~Nr;&=H#@~>e#65I~)9@28hWQ*s9ah=@v5<*Wpi6%}YmndRIYc0+#!KKBK6L)NHYD!$% z4@L)|a)2q%ie8{6B}pbDg|*&&_hT$(n7;>QV^E?ypMyafFsy9C=1345k&!>WHNbMG zJ#>|fuho5ZnxpNJ5A8Vc14jPO{`$0Mu|t>i*bRfv5=ie)I?+CK6ok=7<+b8IhG{nq zK~NrskLET0N*r}okPc_Myf@bHi9UH_StH_D+8<8paWQ1ant8B74Yp!}hsexL|NK8d zgUsixA{-C+OkDax)0cj#Z^pYDu>qbCs2|v?08uX(GC^HA`nwB1M|?}awlvCObUcP7 zSBh0tjpF?)&kwJc0U9YMqo**$AWCb0+z@3Zc6)Plbj&9GnhSLxMn*3U z+K)zF;{B>*QZpKImZVV-1FbY)>qAzTR-(YS!L?qS{ym6BakX0(?~>M{S?~W%>iu4B zyLhg`xrOY56lc)Vsw_TZHk4}pq&W)qv@MsEoeItz7%)9#!%^HAu*QUAl=_ba z^beefjScB-etsmHj;U6?HqD11ghQAI@QVpDGDMLytic=1lhs~j=vcdLWa&^7fM)3M z{O|m76aiM;IS0zDma`HcetcM{beLx@ZpH`XRFG*`zVOg&Jml;tS>2>y#XmTAq+uJ?O zK*%HW$9f|%?8G+L-dwYDf>j0~EYx@exSS_1?d{)Plud(4wuB%Jzl5rn&cb0qh)+{w za=V*Hz%lp53c;U3wocNlX+YYOAYZn6T3-4TGUTg3({M`zQ^J<#@VU1P|4Q;e2u)3c zg$Bg}c0&wDm_P{e!7lF%0BrCmo4$g6w9mPwa7zLakXd$Wn`duoZQ7ru-c{_WzMg?D z7VSuiQh*6m^``#;O50#vH(l;#UHIg2^|FsQ6M_&dmV9>nKJ2Ab%MBkG(O^QvbkGeV z?7rDchZZ??ng;0kCqIk_`M%+#nlymua^U?_fM!}lKi zY?Y;Q@=w+momU4eIqWedC@g^ms>{rr_PGR)TGg?Wsfe7Sh-iL52hEu;c;$4}OtywG z)u4^PM}+B>Q*fWcQ>S>3R}BFx!-S6O(!TyaM}m#(#EN6xmosgo?~j^FK71kszjyAv z3+NGC*SU3ilQ9bKPnaWhLPVUAH5_t=&6D?ch%BJ!iQ^T^2&R>MXhMsdQo*%@)G-fyX3U1=cr;o>spOil zPU`;vrX2E%oWm+xoM%iLBZ7Abp_eLF5RiKGa$LA^X@~eeu{q!2Q`^L5 zsaXetqfsR{DcU;&RoW3N2|Kfj_&@HKH+b2dP6%P>e~t)d@;=d63_}9ES zM$WKid*~=Tgc7*41fWJ-e>(AXRPpO~V}A-Y1E5nrDe-G0O+dxTlmVjsEzYP*;3HGi z-*L0>3d(cwDt5Ui*S_XS<7txWo7d3QVd&F$9I8)5P2ErYcz5heTf~K!Ta1jxBfo4e zd1+dhjWJ76uXeZ)qHzQyh_ps4Q>*6uObF3=Dh|R%H8F$|um0he+5>0)=y%D=NsoM8 z#cM!bL|FRJbgDy3K7M5#10U#23`D}fAjDi8s~jR?(d{2Xc;mgna&wAplPntz)5$!` z=Mz3^8Wvpr&6^Iw-SC_XlxI?<* zXmc;RH%|saPxv2zG)Ti~W8)57<7)z8-LKa^awKV0!a1i|**Y<^#`a6#ftEMyr*^?) zZ`rjLL#gn$Ds~jnQY`eQ-l~s)W9zh{A6G{dA0|~A;wSt9KAn=_PsVYHHnIkrdx26u zaOIsd+Q9e2$u~K<2i(YgQy5uvb8*`;)Zy4YkrYn&VCqdA^x>exgY|3Lo(?6+CG}rk z1fiGb6dZ3lv+4Vv#)6ro#)>H~adLtCvT8^fYv@QY6I)lRFv+|RGFWQhwTG1ep_zA* zohhg73$l`K?ec$Ra&|iaz*u2i_DJgMyVs8}5!j*`tgz{GpRJKRa8-@?; zS?pSq*ze|x3_k$fo z7zVAg423)x5BaS8YH5JN))Fi$vFt zKa0-7kn!7xssNd4>${7&6#Cm~A8gSlz&Wk$et5*94*urm$l$b@=*n_#G*Z$zc6JGT z(8>Mk!sXph$3XEf1qqIB6xTOAOzzbDtI!Q_#12m!2uwO57(sN=6(MUhnS%|JZ5(MS zizVZ2Use%PVf9Vd&Z z@GN7Sm&?0B(oOg~=0!w!|HWOJ*ujI>n9&A0l8*r-x)#iKLN#FF>dAR-;gP1J~KjoW*$_ z6~V{^^(L4Im49a>CkBbRpzlfT%mPw{@zW|hk>Fy2O3u_;s&tTvR{Ty2I}fTPx_@`n z|3dBRMsK)}&9&Q0cnr2H-ei~WWtEi?FtxMaanO$V&OYn+5DJXCKB7GviOfVs+fV*C zt40N9h;rog8&Lx0Da80sat!wvi+<+jpAnmW4Qx#vm+DJ1uKb$RXF?W!N_>>!0}<8q zrCV;ou!duG7Ut(s5q8c^%QG|b=hC67ZhnCo1HQkfACtqxsycQ^_cYz|4=aC|)p2ky zap1X&eBuFx7Zm&yjA155axFK2sN-!1Z(nlq(a4SPu~`#b{oi-SI3217d-1X88-MNwpD8vVS-0cpg zn&M_o4uvdZ)a|!;VV?p;x1)O*MPdE(w@Ru3h}PfBb67MDKXt+Qs!on-+(4zYNa<+> zT?2}Z>xaeXXe*fsOAZWevzRAX6DU8Fdar2GvV>2FP1}LZb z$4J}~cGz6iJ=c07zC{d#xVt$ak5L@7wwEVOz3M!$iN#7-uLMMWyJ5d7c)kXuhZ6Q& zeMa6CWM}UU`((;fC(Q(V=?Gp(xM|k!(W4ZAgU4u0Ow7xzK0i88s7@vE=hf&T~iFPZr3{X@mfy>53?Zk?+q6K7X*Hpii;8QC@z zq)Bd1n0=)006URhT97!;L_T`E@Kel*yx$J83I878CaocvR#>dxdMi@U1{aEn4(n_A zLMbdSH-O+d9l+@E$m^+%W{+1vc@oOs1RD-bq%`DgbB-(%GT7}6)o~nrN$TH6{s&_M zF<>jb*(kE;%ZBN_5vYgLBp+rl^A+BE8SL342#W&J3HXpkh8o*wY38uQzoh8a_(3PY zL6rmr5KPU95Y|MC0&!dfV=R~lz1sFN`m%J!s09VMWREAY(EER zM0s)le}EGMsRJ1MrL93G2unyh&7uJbw)oCj%rElfhFA{N)jQjFxpR|E;L@@WvSng8yWFKe1fez68JJIo>@WD~m{TMa-$#sV9T{;;2x!Ch$ zPA99#@XO|42qyO$?flwxwoIg2b!c(f5 zyc2VDP3N@vN0e>ASCO}aRGLcp0r~fl#W#9Qd5#*n70$0}$R#=NqF$v{SwF$&Vf$eT zk!nDdviOuZZ;>gu!3KIxbHUu z6|Yf2<)|8J8zEV9qgLZ5Xk(i%cckw1LH?tlOZ|q$d+|IZqVC?)6yC{ikgTHf96M~h z4u5(anx3(ifEa`72^hDX=sOuH6~o$7V4_fjWvF=JV8=} z{nGxEOoY?qZypAkjFe)eFnLfNhSrhYSwn!8+rI;Hm)Z~a?{HHcLW)9m=ley|hMva_ z`IP-SZMiN>DFV9mxgY^qe7n0Cu)vn)$P$@ciX0vINJsqn)&W;u#i4#gt=khP6qc+Y>vx^ zo(Vdh0kWyF{~R-v6<+H?xf)}df5ATG3?Ra}Yx3pveY4#A=}i&c&nZV!J3oY|^j_?x z{Yy31YwKs~aAluj>vQKTPV*p8EpgT5UMGhZotAU&GpUHTX6ru3zWmpFkP>>|e4{rA zApS5YHiDLM^vVGl#-*{5h@~~!^N@z_p*QmJimSX>7n9qP*Y{0E&U$?n?l?y2wZuJN zXM04PbF^HC*!H&-oKGr68z;!tpmad^d~p0Guih*`_Qs>=c8NyP&Hku%U5!O}!P{_) z8x9fn0S9|YG|G>P2P}WIwZ((gDa>nGquU8A84qtA<;QW_IHxqL9+p+-)t;PXpqe6F z_W(b|LjQ0{lfCoh-XM@o&*{x^@Fr0^XIb5s0>tkh_4hHP%AVn?i8kUhMNST}-NnDo z7Z*c;8amf_J|A?j?{*i%3m6~TG z<8^7Ur)rNd>QLgKa*u=oFZGea=k|aSE*4? zn7j_6LeF4*Z;%EwV4|{75I}7j)P9ro8Nz534=FT=n4ePm!lB=BA;8zO51R(XXe?k87Xsmq-@)O=*E(#dQV)Qgy}WhcEPs@J8P4Myb=*3Vx8(r=R9$ zbr%oHg8$tOxPH<@#bUqR0AtpyyeKdHaB&GN{mzh)Zo&HaLP_OO&a6wv1?`1j$Xr{s zNO3B*X5-I0yZOX#)m8g!at1L%1B8rjH0 z1Kx@0eO^P8}4j0I`;UHZf|d0b^x+rBut`yZ}BjTH#EiZQi7i3Z-8N(oV_IcIRA$@;F#$!s0y9 zOsl?Psd>nwFzoU=jW%Aid$|`}d=K-NM*aF9AReS9tL!WwhQ*^f zMhmWf^Fk1{8@-D%ipMqoTTE3jf~|6ZcMS=J4eNOtP&F;9{a`COtFBE6LpFv8Cb=J9 zZ0-rW{OdRXNyXRM%o}DJ4_K5U(6o2MH1*gJ@x$n_heCv_YK${QJlqZpp>$ zS~-~sf>5Q2ajfC22kKO&-7hyQF4p1WRTkn)AwrnSF(A6n)IWwT$uhvsg5W*SL8M37 zM|7s9f3s6Uc#87gX!%l2kwempqnwtLma`QFTee4A&{t89!1c+fRcqMh)`=z>(k z+O?(;Md;+>aQf;PKg4U`A`Ji9-Mw~Pkp4)H*21%oDKGo?z{#o?uB;V{ z#F!q8t1#ip)3xsKjlJPd+Ll;Lbrh!?I8MMveVctBO5Urr1MdUuUfMZ`PNxaQDIbu$ zffJoaXWzlXBIZtc8-4@=!fllP2QbQshkbiwX;RfG#>h!)TPL+bR0ula42PTzc19|) z$Yp=65VVuNDqxG}foU5@g?Nt4JT=tB>6XIJY_F7u+#8Vd1h%E>TLStg;j}jk{0ac; z_=jIDT_TIyW(m>N9PcJS$k(ody9)&;6PexyepiRrIiM`x=)w4FFv@L)Y!atKQ%(#e zc*)U*KYbh${tS@OO$Oy_sbLU=^UFMdjLo+`^W+%Ej!_ep1FQg>6aEV=yNfS@zL2Po zBW&_f(cO6oC7t{gQa&uSm; zH|W(#_sx1P6%wcFXRDR>@%M;mjg7r0sSqDtbc*CuAB7Zw1S{T*PF&}yIglxnk^XO` z=*o`v{+C&wJSY_0^-$1=mhfMGxdA?~TK4bXfV0N`^qmTnBeYBRFHcH0!x2jw0N*r$ znn40TLlkztPLBR)*!4va2+dAvwbnox*|ra<@V zKNlY#1(>_x{0)ZzAqGv4QyR$^t%phO7Vx?_p3BE4$Nv8?$!!mAlN`SQ&p_|@Jc)WQ zH2Y0owh$D4Ii;5`W25}|aY?leit>5IVin$s;uN=>?TAAOI=YL0@NFmgP^`}HBbGj7 zaq2tI4S8R?kcNnGgZ9qCIlfRYXn?7}?~QU$a{cvt@ZZ4`KMWL2-uD|#DWX8Q6P=gG z6%iVY=Y1TG{(X<^-$^lp0J!+{s`OD9c-lo2?I4f@QFgK~Etj|Y-I_&9U?y$ZTmYb1 zE=f@AV|a)kJ@wd#!N_LRnzXp-8(?jemSjYVbSE}^WI#^yQvIvjgK8sIZr=&meAvIA z4zsgR2Zcdb|0oPPWyqe%4F;)YscO$53-EYx|D6HmPyy`G(F46AZ5ilg1rX-Pqd#Y= z0j<0Kc(w;!Zh7i)j~n`{@B=oX^Rn)j7+(djNJZZ)*%$xgeDiM}dCbe*%GC5ZM%`nZ z5A0TuJx`gZ)YaDM6<0VDLM0}WE8@7msks+c>)StjzHmCc&Ft4nBnvy9EW%~65KdY} z8w+NmkaNyIu8w4XL+Ulu9|zceSS=l;QC>M$EMpyufGN2AYmbg*r1%Ck<% zNvh(IUe7>+rDbF{0oFt1(<0=~oQpn%4!?XPIch;vyNk89l;iAxWk28h5LyHrkiNb> zg?58hnR%9s8MwSSq5C&F&(2#aD8^kaOhLkDU4D@KM*QoIp52h4Pq}91JHc%B2Nzqb zuZ+tYuUt_F`Z#Z*q=i-`mvsnf+6q_q_K6ofV$AP?ZcX61*5eoy_{HnJsBm!cvxIT0 zu4h*^cRyANg{E=hS}*$MA1sv+vo=DGTM<2q6gEH38fRnkmiIrJIQ6*ihYaLM|9d`X z93ZA@J|9w^Djt_OtFQA`;>_cigJfXohflsH)Ax24ui&0brLcTuU6Lw@Uf=zEc!`J5Z!Q+my92!RTwk=TWNgt^eCGP(rTVi&I9TS# z*gMgc`W`%fpU;pT;!I+!0Go?#8o{4u^}wo!hU1NW0Yc|Z2CPZiC;Btsr*xyDQ-jsP z^#&mP`z=*TPBHRS*U`-kbbv$6?NMRseRf~MsJElJa8<;_fRhPWmMn=H&qd;<4jj`jv{NeKk={X2nQ8{9*xJXLCKnMl%oG5}p$= z$;bfRtHE%M?@6F@DS2H3r2VW$jyUSat(5oGUC!j4ab>0zKHidt>{Kh>U2yVBEi}zx z5yev9TB*tB)Mf3>ioU}A=%92;*)&8iXN1$2PDY{*XCl?E(7YpbaPcB~!W$|j zgBQSW-4lMvqy7y=o;G4sX2UKl-vBoj)=aDw1W>8Vg1&?Y)+#j^6fyzIPSZplgyd}a zRJ$261a!=sLct!}n_L;saQV2=R?(1iNimmNURyn$>kU*pXR{NDvWxLr?N0^VRM}bkA~#+12m>n>j{fP}b&a}8;Kp;2V{v9HVRFVxIH^+fxXS##`KIaCM)4NF{ zTqa7TXD<-mepQ(h5e$1v0!gdT1;#1j!a=W&Sv!4X(lZgApPyFmtg(=|n<-O-C(gB& zlY2w3^Bxm-Nxi_TU8(2$`r44LDEr{qyP26zuB|~2bP9AO*IFQ-9b|CVpC*#j#oh%a z;aFGoGM+5?A^^63H&hmxO@_yO3-cbHDcbzpGn_?vBb^}-PQu>bQhgu5>C&Z8%l}N& zD>y3QOM+ILhZ?IW4R8DJ#F?A^ei8+*v=a{?MmXHvKeE=7F_^e(FMm?O{UC;uR)t(k3UTVpg0E1L*eb6PHL<8bX^i`WGF3OQj7I)UYmLWPK~e0Gt+RCT44)I((fXNG5nSW>83=PNXM^upDES01);**vWCFT%woc&g*b z2}_RFB@Ft5KoMp&6H{Y1_Cl)hnz^^l21a#>ohu&!P$>ZON`BHCj9zVu&uurR$JMp` zTEtPLKop4sAslpEONZpdJl~n^|GXtTYu5}nkrWejn1pm__Dbt{M2VTCRz4{3Y!N(O zTqDfl03QcBOCsqZG9fTA0wz%CL}(iiQWa$UYw<;pbkUWjC1dG3|MCA0+xdl8sO2A> zr$SmWa>u5eM)Lj*G7hM(6D~Ml^geNc0^*J)pZu`@(-Ur}|3kEBSd%$xZRFHh7 zFZM+j{hCjz)p&J;G^WfeD-XNEs#7Z(O!I|l(3`Xu4AdAJcZfb&y3qnR1w?pwX=0BE z#e^I>`F`HoLGzBtobcgLq`Qg&R4m_2(voFW`KBaz_$ec|sSeE(gm8{^kL22|v7k{U zk8n@(euC9*DRCLJEWa%lT$uYAYs{zQ(b1bB;EWeU%QJ8&B zN@+p=0aSO`;;$E|c+V0&b)Hdw&pN6F9Kr`G!D8qh+soTy54fQYp-(Y^8Zo%laS(z3 z;p-~Gb&(JFBH5Z0jqR zGa2U*t|R&``29wIU`?y&_LE+E$D^_#4JUAEBoC8`DCBzUJy;b&YfHcRAD{;S6}+9C87Ja_Zk{5fwY=+) zS=!(P$lBFaSnLbKkY+qN)Ey+HW_89hzvyjEO$A@w3|x4+CE+6&>SpYBfRrtWh^Hve zA0Ns1FdTV3q#(aYH~i){_ZbRS6uk8W7ci{JYW$p-ut=6I$he;L zc&z~KN!jqxcAI_hlhuC}wNa$`hY0m%|dF z1I|B*JA^!L91imy5p-0D>+b#Cevc*bK8Y zk)UHt&JS9CH)%-?C<&L^e!CySY-XO!!7))~0b=|5X!H}jHC&^=?DJG?G85MkVB{#$NTUYVCWErmQpx z2rZO4Y5223b(X{P^oEfeL@g-Np#g{;$wei}!<6zc^1v*AadD?alh}h8_I;)9|MPRZ$i}z9>*}95i#p4blP~W6YL*W z-JC`5<}K8*L(U*(Rh71@XITr%DtQ?I$7+<_)~pF0%jJAVc?UR`)>`7DcG`Q6!o<{9zaO7ZXFQ@4b` zb8-Uu5c$N4B44zz(p#zX(-=}^lxRNTi-D?i#Y(L(FFNaoxqMrrS=F8yr_@9Gs|g*> zOq=lXXcRV6(c|8liKd5@`i%$U@^~FxxdZF!;wUlOoyCz5T3#(_y|-4P!0k%D8lI!O zMzd*dhO78Pmow3G70UBHdCOf>juf>ZEbv7S6papiv_9@ceMT3gf&Fr+-JXN5B8^gC z81MMd-@ocH8rMf4Gb#U`f5yYJJC;iiTDCA4;jWfb7nu-l^s>rF;G$ftL@?fYta!aG z(cvV8lsK+I6NOE_WVi=N|1sNoLLoagug#h|$-=z92Z`sQXVKK$hI_%GBKCryv~ulh zQSS!?^14yk%l!p9pwd-RV3rcv5heC5D6LIVl86Sls&RnZnd>^B8!I$-hP zra(g7k?u^`nQ}Szy?0_gORLSPN}V>Dug$p_q00)@Vd)|KLom?!SX7?K-HIt0C9 zqZqcS=X$1Bc4OTWE!oj_*U30E2rLsGzYNegPY9g_*t#So>30JHzs2oGl|dfjQ33mEGUZ%V-h+ z%Q>?+Ti`c$`MW{^;i9`!jt=RduluiOiR{b`$)WQc4=VVYYT(!cNxLGVMqa$LeK00d z1^aKzahRs&aS{;lUn3}sg!N=19M<3rn zJ4Dpq=E%E=clXTV9K?kq%cFtT4A(Z{SoWc6qZ3?0)m-s1BNdSwleAuLb1`4IG*T@? z*zTXpo8#6>VzN{LX15e@6BiZB$LSb^3g&ihhF#c*QCr6$8W=2OnBTKGl3Icg-?_C2 zpliNVKA*2wk*nD-DNcnIDyREZrc)#mc*vKifFseYk0a8`H*p9N|MH$=&oO_+147u& zlj1+L>HS^d7qgar+(n-%Lo_eX;6yRg5BcKgvqG!!#_3MLGm~Oq-=GdHgbS?g$R~^u z*5lv4dkp%Ah@_ZMq~aVhVLzJADB?{&Sz%=uS?ck{4OHr;D0NndQKa9MWm>_@7+{|O zZUD%&7?Rg|VK-7SXE_T?Mg893%0wS`T-zRklEZaW4m^O~r;2}D71$B#F_9H4HW-b@ zHB7>v8PxO^7^jn8t}OdVb+;p?A3Nf~hu}$v9K%;$Z`~YKhX(y#{=lt+VUX{oQ`-eTZvbia{lN;tmO5@qjWN3U70`m=%r(W(fj=T<&ehpG=Br-H3pXnHM#zG$~nYF#b)T) zc?J4oJ$1Ic5)vSYbz3UOD3ZSN{M>>K%j<2qASVQLje3;__ zo``zXZ46rD^FE0$3dLBtt;fq}e6bz2@Yio8a+QiHs`oIEY){dJ&2WhN@Gcc2&f7oo#glbAq-3rdPI#Zjt`0Q4y1Ri&;yQX&OC}ViZyJJd$~$VivU?&j@k)~vkzhZ+~niwbmJe| zKDO{G=6{=W8|<+82TJRO>x%XX*U;X2;FC<_Q`y>EBV)YRnHHs@fIII>TH~KOKwces z{B0R*fKq4tTo@dMgE9OXABd{UwQKMXA$O1S0c>%`lSx)C(1EkHN0gWADIzd_PgYr1Fd^Y4 z!_8gNX<17kb%`fdswHIbS){zIS{7VxdPdj5@t5_|uYi9Xot3V!yaMF9{ogaJ>?pzG zDDv5${9=3=dCVo-^7?1K^Osx6?SN8fo;Q;~$HE0)lmW`Be~;uZDX<+ipz82H=L?suSbz2LT6 zn;atuNa-3<91vc=E!bKyOw|9i$+IbQo7>1mzrT;aC9{4V*_u-8B0WgBM!&)+L6G*u z(9-iEtts7bjlzHS*BEsuTX2rTA)Q2vD|uk|&d6=r39VPT7u%ap?B7c123i%MZ${q& z=lJf+cb>!#2;Pu5mpti1iyuK&AM4i3EULrGQ{se}Uc~6kZ`pdEB&d)9DE&{g2W>2w z;EM|q8}$V-uaYH{@5>kp=ZjMg0Wx6sV@T+gsu4aG=V5Zx;Um_uV=enW3i8c7Apk4i zWxDo+O;U0#Ud7mnQTBJ|*3xO|V5N}2f@q;DYyIn)l~RSL@T-cUzt3L^W6IHwZw&D; z3Ii7{_6;CZiuE0RxZ6@-VvPRvkr3z<&=!F)Qdhmg9CZTmG5BzHGlssRyexC)j~fiu2SWP>GOaBM1E6+^UT=1qp1K#8k1?|P#|f7 zbyjZU^VKzc$S|{!pIs_q>unDhji;dM(SCuHSCQ*;B_s10593!MxATCbtJ5v)!bewD zdokWN)-4pEzJ|V909nDvQ}(prF|trfGOdw91P!_R)n_CGzS1Lj^^T33npkM!M@-4H zN&@w*mqu=P&XkNT`sFK2pO*()FS_*dH8A=HrMU0GUA8~2xL~Q^Ou)C~XogHsn;_vW zubF#1bcV+vW71;s=msxiEj?)=gsIPK6d_?%*Mc1%W*IGIVhWb$mYJDI$`AxNA9hY| z7F)p~k<7vBm~H8~O?D~t-XD3eE}oXX!biKM<{TYf%e?KOWuLRka{#P@D~9{Vb*#Pc z8ixzFv6qHL{P@w(^yKZw@W7cLKcTfCudhQ=?mQ#X$2{;^)JB?R0_0kp-Rj>k? zSCuAq4?H3#&-p1hGuTYCU#p->+sl!yAuKVBR_3js<`&I#xnYhw{BV@*MWw-ql8Tut>e!v8)v{n>z$*{CF<&rpYb;ZIcX!CDyV;oiXon7%J>ld3tc zUrnvS=TGZ)`2I6&`T4l0n*G!Bd?lO{eKLdc_7pOAIG=Zn0scJduC>itY7PYN*npHCe(?4e;y%i`O5wzJc%*YOq>iC8~SqNWDtw$54h#1Z>i5H=au zsC5#Y!@4OPlNk{ZRswLCK*BiiTI?xc%OSo@25A0ujq1FI`RemhlrCtPB z*8dOCN^5C6dnfK{14UKQcrQ*AmMn%bP}^RaZ8tX22rR`XRK@d3t`aP;kiy;0t#Q+$ zb?va9Oh>3!o$*uREt8iY(nUNbsc%DG!^o6K?GBA^TZupvrvHkE9fu$&=AUXBO;sMW zMK>1Ab)KjdAs|SkO@o#xj-R?({Ou{t3Yfq2peb-GTh-6D!%T5Q$g!VGOKO_W`4>f9_P90<3DqKA1TrD8!c+ z@w<0rmVKa;sRc-kG>Ga8wKJK1(@%M{B$gU{F!&Kq^3@S7t-i$r8_;w#74Xa61>vq^ zMcJ6K#iqjYCExbuQ9xQWn{-U5DaVzJ29DszF9)RJ8xO}sJ^tJK<@=TU)GPZgZ#KTZ zW8}6eR6w-2kZ$#e{T=f?*Zhrgu_A_ezt#n>hv#NJyurT`PN9yvisiK8kR(2ua>HSd zjiX41R-}4B4kXy4)&gRWJ>QpJ{giF+Mfd~ws1j1&I|YrEuRtm%K^tHFvH+?h@|tv4 zhwyj|BH9~4bhx0jY;PmLrH{Cq!=3jSwiZ(P6n|x0s003;0J>DhFv%8?5_9UT^1o4t4*0BxmX7NPiZ$E~CzVlQ6rqHDD zBhrt9uKN!;xgGpCpVwYk(2rzt!E*UZk37==wRqTKf19a#7O`#eTb%s3%oT0Oh3&{i z7!N|Uy}rMG5!!yvCha*Lv0JcloWJ{Oi8Xc!IRkF2L{~I<1-jkYVdh2JZf}dw<*oj|OQ3_N^Kr|Zj$ypU6U<;Wkd zp<2z~ut+eyjW17{Wu)6Y%=q3j4Wy#Z7xCL0cHmue>aTjpt59w8#rNhhivhHmf*oDW zmuD`;c4XNr)Sun?mIei`S>K)rNOFcKDxv3;6RK(-Y%V)5_dZz);sPfr$@ACZ8nI5b zd+Q1pwJv;t?6|N*(Ogp5{$m;ZjQ;_0)BSCO3=ip0%*X8YEhIbbd18}gD`o=S<^Xb1 ze%}QQsdAkYGu$gEfI9gPWWC$t(yNbv9N$P?(g!k zvE@Ra|K3YFCzWm(7a_*2X(go!Ack%395H&K9iIm`MA`pvXv9OnfC42sS|UnL0z>7; z{FCRT%iF(*S?z-e^^}s;FgVzHsgp}t_(C_=>$#YW&?3(H!jjkVNqbR?Roen{p;VXT zek7}_mpA|3xoJXgqVGV4dxs3DbS-kf?{>md>!WG775i)d*)D7w+9QS~9W}PBd3bZL z5RC`4uO2WggwU|S^f!yWUVi0qZj8A$q40hILD$yTw!{oI4t5l%_s!9_oI6x8z8O%; zg(PF?@c_60%qHxcMl$L%;QGHmy^@wS$im_9p+3$S@j?lg=h$muf9cpp!yKltnyG^m zaB!szPESyJA?NYBB<5s0{(eoLR41opK+(>6xSOd8@~)}J^~Z>$?k5c()i*f@+n(95 z!gKjauDG#et0vtye$xph=~Pk(v_) za=GMTw*GS2P^%b|^HE+Jm)$lJL=@AXpb&{{oYj+EWI6UrZ?fqMo#h+mflI}5`3pbhkbNsZLIqQBlA8iWHNEX9oU!j-fp&;F8J6GZ^ZFR zfUNnyp+q2tG?7h*m*!0^gv)?>Yth`pGz*ulUiy+lTI*MzZ)MAn$lo(`D;qRdeUmo| zi!1pQ6f!Ml2~ErT)sr!#lnbt~UB(4}SE*<(Z55A7qn}28dB``t4fx3c`WNDKUe0Jk zRE?eJtIIaJY&zoNDPEPmMG5D{oOdpN1}q7e;mrR~C#?e%PcznP>GoTo3n;AQAs3`y zXyI+t^siFH%26NWYl@MI2#oE~)@QyYF2{&m=I5@Mu}(?DA~RkWJt|{igI87+W^eUt zayJd(LeJ}If=cbJPW_ z@$JQ&<{q6v#5cmQ4x3c^rAwO)HUPor5SBa*mhOu6xIBYYlI1d43EwTa^)SnT-$r#- zhWB!;(VVS?08XENK9{QSueCA?|E}|RxqeI=Z0f(wOld|3{EhPcVF6-&4Ky;{LpRb) zG^_W0Ui-cSfBP4fTa~ZQif^OglaH99{7D#1Kk2Vp;z+gD-M!wCw2z-+>6eqr;0M2ZtB|Hm<0p{} z80k|Q&F7@eWiX_FV{13wm~hu{Snk?xUU}(r%+zDn)k}bMSw*k+yhDNy`!i~iOkexV zI(B6uM=AvK8qX;@6<7-4lThT|f(3H|&3ouzo5Jf2@@i^S*3sT{*z6gV83Xzlc=*N% zOc=E8j4>)L7Y3QUJe&toNP|wNng2%ARI9Cwzb{0nQ)&>#F7xNppGZuQhXi2f7^gk7 z6I5;4uX(#%l8av@&1^t9?|CmK0et^QgAYEjG!yJ)lXjgdo9sFwLvMIPscR|xYlZa z1NK&)LJp`TnM;Jm*GxX=+-InHcRRCKE2L_o2%~5ypUp%e&IJxI%ZyQ%u|x?#hm{8` z+oie|`)!ldBPTxhr2+3`e#;ojF%=+M+%63FSF|=`Ss=$MTj$;pzq@6hpLGqYeryijM4Sq}*x9AbwlO_nanoHyBA&M-5bWuoIzcii^25+UbQ zu8!MqEg}ypL8$){heGd9Vxu&Dnh5$4d_CH9TQzLrakBT*(sx(@6^= zc&)S1hrJNsjTH53G7s$x&m=tN0-rw6ouL5wfM|$^N6;ww4T@i+;GH@(Qu$_h=pALQ z^BjN5hzfd;(wAFMg?GFOOMb72is3F+{7y=j2if3RsB&3XEP_T3`?@+JA8?^ADSKWe zcdjzmX`g;?8GnZ;f1c;c^0mQ~;Tiv2N$_i|a@TW6O(!Sr>yx1b1m9n zJO^+mh1K!3a9YFoZdxqMf-E4vWyAYF=Gdy> zO$&yX=ph^Iu9O)hO)Tm0R=7-!rN*!;5(5Ht5#>zUC!Bst9pKegU75_TWJ_Us?)&{D zh#eIs%wjtCfK`r~+!X2z$U)~V6gIB#+fLw5he08!VtyT0%_lOB_^hxT!cg$?C zW%%eXQmak;rT4!A8MSq~7$r2kU-$?oD70`CkE&VoTA?^|Og%bs1)dj8 z3Qsu&w~Xx=-5#tpx1*D1s1 za;hz^(^a3FT>9oBdJ!DV#6mnlBF#MwHVukntoD;GPQ~O#&waICGep^pktj%K?Y1;i zro<#_dE@7fLJ8)K;Kb+>)}r7_+SXBT+XP_Zes7gCI&hsA_ejE_Z4rmH^FOKYr_Na1 zLO<9-$|@?@{O1%okE1%SofG`*LaI&IvUjPmJbOiF=^kD$=HI~^(BuDvW_MiRz`F*> zg8rvi|Ct>o?4H$~QWy*X{SshzCIv0|YgQozNKkNhD-kL1DB$3CLl~U%t;;$_{N>r0lV7G3(>h$&U%xD{e7fIs z@F-f>F>oiv4boCuba#Ww&fQ*N*s0Ewo%)Aox}Pk#6OV+M#vu#N3UrXODdY%pa12uh`pL7W#em(_DYq#RiQ)NalnObYGW}?FS{*=^AHEI76C!WxFDFMr&)S-o@8G|yYDKe7 zL?O{MHd6HcqMzEiJ3^+0*fUI7|A%BqxKUS5yEkOmUPzlJ!li|fFIfrp>P>`2_@y?x zUo_!u?A#j(PH%WJQ+PD!8zRw1e9Efw)xy5Ia5!GO7om<__jS*BGe2Jf0l`;u;OR5((Kp^)EZ zGijNToWZ_kn{5b{GsGJ z51Q8Fv9=93j7vuUhEW}AP_;_ppq%v{R;HaR&f*gb1>chD^3rgPYrd3kdBY)1S7==# z`o;ZieZ9fcXf_hjKt5Lvg-bM^o7u@8(z0;3I}XfxM!VziG5mC?Sxv)-16IJt_>PxB zv+QjaVT-NiR%$DcYbeTVOwa$1zTMV$OZT*N66N#KLL$y1(>Th}bpOKaE=PtoMm9D%B)B zHe+%GToO-wfa3liK#-!qlN)UQkyX^TV^k4Ax9g;6D1_={CQNo@-QA?dqiz2O$fomd zClCZXN8E5v147Y`d@tYx& zYV>z^Ve|N{Q6|lN3d%?qf5D?Sh)GzH7TTc5VYHqmU1dol%H}dzfqnrnOKTb#Gi`m= z(oE@hACk*fZs6!NaO#?&$nX9JfhiW@G6Q?;TAawMwxlUCin+?4 zGVOP1xqUuUK}3AzSq)ajO9)Z!S~&APl4K#bw=o}bUD)~e*-|Id-+Fr?9$pp#E_{F- z&9i+deePIUD8M1_^g^Oqr)7)(&dhU82&|)iM-mCc+g2&vUDvc)cAnc3wR#=w=pX(B z@6*0g{&6IZalTgT(cdU%y1%1lC_oTY9MvUUeR~ z!$U9JPtE?WreVv!{jb5Kekrl+m6(y&8G)#u|W?(}TM0+H>D2cmDi}BEdu_KGFJ;XoJw9}k(qUySf#W`0Qe9FZ0k$>t z#V3rn0N073z`t)QbP>ofFU-wLDI+b4zzYWvYF%UD=T`pgBm&|s%S`l(eD;3_1S0d$ z>e})G^T-uX8B?NwZ{=puOp_qaT4P|i6oWMzfB$zLTB{9=eSm}~-ay$E@4Z16SZxeN zd7BAPzh7g3hFtI8jiWedySW8o)t(7p{3$^;DrQ~$`|;#^g4+9gWT^4ii@IB)gY}bu zGu>^EOWrr|XAG@j-rRyl7_u*R28JfEdos*79Y zeRuuX?ROY%lh5+`1o*3v)i*F>gC^Lx*|4BJT>)-~y8GjB0MYOEK+-6@_qAPvB$8$GIY{cUDmZ@Vro}1bQ+VMW0Ek_sj+F~`FD=}xer-A=&gHxtwy&R^w264^8V(%s={GJejvK!vk~FAfXe z%8CVsEJ4^Y2=$dd!u`Kj$F1eQ%He+c(JfCUGt#G9&?7#U$1zvc#S>6Okhy-EVg-T= z_CCD}W>iq1=OhZL+Ig?5Aw!G5 znXX6Z11o2jqOCIV2hbx=csliumcD4U@N36lWrrvHb)(BR0`E|PMg4Pv%0{0XM5!|C z!SgV1?j=(BKQ$f%gPO(wCCAG*w->zO&1lGi* zi{gSkYrwLGXnyx4&Pgu4zD#nBXqeO*wq3pRR}{zrvfb#*RdE??KkG7Y|F`cnA@Jmy zpmJmA+0Wk+u9x&LmPoC>p*o(|t3h2jq}Y(<-=@B~73Zq^DFwXhF{^q-NcrLIO23n} z5wdc%+_%qLq|Qn%g|cI5oh-LX;PTqrv8-w&H}UY!9FDO&%0^n-ByUxsy1?3@_y zrWTSzF&8OfxlKTZkT$jiAwzt-PFgQCb5fgPgW}-;8=JCD{44;~6cltnM0_gho@d@` zQJ4)pdYAS@aFlPIrfT{?_J`5#XN;4Y;9bkQ;rHN&59hOEs~1CfC)>|fpjmclR=im} zAYG~`A;%bJM3)IM!wC(ZY!?|5TCd(5_00}4?m5g`e3B6pC{_2zm|9!?I!;=rvi`r? z4u(S&DSyI$8sa2>J8hSOgOXhXrF{YkmSa4G8qO#C>oTijHm1j3>d67er59~VfN*qp zTm*gtPd2EN@507|4Ni<)#K?;O16VdLa@Bj77X(3&c^l9Fu_3aq$nAHfUw*)_>6y3H z5Y17VjtN3t$K5t+cuTID+b$21x8Ui0QNN`No3Kiva6#3}*Ni$wLT}3i>x~RP3=rJi zBpVMBhKdTzGB1CUC>XS>osnM`JFTAOZs%6h0vr2R%2n)HY}++al|_RJDr+}iF7-() zo6qWr0EvHXmnv$st&eowFMY@e;NER=Z%TJ zp$)sSa5IO?H@H*l-wi;kXLxki5it$sB3IswN_3m8EDx4=r(@X6DUck{4i2U*%iwXD zE5;?Vx2_D1x43^5UUz3|5k$P^uEi%+nP2hdDZ|r?j)|DWCsunmU!cyz1UXD5bafqR zqQd|Fd6R3}^xq`v@v^5F%~_p4g)(^nbr{8Ed+($<(*6q_cObsx*tFkCP9;0dm?^4Q zWa7WQ`L6KHv(~2m?y27Oy>!O(;H9|ec~jfktGl3krh+KRtYEmcl#^5CFu)ks^I!o| zhs{wUU>+#VCG{r6`rk@{|qkl;=}hHfLyaw*g{gNT)hHu)8l1n zow(D;*OQ&6&sk$%!8ezOIGh^pWoGds3xv6Wh#aTG5da_C+ZU~y$tX=p$=J@#4UC)V zJ@fk`9q4ZyPWwCA0m2r8KdrCYI1bA6eGUCPv_WIUf>=H;?>mawgj>7uC=LagKc2F1 z8`a!CUn>!wCcV|cgung14%d@_0g_sJfE_TqpaOtgmh5iYeWLD#9;}MLziT84Z*jDC zPO8mzg1MAR_SPGWF2w`SgAjo~Jk@Oixnt=qq2OTNFsY7vW%qqmDjH&b=Z(yJS3Z&~ zzw~#9#vy3ABlU`S0J%2!%Lh$yfpjf}V}X7AM$MEQL>pmb=+_8MG`{UT{|vi`j*weO z7#T6> zhQB{~DQS>6z_}(R%L!-sjL**FBvQV;?6Dyv@iz87+M!XlRpN8^N(-Pt@;$npl?9yE z!=-lw5OPIwC+eQhM+Z2vr;XvDw5gq}?_3lk7Muo8^p^~>W3Sw{6&n57nu6Z;eX_4p zV^16UzUy`FKS~*!8n~d-o^F+w$GD;Jd(f>W9lN?tZ>3f*b!N{TQN97Js#&X$btDIu zCHO9q%K4hxa)$(xq%7*eh`1>KCT_$g_c7N1VLJ1!(EXOqixk!I^{UsymU;>^B3 z+F$2+M|l8#=~E-BXv2Sh#8*dPu8dd>%^kbg9oef!>SuF(>1p%%-LQ6|8UifFy7tI- zt7!g26I*pZ|txx=<-e~EsdZykmJv7 zFtnj2cCN$jrlNqs3g*iIlcMfpRi)iW)A(L6*Sgk96sctM$jzWwz3|ojX&+F9tQ}Z5 zIz|f1pzNh*kW&fQI{7yq4SGI?1Q@ItQ5;xSmz1+c$k%!P7f@ODFMG!x#+OX1$`VlK zGXR=$@|B(9Bf5+1pvV2A@iS-Gy9jXu5Ik+UBZVOs^5BpS)W+y6X3q4un-;T3BE2Q9vMn;2XD*5 z-G#^|`>b0RZS<+Y}`;1epoos_1E&wYX7oHe5%>C}v2H4{q*B>cRR<_Q&k!t?a@gqj%ihM9%f?lZ z4%FDrP&0VtKg5LK9z0-dG@NM#^E|2Vl4I6ii`oj$VrRoFsOZ-weQ5gP^BVqwqkaqR zlWP7Flb)db;PT@k^;Fuuve>qy(5#JERbETiix1w9%VLTFmjl01ujw&riVBR@;ODMC zl9Ktc@NY!*PISk?u`e~{-L?O+ZD5{~#lANT_oz|@zYpZE7&U+#;inVUJz94Yn|qNG z;wmpsf?xL*=!)^j+?0GK4v5Ij^xu$IGe!@vIBLG`-=Rk%-OyV8i72`Y&npfio4433 z<%lNrJr@_5_ocVU2P}eWH1xdp1!?;L=ipOVhr5j{j*lSH`R}_RGUr}4+AKv=Z{xF# zkZ9bQ+WjyMSi`T#6Xy~O6l1$T#}E9V^I zMrV{eCZ_AWSzn+)9s9h? zzzExJG;kIXxLxd-Qm@x87W%OC!$7DL?0`P)79yAxu88H!n8T8-K7T9E>z}Se1`TtGD>eODG&6Z zViy~wNztHh>zocw8yifQL`<#=6nxKn@t%7i@ickbq)Je{%>FvoK!>qyQRO`Gba=s*CFvPShVQi8A2Pj)%WFhi- zJ&WChtD*LFhiTw#=%gzz6k==?H+rK`I}{w2lZ2+k?$~6F*L@a;+PK-5A`(2?jAg#{4Crj5^?v4jnzyNIh6B{*S!8yp zjxwjXUgx?TDi>&XJ+oEY$g@EJ2grUot*R5E73WcGnE;#oF)qtZEgX0+3<6KxjAQbE zhH)-&Z!1Tqkba_p1Uy%`RU&@YE?U-X7zW!w#JLjt#_)(R?r9UzrDUz zaNp=A8FY(HgU5gL>Tgnl$KD#CO5ZH5h<-tnOa6^sZNXB8XhpYQABRD2}^6`*Q&YJHBvl2nwN^b2BUU;qNkwF~pYNrY7LBA9QU^E%OQ+s^eFe z`l7v&lu5ibuKVo#ofH#$|H0FwR;O3aJ^%*igZE5{yv_XKq^_^f7MsYsbX4WTUrOI{ zP=b-f{WNRMd+W_#R%9Tz#rOJguEy}Y2PZp>^CFIGYCIo5ZT<{B@k~*3#1Xw`0I(X^ ze3Mbb9THFLL1;V*#Y=r(5&e`H5Bs&C&jh|zyjd1{)Stkz*z^Qkp3XUCFfB782xOGU zxN{Q0@JP$-*Nfg#9{-Jj&T%d5oiK+$oc2kn$h0*VoZv|Of@RL}V3fCK+9|8c$2v7~ zrmxzk_3-$IoN8FxO#b2Lt#~IE4hwE6GibY)5)AZ9m9h}}Aw*An` zd(p3u*6u@ByYI&}gz4uz){59Gb;LRNN8C{}Q#Lb(3d9;APkoH3#2zaR*9su<<$SyvSccKn1zLG9c&8xQZcQp~x(yABy9mMiVLki9$Dj8duB0s|T zF$pgZ#`^v8FO@d-I>vP6dSYHnO|Gdm7iSPT7k3J{;xXL+JON9bhRsGl@nfUvrDSHQ zDKyin!r+oll-m$w@m9eoif0+EuhUWYxj~pl1{fAE4L-BH_Wne)p$(hk@7E)x+I_EK z;C*`7g%J%SR?#cSlX!Ju3u$>Or!u0;8*{4u(uZF3s%FS&IP1_)e9k8o-1y+u zrSAY4Z|w7rO2+ki~^Jmva>WEIJmy+ItfNRB#HOfM=(q^B(?VB zPe1&qv-@|1Z=pIi=1d0MR!w~G-=eBhqc-My6rC7S+%9xV++4zP{b&NE7L~T4rHTTY ze;Tq|fAM^-o>F4-`F*wxxCY+OU}<@Y^}>5NZwc2RuPAcXZA+O>i#O2_i!0fG#!x}`>!)V1|*xJ_7p=qd-6ZPdzcqG zZ)+F{Wdr=wzX%6DT+Pt?Ls4H%yyj)qCqpB3=*M+}fJ#sH4~8g-{?2vvy+hX`r4NF$ zoJ#Jx%tHy(Mz zn(ZpaZ>)nY`d}ebD=#Li6UN!>jj>_PwYJ1YUQpbcDhdF8x`2u4BEN}-ojx-T=aPft zvA;A8f%>~U;cqf#)enz7vuau$WxHEYm2O{+8e|j+X4;STdvh3ws!jPWM<1Mnh(O?T zKs(g##_=&TMKfBev}KoCRdy0`O;0ZR8kGf_#(jHnK)wr7Nzz4=2pCZ3JjpW7C~UyChmco0@*dacF*+ zOry9*psZLT8uQ~{s!Tc_c&a|qZpYHZ4M1ZX78QjU4=Y7qyR3D=vVZ%ygLiSTwsxWD z@-#mf`jD0%-b6( z-o1sisf4A;VgOGyI>*!HUT^McWD0715I^3_&3hE^At?HA(4nK|<}gzhsA?s4DW&B~ zyw&StJ2g#l>r}+j59=dwx`Uj({Gq5Ay#MYT@sywnFsmh{IcKV1K8oNg#?-dEqy^Pi7Dg8h+R zT$d&ZqM}tk=e_$*$h&4%>(q)g#>`*m#?#?&C7ZD4kOUAeNv_YJqxl`+6Ib#;X+CMCz=cQH|?Lx?=bg1ONHE^g2b-Y-dMYyxRo}oP{U}Jlnx)W zv5=4TJJ?Xpxx;--?5}aVa8EmYNq~DcF($}@)Y6pFeYDi-?{`{k9mj537X3efXs=ld z;sWbOQPTlQs{AhHBIxnhr0*HZFZKOLJLx074cOt~%kwG@0p?Q8I+7n-(q0jt-g^)z zZ9^IbJW>n+v=)BYKOFSWeYo7CYjs&bhlwJVF*1)oGr71G_}=SF1g8P)w_{I3K_;dU zk5}!~#*a7t`@;y4yDFn|vXdqOgnGx7CU9c&cu_AXQwBar^8L3a2t1!#}QxIB#O3 zd!w~Tm)%RgxZjKy9wU@hDfT}A{_jir@>eTsKVPeQwC~7Uvz`2GZ!hsc-UROOEc+vJ z|0Clydjn4~e6hAjaH{5jzuYgn1UVr=hGq~HgH+6~yZU&D2qr|HIay(MGJAK%PTl_v z!s52OlUxE!> znNN*zDK@T=%&Jd+)&Y(vN&6SN8u3=@;b0AkWiCLNFLl)nMet70TZ{I58V=8xgHD+@ zo!WVrYB4Rv0<u1t&;$KOy%+Fim;P*!)Ci3v074n!)iZqAIrpHuZL? z3<8I3EllZ$P4NB#_N3-w%Vzb+qJ)X9R@B`Duapu0g~J46o~zcXrZ^rhuYb$NAiT97 zE6UP_A1mwBvKJ2@Hiql2umG{Xuh^csJhYgsyBF$=5Sad{_o3b2<<`6;FW2tZIE8gE zo(vCoB~3ZasG+pJBl2Z&>dz}-9JWQz_Ov7C7Ek%#h$as#(FZ0zJXkBe=M&Z_*leHC zR3ZAX!R)V8XD=b7gS7=LP;P*;YA5~Z1fH`d(MwKa*tFjaE)IzCqkfGs_tUwb_mbRD zK%SmBT~vqZ_J^pGZBt{>TqPHHk4wam0H9ZW;kY*$Ot}9A_=R{bzU47%=^;4U(0V;4 zvRxF)eLHh=PzKl1-oI++b%VTo6ascsp8D@{G>u6TmSF|!M0o}a zWJ-u_s+_7NhQr-(R{yzG_TGt){59~)r*#PIA|B6ghmZF)b^RF}y$Z{z_CI_b#E&f* z$eb2PJNAJOq8V*HiY^B|vhWTJB+ZR>c9awgd~x_nE;p$72l-eMD}pJfz1=%pn* zR_RHKLn>WXuNB^Ar7QxHK3^IaqS4@!8x3YyODM=F6@=3S;j#?ctY(wH4pKkn!UK!f zbpaOQgpHF$ILz*U0CoaTRmz=R2_NNUd~|H7-qWQ=E-y%L=_H%u6|%W})cA%uYXP!L z4GEF6i$h{uEdUzpLo1FQ@>Uf?Uaq;->SYyTgD6L;@2SbO6wie0m?9mAQBI2^QMkaQ zJ9=xMl!uD{{Nea`F^5n*x3HjF6^|94U!=!FRRxBt*3@sh1W++|$GHfT@yl`VMY&&y z9MQSXrS%$9kR54iO9eF$t+ihci7GXn3%g|7c~qB9;1guhzzenz7gxDH?B3xJiOB}{ zh+Ei_4!QQAgTdr7c6@q_^c964K_X9f(`ruDNhhkCA)bHjwWgO0q5-0u`jAgZR5l4V zqhoyuK*YCfaLSWiFW!j$8!D|0m55>0Z9=^LN2D!PQzz(GPPb*lnjqwrM$Yw37 z?ao*{mzdL9#2ZJ4cCkj?r_@+FwqSLqkaP|x7tR`>B1pa$|LYU%mQzzR15ZGlFU1!4 z{I*yhI9i}<%RPcA)f_Rof{|Y5a{OMBpb6dO_G0_0E1CijXzIYgW}zCY#m>^ma1CA! zDLNnfYFXEPsQbx#p8DFGV)B&un)+FSQJ0xa_ov;%q0o=-n2Bchoz^M0;v%$7ixJ9T~LfWdpg0zGl0i@af3AQ#yWXTg0B zvZK=k&Y${Z{_n6K@Tcm|q97WhNJNRBw3UAqdc)dOV1VEV@2z#{h>Vmw)e8YB((TK| zxuOmqoMGI)6pl+4FuOiAc-ZIgtYa^*>k$joJT7|d`1hPS1qSsv_c=3ChoH=3?taoT zxbmfJSk(szp#H}jc=oe|{AC-0YMCBskM6Ig>JHgSu(~YwXk*+a4^iYZ7W!eWq}o5Z zdzVZ@B}%t>cQS58WZQaYUUw5nGj}*Yt860`3^l$l1D~U(l-ZL>geaoDP6yV4F^!y0Uj0|ftJ?Oac=d?xHhErPKYN^aF5;~6 zusVOk*>$9xq+9z$GgGd5Oi3%#{>v(~iu8KoS=J_WJ0|deuI8KgR`$e;3bv`K4y6gh z<7*Cj)1FsLO8v5_;lr2@~iZuI0WRplh->`aPrBc|Aggw^!RO+X5 zkJX|5Z_t!L5G$HZaQ&A2T(=h-Aot@-)V0}<*os>1L`7g@=-i43N+ogH=x0#-eIM^{ z)B?1){Sp%hO};>hn?0l(r>)&mirW>S^!AgKc3pb=`|_WpPqSmGwS9fDhi7)=O!-zn z__S7G!`>QrX5nj%Rqt%&f`$fL|MrH0oJ>Cbo44+LR$V6@(JOSbj}^O4y^^gI7GKXR zkB#tqA&L*V-ZT9yl@>V|qb;S8q6}}YFlKy`vb+7IXWry{azI}CSM>I_$m*(#+O{%2 zTmNN~hKZ-Ky7p37V1!(^!wAGF5T*;(1xQXxC$hXrua)ydJ585HHtt}qA<4W*~E^~Z42j@WjjF~%8YrY}#Ln~CLpfj!PNCs z`U6@~s;hpbQHsUI>6(XMpUrYuq69CnC^{UH-5&TC5kDQ1gdZo~yaDMK>qAN|Y9Bv_faozT{!@?RyU?FxQI$oF)54vXqgF<&e`+dR=b! zo0C%)I78nEvIV>OxZoV`I_>F1kk6&A<0|v&y_yahh>o?Z`mFFB;-!osAIBKe)AJF* zsgV^63Tb<>@>L^R@utT?o@d)(2mnR{3&;=jdz;QkDFjSj7cMlt}q6T_r zomz>UO5@Fw{*V3;ooIuMuN-~t^|Os_R*$p{>SRwj<8xN_Kfkf@a|+}>zQ?cHN-(q% z{fbhM#b9EDH@g+6`e|xh*WWFK8QT`(Q^Guq}{w;_mshY;j)`Jj(5iNUwti*w<<@PbF)bkY4(#_h1?mqQvZs)LsQf_HNXV|5q9 zcjm287Mz|#1L?*ee{((hDG#p6G`JKyD=t#f<8mJXQao$5a76WamL{uL9Gm0T z9K6)u1;`s7fE84aOvZIpUpFNn6+FD#-$$)uU=~Rq2HrJ2Du@$B*Fw5YcGd;0jGsN+ zLex47<8+T#((L#^0ofaLaCcF>%%5O5P!7F*zYD^3MUH=65&B!EqV;||8lBj=Fgy-4 zb9)L8+x*K=!coP4T%)qex^Ubg+e4*RQR-f)*3FI!yaj|CpadK4Iy{`2l!drMXz%bV<8NPm0VnEb+^~=()9(Af7DD2~|@MisiM(GX7F_s-N&TsfyD+*jzOWe#6KtwT0D2 z91LQzYJmLNLP=g}hP0UDYeG7*hrPbG43m{(Vm$F}x2r5zQ=6M?!N(5j>H5U0m-PNK z{BgVtI5Bcq8ma`cTzBV~_%qU8R%E zMEK=C|1UAJADR~tEvcH9EL;(zuc@urQJgLI&O=hur+IWQ(|5%Gkz~y>Jib=wUX)Lc z_`+oT@4xu}SbP_UasQCYiawTS&+X9EFlhUj%@o6>Fpc**^YLoJ`Fd0FiYA=k*KfS| z9q)b2(kVNhmln~|1iTgu`_TuD-|&D0coZeZd$W5x0Se zPQ{kM?xT#i5)eibxX~)D#nyKOuMdMXjfB>r8}@ETkMD%Gu* zAf8eu@$=+FrKC)wf_3-D9N??-O#8BJ52zomi|MA) z$4$MQ?Av-IVmF&b4GLK!ht2q5PwDUf^IZb}<;-54lj5MI$498Cc&?_{v|KnXp*%oY z3}4sTZk|wToZ`*zhSkrf?(7wT?j!z-S|W(wxY#8B+s{d{@+G_?fc;KkX~jn7qSRH} z=epPn;6{tr>)InePPrMko^}pfO{rEKq?Qi6Yc9@|TjRy zq`B<9b0{Wt$;UwDiqOJZga_QGg!A!Ycv3Ekf7wq@+zEbhMJ0cK83WF24qE2@VX*1e zTW;fwJmWW|WNXmrP3xI3H?Sv$MdbV2rB2a#tYsGi4(aT#AgB$^5`(Vp2ZBD&X2OaL z9BTq5Y3gQ}inB3WON!1`7nzh1A&MIJ*J-kJ)PrAf(H<#^7w*?2lIqh?#Y}Gz3~bBo z5+$BpJ|R+Ev|lRRUxEfCiz#xB#S5Rz9USuSxe z>nS);2ygVcu~P|ecylqtwhDLsSD%<8K-G=uJtj0YlyGrp-G@{+EQYQL%5Z3`R2XNf zt!fU@d$PYuwTlhr_vFw^n?-aF z*oAfeJKd_o%Rh^HvI-!Y7Twa-RX+RgyM8#*Lgp4Y`gozt)aGB*JpRcUlcz4;-N8h? zlWj`x_c(S--dCD;E5g8o7p=QFYz>{KO*IGD z|L&xY_uUi*KO4i`*E)y>mVG&0!z9O`=lw)pq8uG^pCw-=TQ!5~&|+Ta7*+>b%R$b!KRspG=-z z^SQaOktb&_PG0*?xiv@Rvzk*%GgoThDyvqkwa0y5cEb(|8FALUe}nDx|3l%|eY085 zKGDy3bFK8xH-qi0DLE2bc2n3s0r^;-;NmXP*f34z2 z`LS5*OQ`ZsAjZRS3!7;RSM{YC8D1md)3BACD0Hq~PZq}XUUgOT8(+MG$beS9l*esI z=f4eh#Xb?%Ro;Q>n-W0!3sC*zr|Gu9>-Vgk`{&;h=@0LXczw{4$43kcne@$s=dl_- z5_#IqYEYhyZCu4$H>ANcw>91@#y>|Q!;gJ%4Gour4hPYQh%9f~MMGZc{Du8vUtbUN z{Ne>tCtAtXHCk_9L{}PL@47GuBL}juE$sFWBjXJTc+H%cw#2CG>-u5j5gX0t_B!rv zrT#a@ZB?XbM)^1^tC;9}%ewz;ff`#_HxX@oMQ{STTxz3R{3S;Ro1Zg1IT7KM)y8V5 zTx-kN%{%8~A2TDgu#>cZbPvS+Mp-W-TXdvKu-MIxx3P2GIW0x(lnLTZ zuCp!DiFY5|U}hT}&-k{vH3cak_)G!D`l;Mtqw97N+a$wkDv#9djbupJ!qKr$15Bii zYdw@3!1+7!-AC5`OAohM8%mq3^s(&Fu?AP`IhQP`QOT|~MG+!jOEO(a69b;%+}PGs zO|Ep9y*H~2;30gkFf(KwpWhp%Cp{mi_C6diBtGKQ-luyRuxoEq`AL{vRFq1C`ri+A~2eFL5;I% z)6URmvTJvQI{_%CTy;ToVC&~e%aa_7zpVmT7HCYuge)K+=OJ;G`@*!(&67>{ay0uO z;`Zg>)BHIuRE`-*cq(#~emR^jiW26u zF4|-TN+4*pf1W7Dge^`%fExw6LW8>MM85p5WdzALNYzMEyqz`r3)`fuT;VhqvNm=6UJv_mGJW4 zJtvD%cG4{YnE^>+f&|HDx^18`gMMkzlDi;@OZ#*)BGD)5p-aWDQT@J?ZjVmYvsaw= z2c%O&VE$HRp>w176ft#_X$w?; zFN%&FNWiaGPN=eYnCaCzcu|U ztlKb`^e8p(=4t2zn$6?>=h6MaTS@@+eIaFD2Ru*U2du!!u;(B3ui5czlZZK*p*5n} zV!kTHD8ZrXWQnZwle;IX@s?;+!c8Z&q7wR7o2cB>hi;JKM>S5)Fk^PnD$4co$}X5l z`{dPNyBqfV0X-p=4YgvAVngMxfpSYvL(-WbMHSk(VhawFQF%jq))qBRo8ZnLzQGb* zHB91>{`NE4J4%azu>?JLt4q%#2i^tX;U&Q4$~*ljg|yaJ=}oK~Y&G zRuNEz`(ZmY8}b?Uy}^5n#uH$Hq8?28(GYG)yXdAPx+^?x~oBV~l`QGzdC z5Zf6p_;(pSj;uKzw0Gnm(XC>zr?BSp?(X+pH7gMO{22~#7*VwMw!JH#yQ zf9m)yPkF|)d2GoBAJ~0TUWT1!J)JPZoCDj(#g+m(g*UqGFMxp0#z6xiK?m03O478C zRsa;{Q4I*9t$J%&u!c^d88}>a1rGU0B%8gOaCJ~KJI{b7ezaK&ZU?|Sla7WFA8o>u zr9quY<}!&$agr6%)0;)fB)97Qd9|Y^v9T<`#|{(cTzn}A=G1o!x3KUhRp#L^6{>Nx1b+5M40m-!m1=DwZGuf7e%yPRLY1!zf3cO!r^ z#OBMg18)O)uIi!vPCf7qTYP%!*lLVlA$4j3-_P!_tv2zB^ zeaCRg5-kH9KO40C3tJD`rqouG?0h?bU@EUopHCW2;+cc=Rwh`gdrF)z%C@zZNx7p0 zT+>|UK;jhdp1$fQq|Mj!*iInW&lffYyz?^GV!Ju5A4wxt@f*GY2b3Fd-$=|hWrz{@ z1`NNasaIV;+l#$GzpuTO!Y(7B$;@ln`h5Ezz)jIhzE1|qtc8&FxumwR`xa>Ebv1u0 z5v)6-bQ`=>K>E?vy^x~~sIK|BRaLBh&fScPmyEx8{(Y0N1ms!iE)7+72Ysocr3mk7 zc4LwuG$2y_Ia$+LlD?m9Ay3bLxd|P3Cal7sSe7Bwi{=MurpAN0%{?V&&_J8uWYV zsUHdYG01%}%Ke}?H#Nz;lsB!0#UV>c~^9?YIBFOjqna-BP*74d^G z-H&J;SSFE5zGZm}wp zu6?Dy@s1$(aS)z^QNdJT0>NK-hXTmCXmV*RWGyqYpuQ@# zBp6Ii<2dBf|7kt&>RCH8?s5(3M$azdCZ6|-bN`8-X63Gp&{d8lQ!L&KkmQWp<$fI` zvF9c}$&MR8hxsehISc7Vnee_^{fy#Fd0w*KFv^RrvJJQOWH{dZ_8#XH7lgSYE5?G? z)f{w?xW>|ca4>K^H-KkHPxwxWkCVX9KeKK1D5UC_y>0-jjPezCY>qhT7VUERKItbH>rfjf zqx_3v$D*BR(%ljNH@a>20(0z#L?4#leD&bNt7ar6gVXeX039zG6oE++v!O`j1Z6WM zc%nQE_1x13z;-Prua1`hiOJktF+RCBQKjv-*XQ$uR3+URP&;yM_=8ww8FMcL>ZsBC zflt21$^qRzVP4gJ``DvMdFpHPBrm_Os^r{xW{VjB-p|z}@yc*t4r7+1-1V^HuNVrI zCLa;gBm4(1O72xy+8-cy>BWQ^vj4Ps=zZ}F zC$>ikBPgT(eedTH~_gAo-(Vai`nX7FrO0 z+Lq`ng-^0wr6iaEdG_bYuosfBFQ!;&PP@L z>zXm)=DQ2Hud&S6gdzM5iumwnnv982PKK3TDS~|>@#%H;@sR-#roe8_?;zDnF=mrq z@@D}8;TC0aGs)lp<5zMh=X^fl-v?POX*N}=lh)OXQ)aj5`H=T>76spve`{08W4EO0Y0m62U&G_&&Q@zEyjcp8 zVvrL>2#pvAUxq_7b?cy>zb6jSJEW3^nFD>dYVz z7Q}6dkb-3X2C44-kT%g8NlE(hHl^Dpw>M_bag5+!w-T}^u!Njk7|)=NhesdzdM?&R&CHRUk=3k9Cu$(~q3P!omh-nWNs7>^ znS*+IIfyK`pZl(rnD@!nN|A3KuO%)Vd}-Bv%*3FYn8O~fAC@_fGycjn@hrBmS6*Mp zYVoxV;W1cVmbAlxVU5ya>JKwL)JZ$WQn#^``i{14uYz>qOnO|zd|KX3RhuX;9nx2W z{M`W+2bwX$=#!qXoQ#O7csN)T7DS^e2n=Y6#Di34-m{M zlrVMCk7B?0i#>T}XcZ1;&&X49ED))I%Jex3AT!K)gol*2b5iVAt-sR&yTBB!RpG>s zenHlh>gUlH!YH&J8n7#zmQ%EQ+@mz2&TMEnM90SRBSIMlU!QA@SBt*#l?i zV~`>?{K){Nen7V}Wu4`?3rY@~d&%Qf>)t<#M^*k_NSZvSM1JHQ4@|2<%mNI2U%c_& zB9Gp2+f0$sQOG%-x2Z0cc`veCUR46n%p9A~0YF8!&aa2=#HSS>%rTIBDa(&(`+d^G zQ0}vydwR<8b<6GKkH$|d?)Z7p#omVLbt)1J0j~yF#2F`)gxRo>==U@uRwI6oE&%eQ zLAOV%)`;23s&pmkj^WB$Vx_$A*q2GYV2-}_-2aw%EvpsHEOZ8WSzxOVmlMddR)jnUO%+J<=J(u&rcGlDnOoYB%lCpv8z3WKF!eqbtR!t`-o8P|}2IN(EMlEQN4` z*6fBdhUyVi@tI{O`%l1qYlb}V3{U5mo_%n+!4ng?WhubENlSm8$GNm&%v*rdU~`je z{Nui`p>G43ET#|Qx)fiz^fV^PPC2cMX)0~WpuMS56b!)z9lNf$1FtPzyf`~$@X6dl zjF}(g_6+dUB1-)?KjhP7Iy&fu!;I|>HTp=i;0xL(BY?_zIPbxa@ho!kp2OBR;a8sb zJ*Db|-Y*{d-;IMV&zkzAm*XF91K{77m|c}hO1Egh=W$3|&3r5c|CuOe)@(>BBf<+S!vp)Y(I;=L)e|-77=35VK4s24M3IE%1!Fuw4&kln=LqrS0RzD|C z4?E2)DLQ;J3j5cVexZi!Eoca6Wm(=I2#!}R5_L&oA5isN({1bgaR;vb4t&dlY;`T7 zkHxT+8kd`cb$!Y8&~>R^kX`z)iv`5_WpV=u#^7GNl?=a3_B0&cPPY{L+`P9@kQ1n) zop$)cF!;PnH$ElvG{g+}d%of`1^1nkG8k8aOW^2!b1=Z~L^ndjLA>B8V=w;)2+MzD z_L3CW39mD&8QLrJ$%Q$`#5vtbaCTxG_R*`aUkjr641>PP=&-_4>8>&Q6#r>R!1e_0 z*^RmB{b3ZZ%^Cf5ez-UwH$_4dV@1l3@smkT%NrK?kxr;Hf9SRaW5?B1JQ!M)LYS9o zYEqI^|EBa#j|}rBAP4%DY;gPZzUfMV7;j6AjCkP(`{&$#u~TM^^IATWf5V#4ns(!>na#No_)HoyshG!-e@ltV;>$*X-e=<&KbspQj~?KF&GDj^Q~rcHQ+4uPGU`7rZX`tusr& z)FO%-26%nb)GM&VV(K1zhaMj-(+x{9Hcox|Mp@iezw@(ng=V{t>ycDso{hJHei|k9 zvbvhH`FD4VDlKxS0nzW-Dij5N+`0Jj-(i>B;ZuXR?lidDbY_1F?H0HCYkdn-7syXM z@FREj10d;&T?9Gjcrn>t)_BpX;;)W+rPeabIWP-!Mq!TzRK?iE&wD0C3JI81B;0Qb zCO(rkMqP{w#otu~MRqBiBSP}>)2>owUSbG~hl6CEbBgz4T)aeVQtr$}dy920LalT+ zg!TXinQm=jzuViFB?%WrxU%-&wrGcDmD^yS8bt2Z`*j-|J|Nqi1W7>Q?a^O{95tSd zTppf7whGGW$T*Y-iNzIzM=S84hay1&KFaax^Cyh! zKrb!^L@3`oP~_pbo@dHOz0a?*X=cTsf=RJ)H6W_6E^3=Gu4xQvjL%ZaQbJAOydM$a{KQ{Q zFuY8!gwMP`V0oD#%^`68d`J9^DOP@?#HWC33l*C}B4_kRD-;1~Kw*7Hc!5aSrQ&gy zX9MtnNrZ8~lNc8h%c4{!Q6N7Zdmx?2b7^5CJkg?3QMyD=oX5iz_-U^!J`dT&oE8La zq0BZ5cpiw~m|1dQDpYp!ThS$D)0DpMIy(i4i#7G+b_3uYBkBmb+Pi^2!6 zF`Jw1_DVStKG(c0BBtmbJB1poDM`JUFJWlZn@_p?CeLDyC7NlPbIDVAI%`YS7|`k~ z%EP@$TCKsZ)lC=grq&g))OEYzxS`i$y(J9NtPXd&-FVpl?dmWjjO|~XnLVUpY{6;g zty+x}hWWR)vj|l2uXB63JYx2*v_{8Xp(3PCW^q(P-x&Dz(mSWh6wkF^{cY^hRr=F| zJo0_alcadGf59G2&}0E7|7TSIi-Qeq=f(56W@9cAAhnqZFHeFK9}&)oyJN2vU?mjy z@AVr)mW{ghsig&Uj=qgZ!6}K1{b=v?%1j|D8j+T6Jg@Za!`N5zJx8T%uRk^71E)M`HS{I)i7k{c)xFMh?Utn)~W! zi|r>)E+xbvgViYuS8*oGtX!BIvRSdM$&!n6)`129m=vAZv7Lu}pEkX>o9uYA zZkZ~~xXqKRKN{CPvBZKO(*03guj%__v7Fu54|aogQ6}#RO!v4m4M(sy70sudi*~dS zS%AJw^GJ>DDNzSZC-?p&7GZMR>+e|$qHs1^rjDNqw4-%mw>+xAmf}}qf~$ zY0~xnS>2JlG&@?pP}I?^<*Qi-{kfww-~*&mT=Qs=y!KC_@)SxoS%!XxSdwiJCePxZ98u~; zvE@VqAs!nhPN1n0A&`ggv3NFldxLzTy7g955$d2_m3AqTHO0h4v`pP}Kor ze9vwt1jb90Frlq1pzwCSn#=I~<2^c5x(Js$A!RLh;b^~~1h{c;_<|s0eI_L3QK$ry zX!um&f>gn9F)Qrco4C>lMHO_ygksJ|v%k|R@q8C<-6npJ%HOABE^CZVer5;eBQiF4 z8!;DBhk9hGvQ=+~<{0OP!GzX3|1JKpNViZBSr3`Q02coJE63n)yvbY15X&i8q&P#( zG+5rY>!9Bw112x(r*1+*YB(w`QS$<7ShznzOn!t|@0!pVsS8G^S%s1fKl0-f6#>%po zv?oYXw#yk1DOc#;16OY6}4t@y{Yc=4vqj5hP>6S@bH<9V9@29FZhW?Gav&mrG( zOgG5cEnFNd?fJ7Tfh%m+k;x7WwINyW6)D!cPc963IM{|U&#}IMLqnQrD#jT%Fx@1> z1TXSs6Fx-BH>C3fNxzd=-3{A|H25hhfj=BxNe1PydPSCL&bByyNwL+{vaUm8 zsObU~yW?!K=ccQ@^OIOFqIfUc6&+3J>a&nVuR3Nfjlt!f%75|M8x@yFkY*pMBzop- zlc*j0Lm$(}{kEIhuAuG~uxHn?@jt2k?$5*E2SnwDnN*qwBLad|_#j^1aKQ)xX)o}v;F znOJwXte#WF9dOd~RVdxzQtBQJ2dmwZ%4F*KnxX{(W+RVc4qHxuMfUA{ z7!oLXqO0`F)|me|WOL~SX@K@Ps4ExFg6E8y|1-2?J&8fkOO19X_4d~rSaXMV6Mt2Z zD^7w?Fmv_qOubaXVk|saM?tBT1OOQZ?+>yUi4wGiIZBnUPqZx#PS9R&L^k(5eG+~^ zX`{3PkC@u*k|C$?B@Ey#n1${AGSoNl-lbj_sB3Fsv0LQ8pg&Ze6|6L?PK~;=z?XS0 z+T!3XI^WA~HFg>!0gz%mREozT*QW~cTEmGu>K4Lt`afkLJRa|EU+uHAQGKi%<;~rK zwk2=h&&%SwGD&4V!37AVS@ACaXjwk%X41O_7)-AAyV6#ItOhU;>h-+4E?=oX< zsZ;nnr^>9{K95hgv-nKJTe4z9;80iMgqXNuUe|xO_WN*jvulLE3$jWkxgtJ&r9R;1 zE8_$MM{}!_WeG1UZ`0xqq-1TrsDVsU{Vh)@~ZgLgwHo(zC&(aaevsF4J{g>Th-D`-rJ>!4ho9qgNET$#AaXI6pWbv0pgixa4fUma(XnAHM+_K-TVSE0=iW zCx(`(Ts!epM5&+QdK^JEs98ShC%wf4JYbmdv!ct|X~t&x-kt4IXsY4#TJGm3c{)*6 zwrEUVhtg__2s`ng_ZF!Nf~f3DSU&8(#d<-KxlO%(#PNLg<-88VH|y`cATPjYC`>V^v9*}0467_yvIiLgv%for#}qL3e}rle^lI7nRDC>EMY}$pP#sS|GsP#svDLB!)ttw_am3`sm$=DIB?(|HhN(3X6sp{ zv|QIZ!+*mphIkP!g*sS`9qgN_$bwIa!_~JvzSO6_ul?_u;8dZP8FPnhqfZK{ zVzvaDOXP}qFYKo-XBHDh{XnX!6dpgv0Sb=Rba3Kb`F#@Sc#HFsS*e~2uJn0+ZjbDi zC?C=0)dS1e*VO#mQ<*2LVo_rEJLX({Jf+07Hok@KP%`vNbn|dhggf^Z$7}&|aYB6- zH{bfV9X_Pt`wDYBukPK7X$2(l-~SS2USMpE3FB(rE-IFl3h5#y3WkOx912BKPH8AW(H@$p$xfHCUJqQqTK~@}6 zx!{(C^>1;&9U_6881eApnVU~cI9XL72@+QiX~U=|B+H86FJ=RRD(Uu60Fh;Q7Cpuz zUKWmBH@s1n)uRZP^_L_(@CsM;(8?Zn2449P9-oA-FWD*gvW1xNI zF^SpaMDpouNQPL!sK448L#mu!C|BV&#hnJ`K7B!wyy56<$`X-|sd9}#bNZ<9bIL~^ z`{efJ*oT{5jz1by-iq!NF-7ySy(k={O-N#LKNDMO{E?Vo>`0UaDh;kIbpIh`-Xa&#x_fL9A`0 zz-K-Sy*f}1QEUYLjk{lCNS%iiM2V%6;ck3aA9gQYvwx0%xN(#q`?hZKrfyus)9yft zD4tKjAM2Z{qwo1NN!NdWPs4X!;&`d69XIBcz`>UFm$&_E-pQ#FCo7=fd|da9P-T(a zxhC@}134y_*a=8#MfH5|<41q*h|3NvkTr%F2`>UUZ+dC(OaSs#6QF1P&K68vGMC#; zx8tmqO5biQFHjcCJ|fTd`)tH%M$E7pn3Z3`ln?qcx)Z!Ef>d1&s90W2(Ktb0l);)- zb|4^t{lVqq@Kh@}Ld;mFxQ8*@(g!8}u)DW$jxf$@TGCAMGXUO}esi?g4QUlZ50*V0 znIb&TX~tfWpXRsi-%f|1<&{~{Cx7MAm$(DXR*(~k;4<5TGevle$ip z?BZFXNYS^)IbcqR{zY*ioG}Kq0S2)F&OGp9}iiwE!*tB#a{*37BV+CHorf(nigUuk$0ek5;W%zLq_u!JyRFi2VPaNN5 zNnaaxy_{PK6P{hpm)3DjieN^Iv(l+P!B?-Obt>w(3!4^vBA&88(pQ{Y8^X2qz(X!^|ZxnMc`seamkF-U5rJeQ4=qk41hEVGBpC?L} z1uushel}X`Ppw^V`SBroDP>8hRrhdsDJNG%>XzdL%jzq;iPQ2*23u-088HK(kY-Ga zAF?#fulaQ!94ud?KQ3+M9O!QG@xF8 zNfUY#G)s{z8?iofvn(U>DDs>PkUPk1t`1r{Rz=1(1&^xdnjAJ7g%UqjX&ifzZW@2F z56_Hbpw>wTebN}|M_m_qWV$|`-(a9W8UBV$HgE93`u+MfzG59^18?_I?gDL}O>8HD z5*uV=!%41-IY$!?>}l!6y@CFgq)+D23n<-`S=R;N{qW_1s13}hlVt8WOHVLo`nNSE zj#6wRj4i0=>X+Y==k`_w?d7Xj|66r@bh}wMxNXp2-?n#k;0|M@lPm@sYi^CCE_a;kC7RHG$%wCM!ELk>KM} zSZ=(!`$OvqdALjU_Z8C1r0{-9exbY!W1Q`>NO8!&c7g^^b8Du3j+JSDMj+;~$Cy_G z%GYmhwncph78!HAN@HO{@vB|mXZ}dEa+Vg_9sZ;R2aT0qOo+yUAXT zchY-_)P_Vhkggx>vb+74y+#6D!fb6LO#^H`wHwirjIi3g9CPgX?Q+e*EIzC6JHM_@ zzI7}|0^R{XSa4VoqLYEI{dg)TL46=!&MfVNM(C+^qdA4Sb?2}*P;cdI!uHDVCOv<0 z=Ol;^!ddsuJyHh6vHP^24ND$J)d)PB%D?R zj`}dh;@7hk)R(9{1-|BFx>YFqmG?)K54Fn3#U2jdWc#c#IhcivU^oMC1yi}MY-0&i zWxkFX5)#jQhL30}uh5P)%O$~(G<02bg#x^~zU@I15r`1PA(IL6-J;W<5C3$P(zT#GTof6x|4(CWEzq6kfiyFSw>USMaqDUs zMkb*Cbmc60PD>t3_YK~k}(tT=X^oxRwht7R> z#Du`1&yT$6N0Kkh&%*l9FI5}&ef1lCxV4HD7aB_CX9AHQkZ zF6KCOM)zs`X(&p^hZL4#k7VtiKW%}#{2tF|rU3uoE_=OtL9@sD-4WFeLScM3l|)Na zL1-|?`o)M4kp@rJ-3T5yG4Wd?$^QCXzU|a&6aGKGX4RNB2yC`A>tLfbYn` z;cp$PFI#2N5vK0q}|Ixyic!t3iddeX@FQ?^gPFrP3L z8z}iNj<4lt0lKYM=Y$y*fV}0;pLf&mHx-+GKlO}C;CQ{i41@~d3-ZC{=PX$!kUZ>0 zsa=f)d`z~Hrbq46=Kla)Is_=^rf4V94E3ufKO#Yf_ik({wy}YqFuz5fMqD!zVK|oj zle%PmkZh#>;I>{zdQ~u+7zs=3|7#v7P`^ZF>A_H!3t*<^ZhA0xwReL*+h{e;O)@y?zVm+pxw-fmR3FBzs zi`@QuC-cw2=K-He9&yzNY^~+ROFsAAp-=mG@T-+08ag2lTT}cAl67a#|F^hiA$V6x z!j~-J>ph-bC+nBUZE*YLn-IDD_AOGYYoe=~d-qkM>ad@L8zEoxMO;`K6CV|;7qfX! zjiXj4mwMW!qsJDro$6viu6GMXp*Fq0{wpt6Fz|0lXv_J+jE1nk+g{#F2HgRYW{*9q zfy%!QPnC*g1!vy`yP&@L4L$dSEa-4e7((USa^)WY-T+TLU(dEwvYUW`;EFz>iLq%&@ALTtt>^gGmUfY*PVslx;u( z$^jX%s}uk>rlkG}&+sT8)z1rd9guLf+(;Sst zgd&T#a~mY^5^J%3YF>T!9mcw?azflvBUzvZY_2`~Y~c>en6vhVk}^7+Ob;-+S`ziW zvpq!K<6EP`xOx4A!7q|(80L3ecL|vKM{@s8xTc^IIxi^SGIle;O~G-gsTr(Z!&`9O zSuXz!iTDd!^61zD_ffiS%jC`GFM_SQM#dumYyABQ`i3A*SakT=CQ1(0IOn_X6*i)=}A z;$R#Rkf`urUK(fM$nxh$wPG^sNk=3A=XO>uDE;`y4s=%R%Y>TjZ;8U4>{&sOZ0}v3>uVA@E$oX^WIowOr1^DQ0`)!J*Gf_=gThN^ob_I_Dh8U|nQH5D8NCJK9HB-*KIah)6aWNcw~_h&7RFeNKh@)j#*5P2?? zh$l;RtE}a==#t824(OQVV(;~*d}UBurImx>3jiX~@OVhX$EK(#FRgTMm_{0LV(Q&L z1%*Iw-6_Vb^$*YgBw})T3)d29?W$q*%F{Nt6iz*7`iZZ_w<#85X_456x}Q14e_*0qO*?Lc>6zjc;i1%GOW zmSHoHqAS=wavt1?3X^$}0KRp^6k z^@iDI4sP4Dt;-5Pz#j3O=?JQWZGNC@-HBp+YQN_1x~@3JVD;PX7JDJqS?o|g|ACjE zR>A2#h9dkAV71J_lw|n+bhB;&o%G|7yqdaR!gJV1<^y7UvxL&1|1SLtuI|GPNIBZ9 z{4hS=%ISacO7FA_{KnCwa^r9-i4Oqb;{XoJ;Gj>-4Ob90Pm)(v36=bB&Oe+5eC~on zN2vL~y|b-n4Z5VI2tSTJ5dvzeVJ=I#cDSec`Iw0Woz7kwZ{wd=6@La07GE!1i#_y_ z(4w9V4m4!te629Ys?2&>9=6?lkQYz7=NELaxcPz8|5owwXf<^+#{$~MKB)ekXN4xd zc*I4qq(Z1)Lw*db_ftoHz11|N_r1>AOpu>XEt$lkE%*h`%9a&{q1)h@I@Z zzND);U#V2mY}<7+17$Pjz~4}u_@j65*hAG^(Xu#Jf2>3;KJeFM+7NU9|Ml!~5cInZ z_|f~S8u=V;)Dw!QaxR3AEkYK77V^8Yxq$P0KWL%Z&}-62aZce{nshfS z8h!lUF_^O`R#zkIr6Yk`MQF7gm=tV*KJYQZBrqQO5*-}0G z^Dwy7P>%#7Wx|`Slm`%-A@?9)?sb3No((JseNnqZ&BxUFY%2r!n!9fLXAMA5&`8=b zR{2^H^;z6DAkPEg5bbk4$7ZfIViw9N>eSn$DQm9c?r@{xIPQVTY9b@U!?B?Wwky8!ShM$|8-kg zw|W%oCGUy+$l|0~`>%ba$?IIbqqR?in54|U^Q?qb@)U=}&$Zy+ynNOD;3Mm!ZOIB2 zg{3nMRAE#uo7ntwO9lcp&Ao{INP30}1j%h|h_kSRCjJ#_8YIIcZuYuVqAFJu<|r)j zid#QM#iwLoZC;$0JuLli~=iPgV&Ay4)tcxM6Vm_*cjXmm40#Zo;&9%zGg#!2ZAl})}9p54vwpyp+t4!iu{+uLXm%>r$b~r)@)UF@)^+9vb z`3040|J%9L92Z?7U1~O=%5)Y2dH9x9aRl51@<>gHHt2+)vC7k2ukVjp+l`uZB{)N=RD7IpZh-7^}Yz7nv<8kpK!Zm zKAVz5)cC6bhTGgr>VhW@nT6A%@Pv_RC5=xnSUKS`yjqbg1P})1EgP9K#JZd^4M_6S zD)};TGP(7X_<8&1yQ9#w3en=DOH7ajPoewMqh&G*YYVoN0=-0=;gYsX;4Vd<51GCgGKW!}ae(1{b3D020fYD@f=P@%`&`2E7gMh9 zW5($l?yJNIFU6i1nYT6JY*)A@5sZu5>`G8F<7s3+giaXA_M*!s{Yh)j*;5B=I#)}6 z$y}lJ@8ERFk9bzp)I@tc)({Pz8K` z3pA=wymxDXu3+Z=)bmHwl`D9^&Ks*{!6j3g8|m%_CvRN3d)UwayypFPrZmPHBCaiY z7#L%r9M?R#rHmuw`^V+LyA_J#C2;doic3R{fQe#uvpR*@`oS2t>Izr8VEo^HFiL-LRG(g3#-L`~+${<`FfE z&!`SYJ}fsUtnN3(5`QxwYr{dEud-=2be|fP$V<0bZVv-iwb{<5=&XPeyMoI@OT_w$ z>-maQJ~yk8s_>CDWCl{ptn5ehmn2{czx7#6r?O03m+pVYT)(d!`Oleb-1SMV2v(Y; zI1==2#oYb}$gl0-nb$9e>7HL3pG}^8*d;oIPuwEIyA~9ZDSto zjmIoUBrE;LO2^Z{)S=m_wG-&i>2uLP{gg8RnXr)Y*hx?^yvBt5=a7j$ljhr*-o1pV z&9=dWN-DX0!669Kybe3E@k7Lh`sdS3{yQO(7nxOzF!`0J=Ev7cYMRfy2m7WyvO0ZX zh2jT>oM9F?8?>wG{63xZ`a>GL@&^kE0?v#W9ZbU0V4T2h7DA*Z168>FdnNr84B=PL zN%LG8vi(;ne?$Pg0fqFKkSwUUMz*1rEl-_3$w38nBkrWGf8#+ zd(NSwcy1M*Dp~6 zY|_=QO$*U2$FVxZ&D*wv!2p6p5Kniip~s(OazVH633DubL^HI6#Puwoe{<5oSfjR0 zRZ;D;kh+goL!m&JLBX@{a_X{I3uugk6K3jx;! zxFe|sX1XsQ6m2<}%NOc4c5e}EV~_>~F9rl+;W3+QM`I}ISD?VO^9uRp@R zk5V98?h&r+oQ`$HVM-n!X}~r9I8=9?At+o>Z)yv%;+>L98XzmZ%RhZsF5yslqqoV0 zziB*o;VjY0CI5bq?luXW_JLf*FySOc>7^Rf^V&?q|DS241r-5}V7m^K?kOc>d^(GCJv(;;(JrN?=3&L6c=ogS)e7lf^48 zM`+vgahQ}eSldyRg!f7LULmpIJeH0GXEQZzZ|&pz019jP*U+fKwP|+ zyQ?FQAkf#|ax9f`DLTW){`z7d5ab~feIej19KYJzs5U*O_pITFE>8;qIi9XC{SaBIE_HK^6L3HGqr7AytV+{!#p;M#@V#l8nc#WIiG%GaBe z2F~^!4krv7RiIpr8-H`t0(gh^2K_bOe_DVpBGjx88P9SDGg>NcpS|?+>hogfgsO?^r9u_H)%Y^$}03ffQS4 zM?cnz`lMoR)^VEkp%nNhc@0}{o1y(n_PGY&P1kAumAnQK>!R8rJ>s3Z$a&5Bb%m>` zoiyYV>OjoycRCK~1zzs;5<*JKJ?exjv?8I!6DA)-KwvJ#O9l&lBIhNyolr1{vQ|ko z9R$?bf&Fyi2(rRJD&9VB>2sL)St>VH90D$m(LX#4Sj1`9YJMasbDtnU@Wn9Ku-%*2 z4dF$XujcFKk7fd4CbvK8oQj=0{Xf8DtGt){mufu2mb@)~X1(Z)bi#*Ckyk1L=dbX5 zR&c*mw0FoR(3VtStL=u=8pLW3ysXQg+)q~YIrJ00aW|d$tF^FSsXV=R(izWX6@O;C zSiY@E^wY~@7J-8G_}S!m&$Co0rQD1wD-IeyvbpJtx2rYq7+k z%7+x2xdjPhG0Kd=ep4{s5^7V{qp8YS9d~wZ4PF6BJJ(EIB5=#XF78bLDWsk&k=vO# zRQQp40ri@za%sJLry4I@I~%Q*YcEqc<++MI1u<~KTbtWEPjVZdEoCjN#pA%J;qr_O zvM@)FK0*is_qxSe&qQ%t|Ln!ZJ1{qA6%L<%la1cqm^8yFE0(2n<{(c9?Gz4p4EGve z+Z)1Unv)l79!K%^!{F0$NyDe#tDNYKlPtHi$ex%YzXtTZ5iNf2>8&y*FnLEBt7IYP z6=lb5co)CI)TaIm@6emoUp`9bU8{G_-&YbXSF$JQoazke+9SS$#m9s$d(1>PiAG6ue;3TCo-X zuYDqjR$}vRgfj&t`qBct=4H~*r0I43l3Lw?os!3XPgMqv1-bmfB$sC|j>U;HmEInAAWsSQ7Iib=x6G%N<~45JbW4_?XT`M#ml zW$9(#Zr%8Rf2-U~&nUSbbEJvxzk~m}Wo1Vl3wV3D)NafBPD=hyUx3bLDiy0Fr7U6W zZ15ITLY-Z{3j~Q{OPDRt$DFLa;fA|^HzjVRH3H-NUbk>lrhj#}l;A3|FMI8e@yghS z#}=dw!Je*5U_P~_J(HswfV4qj0?q~qbC6<*4udP!!l`CV-qr8csk%;fKqVK%`TVhF zA>;$uQ@)FCVV0H8?6Uay@L54fzn3b!X)m3XiA16e6{!j>L(dK+2P=?nz`oSe1gk_K zz;EjOXckA`BejYet1rQ4<7mYk`q;?5O_*AScqK9(70Jixes56hZ-0)s*RFKH(b>1~ z;~%YTB@mZ!Uh1np`1?6jj3L{XH61Q5$o;VK_tp9w@{<+iq5*(}n(VVov&{bJF?mRs z{_}^j0oybIDhj=sdoqd!bw!64P)U|xuZ{!uzT|)eiY)dA4WxL3_KP{oB$5h} z-`@0zeV&u=AYJZmKQZ)`41^l5WYeN`PmSVLe&q7d-*U)|zP;w^8R&`BRu$y0xbL#& z)HkpwfWE_4xude)QN;%kud3^A8k%+$otF?p=m733(`LGVqchP{;<0-}H^Go{)2=)y z+(I5|!-Say%F7EOP?Hz5$DVH=ElKhksdXp%^@ob)g=6?dYZua2`g2I7+;jUoW5~3} z!BdFaygHLRvU^tVYvS1nJ`x&54Jhl@?;=aSXXN4;_w1lK!Lu8_F>h-Bi#u48vw}Zp zJC4bGniV{%h<^haj`yaGll3u)B{xKch@-X zo*RE{G$3X8SMeh2V0_IS`)+?&binJ}m&GWOtxTeyihX)Kznj~>hNRSj*J(&5G?B^8 zCH&*|mR%odW5Ljq3jmyDY8 zUXhO5pt`RmOIN2v8DhoJxAp&R=Z1AGEycwLl)Cvoa*J=m20(ReC%eN>w%8&(wwOSz zhL=YHI5-f_xj!h(uDfrGOB!FYit2ptT~oglmk%O^<5hRPkQv@XqZ1ygn&{uyu)rwG zHrfvX#7lFR>2-RTt}b|_cnwRk40t=ePUX0TeDR-26ve#$jP|-j5a8bBZV!po5Yf%Y zF(7YS35u-Ypi=`HM~!Eq&SC7HjP&&q{V=b=Sqnd;7m-P|F90mqMa#nSy3L@ow%ejs)m%LY?C#g;ffU0P%QIL zhpV?Ab8775-5>BN7WcHy192D?;EVYi=(PA}@iAA6C2l=2-B<}R%c@V2Ves-(YO_R( z1WaW=Al)H+#z_I7!h08|Mht!#-ZAfxj{+1B^z#4xS%<>Fr${FM{Lx?EoBI&3vW`Nx zw{Ew|t9J;aW?a|T7^1{t>!}dmkQE~9^kL8+cvpCeW(L~UOue2doc6l-9P4PM;50VO zv?`YR+9jgJ*+4{9ZR*4w>Q zwXZuDH>p6#>4u$tF^nWWx*f=#K%A2zD_l6RR=SU_#;_~gN><;W48PdI=l;im!&YHf z#Uv)+L~+c}Q8mNBkH?{Hf2cBqw0vXIz7K~>UlVx&MM8g=(%-byoT^*mAq|i-CdS9D z4IvTJ`*aiTF}L3Mm72C6C+T1~Ryx;s2?y)nOEu&Ljlr8w`%O7YI9yv#$KEU%{G16XSYhoAWK0h=CLTwr=;z3v)aV=ab^f+DT1ZNlNjHi0BGXu` z8H-Y}BFoQoWxF>T=euw?*}FaKs6hM**97Z(G5__v@J%v9RGWMsD z$F>(dpLJfLU;HgI4wpAoji2QwRc4>-4tUEMa;ZF06wHHnz8h~`q#AY6TH}ld-@Bw$ zeEIzhHeV6SA&jn`N8v1J;hr;*X;meR1h5C()-Qn1;fqEp}jDE}J6pRmnv^HC5t7 z4JM;%eLRoeS_O7|wQO!q^4>^I=wl1RFDDiUoI>jr- zuSa})BU97XPeDm9V1NLrK&>fz?IM(nDJ!jG5RUeGM%!H$12?bzWt~6@U`-oaaD5Ixj(e#q zXP?9~*I8m3D00ezGv9%~9`a=WARdzi;LzF?^3pdg2g1+->p!aP?XL8hBL_-pX3(kL9Yk#MSdZKsE&b$X19AFy#}wLatyLF{M2$%sZ+M z4gE!D1#|xgh_%b)q$%S302bEf6lF_(D^7fy(GI_R3H(}p@1$0@h27PU`(sy_=_kIi z7|t$YGe^g5c3#j*x=u@7-rTap+Yi3WJ{91G{NU;tlQvw(c9E#LnzrKI%>H#hTO-3% zdX$nUxB1e3lN)Y{>u||T>0D6H=`Dh^p44to2hJfRwM!$kg|-~r71@(PC`cL^M`o_a zqCfr{74=e6{J9v$^^tba)W8CSrhauIJlEovO>BNfvjc%GKMAUw8W#Wp!OQx)@m-iA zakn)-Bwe1Yb+IYOGvRCK4Em}jtK`RHjIL_9_B(Y9wLhZ}cq6DK!FM7HP(>o-Qq zWnsj?o>NE zw(U2V_XM5_seTM``{2c;@2UF$=Ehvlxg>eBe=VKM+RyfSZckT0PA1V+VJ!AwSkTPs z0{=#Jq=Vl@tGUGFCJi|L>VQ$z{&r42-qn4bp1A{(`xjVhL3kex-y2uY$SD?DKp1l0 zib~cXA&abL5635ZjJzzWCj#W;AyormLC-!vhvt*d)F`Ml? z!SS(X`k+$@;;=H5z$Uc>kl%U8$;Je{^prft{vI02w2(jaN8um%-n={M#Ffu){qz5z#BS(!->c{{o&kFLu?1S@Dn0!rxsZ%l6W};C%S{gyID$b|C_>ChY;Z(DwC= zhe~;`2FZ3Hd~d}x`-Xe^KLXk6tER12W`^APeFiUw#umh9Spj1g-+51KJSaj*Z_!FGihxXmf za+M!lTJlNnY!3Ud6!XV(D`7SYXQ6ENXi*UiPo<^KIS7X;TiHC@Cy@bHGgA$He_!rB z`|ovONfxzMyLm;!uq|}hc$+=(C{)uMaeW53>dM9AXLxJ8ke!N9;NaTe{z^UJI#jW9 zc?~Mzs`cg_L=)w8*qn>kjO$~H#}ZaU9$Kq0)RjtN5*JYexAU!TrD9!`DoW@6Ya zjk`B{qB4sNM5i`Y)5~8ROm*;z!oX9_j1%%4VlfU-AD!#hj=$C|!#Y>j!DkDBu|5aO z;g(y~r(&*r!i)D#b!hT~^K94hqvKoZPNCPJkG+a}3g+!;X@CN!oss)LU-;K)xnTGhMIyH;Y@0Mk_C$SL+@TXCm74 z^5n;EFzDG38YNi<`-~=F4j+jK(`th|nq$AR580wypchMjS$SJx={A!x|JnM)7hH_~ z^c}GJA3^-Ggh;I-01|udkqqI7_Su6ZYZ)>xhqWmkV~BH_dTh$MpNXK`opLHY#go4Y zyw5LjNB^!D+J5LIOFA|O@>1lzCX*Xyt2}P(JgInFLCY?g&e8b9y>*WDnt&44`kUZ? ze;5gHJH4~U{rKeBuZkiP*25BcJ;f#J=0}vwE8>>RMqS80BJU z_``#vMFp7BIaIi3Th{djnWSJDh;sOwohr6}jM zj+b7t620g4^QfDB4pSwIM1;3M;jEK#Kr zYgLfXez6XY$)JSCn}>LY2DQ|vOEli-<>`=Oay@pLzj9yC?A)eF6o{z9I8F{08JHQX z_;a|z4v-bbh3^!C0^HbLDusx7zwQZ~L8_TVPX5N3yDo4wduBg-RiR8LIeM6b?0XH> ztS8JiXM40>bIDjt$3N`17&23s>OG*6&2&Do{Xy?md901vCgg`EkF;7JDr+>i(vZQ9 zG!;7ZbbGWM02^1CY0_grLOLqu34#I%o(n@1kM_+4g_zdJ<2fPKK+!Y}-p&a*1 z@n1>2Z)7(nSn1bJ8A>&|%wQHXkMGL=0_&%oruzx}Y*%c`;D{a=xHBto^4ptU#@c5N z2`B!kl;RB3IoI}C<~GehwN=A^NZ!}B@>t_%J73VFLpH8_x_@cF94I=J$UeF9dp4gm zdIdDkFs)j-V3eDa6}=c6F6j%4 zV;R=)kAwakA8p;9F#70q;+AgH zS)>w3*|cB{9E~l~P8tq76JfiCszJjk2l0N(gHnn9C`_fSdMc$42{F@xjeJ?zsI!b+ zA3?n2!uy&97Abt^;aE?L5fBi+Hnl0EQCA?VIG!h9di%~kHHNFO{dMx1jBP3M=Kla# zl)37C67$0t1R%@tVsFUIVr$xwoQ*;`Yij|(W_CWs}`F+ddWCv!8lAs`Shm4C*vzxACmkgvbDdC^FE}&Ks_0o^0 z^7cnxIo|s{-ju;fIANR;MX=7W25fGA(b-1)gyj`n1O=@y#LeHN?|6N!6DV-{pMYhj*CNk;7%|Mx_Ya5cjy0Lp1ktuBXX`{Og8>3zuQ=nnOAsVTKo{Wl z(Qg=l_~CRl0@tzuP8^lpYoO(Q0?li+ySmvtq=G*xUq(-}h!ZUrs_B)afkpe>{bBdI zLFVxi%!4Pfps|&5KJ9W(z8kNKJ%6mJXb~Q8OZ(}4hDHk}@?#Ov#oU>lig?oAw7Q*D z`qZT&@-5ZFyn_+n{Iu9BJ?@B!ROy2jWHUIV6u}>20%`=r%3WTe-QKoo5=4-MAM4vJ zimrIn^`LiLCo?vg(uvwe@v{pNV$*6~RJfwOMsPL6^P>!TIfo4=A=y87_B?L0dcPbE zl%!EQ6xLAXYVN@#);P4=VH4ObA`nSg*08?fx$633OD8aDH)RbLp;p$XyHUhpJ>B{I zkzWSb;@4H=DukZv#2c(i!*K)B2(QWbq5}?Wc#+$A;xyZ_0d-aO&vcl1X zzVs)@#dsbpXJYaDq=ZBCwkI+0qpS41C9r-hU(iUP?Qu`}jc>l-+fGqd-!v{}w)fTtW6u)QWV(`kyVo~cS!HnNmGrhxyw}}c0a2NH{epfL{l-ozxR6`Yb zC33_({RA)vepPw}?Xu+cUznCHglv^w^e)@9e}IW-h+9OjM;YjXx+;3* zMT|v=?(t%I13jCxKX1k_S#R`x9>Hh(qsz&XdeIJaEbx47E;qF-0Ukep&NeDfSm4>38BcfKs8Ye;?J5=IKMh_6t(b3KL5uI|;(;{b!!&># zEf`BIRk&!(YyinWij@t9KLof*?53=%W#YA{<I^(jwHG9}(_dN57}ONDF+J za~ws|aQs+p+I7*a|CHP%2SQy9ZnOD@QpKx@lMh$>8y^YGV_|U6b@r0IRJj5ha?2SK zgz%3e!E{=ivZ)U%=Uc5ZGQMCPg40#C$UilPCXk9MkF{_r0Mez|cr-sqLP%&=1!TSI zXT(a;@VG0!^k8>W5;VZ=^^g@`g1(0>LvM1QbFKdrb7(N&R^)YJ{Z#r6v8pG7$d56XNZVSV?_PcHBq;(jvC8j-_^i}u{P`2nd^r2Kak&B^m2BE>uh z)Ci)*H)r!&u-9!KSYpB}jzpdV+Ott5nOqh1) zIGbPW#7{*Q9|pXYfT%pFK=|aizpCua95kB}#R9wkE(%sX_FZrCJfr*J^Hifwny^*# z)R&baR|lz2HVh{#tnjmEED8u+(W#K@v<2toRhIvLmFXbjZJ{6gl?5kA5?tp2FYxDO zg&JGtl$EX&{dxw=L!gOmnB+gcgMxV50*~IW)|Huqocyy)MK?*&TkC+(Ftjt>Hi|nv z_6)PjFb$i5H(D1>;AuHpSJXp0+Ovp-zqkBTyQ(0_!0YjA2Yu@RNn}I%3;w#aB>tz8 z>w3`JUu@^%Sw+3ETQ>qT7)R#L1wAn*%p~rWdr=EdJ!;#1tdYiT{F*x>^(BHq%xw@> zlnGyxI33_Vp?*=5MtE2Mt^RTE92EzgEhfp$Uq8u1GGzZSManUXKTb8xaXrd9iY4&A z35(z9qGs$4*_)Je;q8hvNwNcFZ*DB1q(|`rFwKqPBm#LDksxFoP-5RE&V*}%dDYo8 zDG|`+*nTG0hNiOj+G|3qu%Wlj=A=Z>3eS%%iy(s##p3PE`7j^e_%Fv=lB8!-*0Haw zEeQ7#88CBExU+VGi(#II>|Rlgt|aK)QjiC>d~V*dEM3`g%TR};u_e3r1*IV|bI3{n zo#&VuZ;xLteC}K2S{!~J?%HKN*)KTN6cDqOK0Y>WC@*i06y00LA}{Ar)&XfeJU0#* zV&9egpgWszu@>}lqy9P(TbbnS>1GBmT|L%Rdx{KN89u|k6uYsRhcxgq_cmz+Jm^s8 ztA06;#2ww0bNY=72zi-M%wS8BGqo}I$}Tl|oGm2Tu+@XMJilW@gasZ|Q@QNOl8@SR zev>Tm$1N2AXvCJ_ZlNXjr10aT!vOA2=CT?BX-nFIyTAPI;Kom=ieLPN4xgs*6d3f4 z>5x`_nP>qasMNyy1_SrF;FcSE43s?YO9>{HD1krr5`ctCJaizab@={FNi_sm0u~e> zGR&j{Pqrj)|+DF`0N+ZkA8-(R2um0n91##hD9?Q`= zIDj%7$1U(TZc}ObCjB^{>NV+ZyQ!KuvaORRre9-^4$iXviD9vb)<|0;%|5r!7kd@g zMBbeVjltrw#>C$JTMDi#KOH&YOG3RHIU28dp_J@(S_{bqpV{5-zj>V-^RJ1>%SUn3 z`^R)qek&)~-Da-ha* zv}bUw@)i+|s-SV+<`6baNQlc$>&Vo=ns=I=K>a%$OuVpIa;(XJuYK_B*3?)b@G+&@ z>Ma?m)j)zcf7M?nwbY>l8WO96Rbk^i_8BIM3Zm#1EAN07Qhm&~s6>7)+k&KDzd?7b zG0E|-{Q-h9{|Jj_!ha3>TO91(P%rO{JU~saTzu^$<;Xutk=Xt>O0D2+FexvyR8-0A zX*guQo1ktzu4R>JE`{7(N7Mq#+FeX%H0s?{m(J0`l>eg6WyRP^)g>9lh)FpMdrBX2M|{|1O$yfuAnW`U z4eP-nt zbZHzd(3<%DFo2!UcpZMEoAjwM#+ECd;SLIP^8}CI;7c6QEZACf7sQ5yLWfNa}j`k34A$hfYA<*Geies z-*IDix+;8u?vw#DvJQ;hY@rH~$u8$io)!mSL=t$rJ zeLIs@k0<2|d`O=3n_I#XMv{Xr@mivH-(KuxD1$;Z54iDg4viXgqHi|&--|y(gef!J zvsrQKk3<_^(>{Xrh~E%!yEt3B@x^`@*SjL~x^t%wB6L*bd;Qrg2{d*eyuxCdwXK@W>zS8s=@)QDXInvCog*3p~tD`Ndat4Dh>45?OOJnz5SP)z?}GxYRO$oX?BjL!vXQ3Cxoi0wN`EdJdu-1 z8}~kS&prnG)L+*hsrR2#yC=H*h!KRxp(URWh$3Zn`qNtEvn_)7aUA6x`~nTqQIyRE zwH3P}e9&FhG)JApsdzpoHHD9|+q6oz8p_AGJx%X?sDPAF^Nl?HjAGRH( zjlc(bTv`A*n`jXDW9zF6!n6J(^r|1t3eMY{y|H`*cxU_FvwiOV39((70ACTz-K&-r z$6AT{nDmsmOZ1(KR{FvlX-i($oi9WuGNo+!C-4QH{=6b)uQYVq)xRR4mwM;b-jeK@ zYQy*K1thOD}9d@YBU;ELT}r$f&vQ{JvEcwV=t z4XWD7Ahuwj3L{J|UdG)s(AfK9;#L86rk)diH1ToK@8elbfMA#4VujXFyAyNl@CfPB z$rC-xCl?H*^R`MZ_z6XUCiV=N+XWiJ7J`pW5q#GVcA;#Zi-h;g9TBo4SJae& zR!RNDJuki)oMA3FxOj#i?&`P}wLZ(=AR^X=-ya5*l5o5^&n^>4Z3=zsbL)s{?PC9X z?9t9Qw-QVx^W4DzzEX9F$!>L6X>?~gje7*bVk-Vu3A~WIWkAk ze)D1u{ZKg~!jc7R0F2}iaHEO;&4(!C6^Do#n{0H$@KVP^2uGp4cVhC4y?ssgGb(1R z4W85$XyJM_=Th^UWap<)X?CJ2=i{X~laDY@b_SBl&b5Xh$A!2;4t5#Y)~nCjcv_>v=0;-O zR78soXPVJbBnU~CY3K~qHItRO{GSt&q>pj#ZNwL)1+uBQQ~U=hZOY0a78%?7W7I#R zhS8_}hFnBpvc{?9R%btIu$pjgXzS`KKaSPfozP9Hw4nRtXfy5#UT04YRUwNku>ue9 z)JP+j5=yvaUCuZ{jhUAaeNP+u;Qzt%=qGh?H+1&Plp*$UmPgDyQGw#SJBUBog?5Gv zxNo5~BgAK^rpUB<#wCp$d9nN}m}n9_UdScoZi{(Of~DHq)^HTKZ)6`T5c zIwr!+yXfB@gUFdlaNN2kCUkinR#yG-P$YXBKPJF&9NU88#M*k4WALgr8M zrnr_siv}N`h0ucJD@T8yJex~1<|x>AX};YA6M2BY+P^(wpBYE=ZbBa!3Pt{DdJjj% zmj-EE(UD48DSJWAJ{s)%%3DFw%~XU1DoN2LABwOwK?=&M{*%yJf#~nDonJ_BXTDy% zqOjA766XRv8)SLePA{1W{wbM%Vm8?q`wBi~KhyG$mtyoQWv7JG_}K%YwORg(I@BP# zoqv+4+)8+Vj)54?B6oEv9|bD(H~zP`|Eq=d3m9yy_&)zPJSxLpO}HrM^Vg`5k`MzH z=S9%eAE1|7PL!7V6b{0loyobW00eSRM<{L=!Ciz=kvkM~vkE|vo2i7dy}Wt=g3KG?Q4lr2CtaVs3-3=w1XyRIO=fd%0?_ zuU!(bYYiHPlinppf+=R*ck_Gabn4R;_#J2Okf9$-T36`-;jiON7P=fOt-#iG$I)V_ zIzJPsA-$GI+{+5H!mg@qBad}(z#*MZqIdp`NH0Uj{7&7|GYn-MN4w@4OZG#Qb-mFe zxrDxg8aQS(xy>E=FZR3m@p2)L%5KO%zYij>%}?|O1MEkl%@c zh8}Mt{s)k2YJ=A}cqhb7D&^`i{YQ3=mdrVxUb(T8(fY|9Vp_F&wNtVr&%BbO#6Y^J zGolD~?Z)Z}_u>7K-J64Ne~WB-K2_2>(ae*&t&|ZuQWEQF*~3dqJl=fIk#ANpTOSVP zuC>dIlI_vb)OhYvvN;m}l)gw&IOay5v|U%+JzRD(Fn)3T`zlbr8n>L*Y3luF6e4n& z?NhiV+7V&e#L>>Bww-PP&0I7%X610y3*TXA1$MOWt;_p!kbgZye${=m`5yXP(k6@n zF8VAdN0)xe1>~z@w;Q(`;Py^T32m*6l7%Z*8sF=LyB1x@sZlYybOSMF6=&=`-v;&O z9~z$L;NCt_z>RDB;?vy>4KyP@9MG4Iar5bdxVx_O>7>+02vS~kJLK%B5{|=X&gkc!*JDzs-uIRx^E0s#w6p|j3D`w%Y~(z_I(?cW(8s()rBf#Yc|tYkjep<@m2YphX@!{s z^u*8o8QG+gSJUyQlk~!uWP(iLLV1TsWVL zr`^k{Dcyg4AEA!G);^pS`9?xtNx;jyZCh7=cC26G5cT{-3ibQ+KI?@3QT(DgX76~67*$C^;^iq3qtl=(_LxA)S=3JimOHibnxthV{9L^3v zC3WW!SY@S|A1&T?IF#+XXnSw1_RjV92(J?YP51r|hmx)Y%q4l8%739|*Fbze53&xt zQhR7j5f=6ZWIHZH?Lg#{!#|{LmisI*_X}tz~_xzL-ds(KgK8Z7x~$t_M?#bFATrNjN92) zACTa~A88Q>Oir8!qs-HxlHzBonD;N>Ll{BeeX%t0X2gg80nSRmB?4jOcutW!B&k%y z5XJIQqDeH7T=f*4q7fFL7ZkRTdO)u)6D&G3D2{NWmBp`^*eHL4j#oD;(A90QxdqY}nHe06nhB|`;Zuf7iYm_(ls zx>@;mv<4q=e5B06*=KhG*lX}OIboR^M4;Ye_+-2|~xJ$BA zo;B4Ci~Y4HH9}j%Kc=~iseLJ%{fsEQj(#gg_k(-na+s#XToqjoom|5n5v;5J5ybF) zl*sf=dM>oz<$L*pA@)bi`1NyCH!0D((<>@@0i^Z#+Q8exbj}$O$j(_NlULP;ZP=L$ zB9hfzcNni%KVOQ31%z@Mufu@el+5ikalOcDm?x}G5sn|b1CvLrXjFDh+4OKb_&L=5 zc+PfZ8UaT3y=+O~Bw@Moo$=fdxt>Tkn&-vyD9z4Qy$u85X=upVDjL%I2AY}X4z(`w9_yF}#1XW#2;6XcN;v_o#zoz_z25|Z5YF`fm*ijMMb0eyZ{93t5$L~9 z7rW1iT==&sXWQo~mVB+y9M1oqxso4$(R zr5>{~kiT26d8r^BTH?GnK{+`RDVhU0f1e*M11?)L_JfO zAAaHQNvjzg!mc*t-_iU@i;kj&l|C@}{n?<827MbMD(^PmFLWVz#r~?^*zTHcth>HT zN5TO>udKD5G*LhrbD%RLgQ&bZic8}b6zp}Sx)t*Ar$~Q=*TjEMn$ajBJDM{g0Y%Q) z@3(KJ2MjbaJBO^#YlUtc`4fSClSi$@nfI-K`#3oS$8H3SPP;lLMREi+X)rAjF3_S5 z-xLw{umh%CR!P_=-)SGZVicF%UpAttscSF)27 zF6+YYbm`mn>94 zYM{}-!+^moduQ+6>X~p$ZqVg88V99L-e_GiV&k`e#fW<*pp+>BCqDKs*HV3l%t(YB zcmj!*N~MpkFNzGkh0RwH00X{(#x1I$VaC6@eA}TM_Z$@EiyrVS%p%tn+}@yyA2DM< z0QB_cXRuji?+ZheMfs??7vl9jhv(*P@l!!?QfxYd#)8B4RRB5eY7ljfh%HtfABf4 zXcQ%=HH3!L4!yTY*J^OPInpo^e>0{pEwZ_nMR9rcbHr74kL!u*9H8LDmm&Wbvwl18LALnf536x)g_8fqLfC2&9~5xifqF-uPCn24vpWk39`3TNK$tV zWxjE~g-*U?DE=Qs=l;m#|G)8>VVl#;XmZ+S&eWVjISg}{Ga=+SBO<4iQ)w86Va`N3 zMoNwyC~|C$Q7ID5vA3i`k_eygzW>4f!+qbc=j(c2*W=O#x_r4C!O|ipt{!&Sb6iKC zKZ+;@H(=c^FvF94%A|ELTo&&o4wlPgYm0t7Tiea427?p7oW_`eIsfe8P*{8F_WmI5 zOyWm=Uo}Vy_TGuzUL$~Ne`nmZX`UZ9JobVcj`rEIWb@dEu4t?63O590e9`)&5cG8`m7(;LR^mSZ@FGxM3#tTwBNC zKk}QF9zrDm=en*`bbQR_>KH2bgJLXQV`dO{N6*sa+fnWYg&BBc9EM*%0 zv6SygJ`er7f|3K|F&dYsB`Wu9mp#e5aAnBp32x9kCE4OHnWO6pYU(nRNBxgPa_78) zwJojN^#ARTa6~b%T{kvV3V?5O#MHSji>A%Y>?NUsqV%ohM)E*m75|FnJCP^aE5?ztrHV^M{&H`geD-T<>rT402m z#;u=tX!Zl}oiDR=ccdrzzC4DQFagr}ptac!^WjAY{~+ZC@YN<~6i=N}vw0*$c`^7) zQ~_=_tUSL>Ehm#aV{-P&7aS4cI)gNO1flLBJh!^+F-tef>8gU>@~=b_VXc|;UjK>B z@B|Ihl2MroLmgrz3MBA1GrA}%8%8xb7~>tMU8#FGAu9J%4$rI$1fB5oGAD2=-_+R7 zC^w?rHt0xGCuQD>^`X%Px>zFa_cZ=aDRDal;Y~UTt%bf8WBcFbuZJw>1}+xc=r5%|3i)K`n&F^XwZV;gtw0Ep zs+dMZ!6gc3iZQS>Fd^BU*)$hbioLP=oNRe5%;N?-qbhiDXbOiTLcO$O62E@9hXlaXJr6lvw1l=&^+2jR2dzV|u|#*-sP z`4m$nEBwH1rl$+~Slqh|yTrASv$I@6La$c&()&h9e26dodgqU4LS1oZsPnbAp3rOz zuCLJZ-cflI^jk72W#xm#g!F6S&>zEvikE4p&0_+-^k2BfzP^?SG!=I?tZ`WZ70;{L z`({%eA;}J@*7$ow){9;(gzMktp>reEM)s#=uWP(?;|DBVUhC0O7lsleQ0=Euaj`+0 zOcc$A+EZHESlA9teRXY<4jT~;v0g1gTuMDle*{PSSQkC?*v)?of1&z=#dp@#c$V#? z0xDp%+M8mAO*ND7?(7lsidyLVlQ;R$7{cJp;lOKbhtlf=103g|NFXD}^U&`zfRm*^ z)o8(x5IMcPmp}87E3tFnZ0WbG8CJM^?|i28gp)r;=5frQK|Ji;($!x`Zbxx&aZwBl zRRXgD9jo+OR$i2o))51=wh6F-wj>L2AN@1_>lO}T!4)h$69DX>yGMtDx@~a&bMy~J zcmarjF`=_nz|#{-a36wx-^?i#z^rI`#RFN=`!@PVhTSD!?eXI+nw4kqDWkcvy=1T~ z1diH(2RT*;J=&v?Od`mJCl1N^XA)gO+J6VbARGuA^C!!)Xkko9^j#qN^^RAGqcN%` zF>2&a8VXa9bzwtOLb<50hXohY2$?gOTmEI?bWW`F(PfX!AZXmxO{TgNn#!>Q$^Q2A z`Aco;dCjweX{?BT0{-zr@``quUVrZ_8xw(9WoO}y$Zc$GUBU4-oVY$rLuO6tFW)^t z!}Ko|RHfb288#k&@$<$SnENg76c#)Nw0p=#f{o?_Dp-yd(C;lXx4Q7(2aVFZGPxbk zB&b2K#wXGmX?@s*UzYcT=DBd1B*=VVUPNu2{?hz#6j94UrogGnvO6h_;?m$ z@9|bWJ7xoTo&*lKG&vX9I-fO(238Wgb<~mfH zO~{QeJN`w~MZnW`&&OU9DE50MXrBcX8WUH;-vcG)YwVYseqGm7zYf38?b=JyOfzG@ zXibMz3PiVr-3)Z^Z8NX=xHoi&jCgira}H`EC6{*ntIX0ijq=GkeQyO!QCf{HPo!c` z5K7djZ@7RLC03Vo(+RDFvf<|_C6k*-YcJq;lA5;?zDJjvL*Y)%(^4lK zIMeU;vltvb+sONVd9r$~rtisrEbw`dy`f>buP;waL(itXFx`VF-dJi}WO|xYxIV5c z&DXDAd=N>6N^83ktOC%G?wO&`KtP{SM$_SPsePaNg`Aw$)WJ8nfVp>}J!0Iqy`Y^s z*BT4+z>ajD{}MV(YGI7}?AAmF5XDgTRWwEx{r))O8(8@s#GoTj)$y6##4o7A!`z;7 zsu6gW&-yIuB%b6mFVaY5FYCwRS046{v=^2*QTmBI(p}1;w5O$mA;3D@!_D&FMXG|< zMPHI!v5c-eq~9SB8RMq1IOcT#{XXxsT_(z!tVB z$NN5f`upPG>qtM2L|@;05ks+F&ID#f1rz$72o}*Y_|H6^(&K*Uw^QljTl#DUi{P_> zX4*ZZSD~s3XBIqgZ;d7VE-`gYPdH3I*nPchPrdMEenT8fb6d+*%LER;@YF~zk}?+u z)qO!BzqI6~#2(-3qNbjZu}@g&4_AY4!ygr1)xG;@$C&UqjVLM znKk%hi~8D#w6yy#afzsSl{>^F1^bnNk{hHxxTq%A!UpDnCO>UQU)Mq^|1H~+39Aej z%Jg&K^zG7-7~>s@83!2DwYUd%e%(6o3&>k`gqGjLGs>01A7K~vsF9pP`aTRFW8R*> zBpb-bqMCIEOV}6scd+fg%GEz=3Lon)c?qLE_XiisbIIfp+J2}M~91I zc~-?eUY!6@R6*q5IK!CL8l%nn?X)i`)wN=b3QXB=jHQanip;X`~7CGpGQ0DP4{ zg?hCOTv(xxgz4w@1okO`{1s3$ha+Q1hJIjzp^kB#SXz-G-HD)Nxuu-zquTpylT)Yf z>G)J`KAwP3NP zFPY(p3caPR0&0f&c3KW4;N;!_-toYoe!_}cP<_TGY$_)1fuA_G>@*Bw33&fuFYTo3 z_SPRWQ@XKCUW2df;74c8b^c4$e$P%5jX$vhUYUu=Q&XYdzK=bM zWe;8}=2Nanrz}w9HY+4_LG?JI5m5POv4m(AAimM%p^*cxuCowI zlVR@4fRDYgMa>Ze<2PO9UPDmEO1Kud18Bn*Vh`uWu=WZlCLE^vy7lr3Zf_diumLPF zxw3MRg&_&s)GP!?DtYz?{UUzD2#1*LWl&`kQ}p}+ z7b8yv?)5%#LLYAbC~xf?x!}!0$O{m>E7`_SpTJ(hkrjF|o3n;X#vy&S!0@Q@9>}v`q|7KzeLR_W9M57Vse3w58jkj+?c{Y zJsG^08F`OZ__fy|byq{8J3@sE+!6fm74DqkY`1iIjv918u!oMUa<5~RPs>y$*AXo- z_`MM-K*dpLLhtRku%ST-wx0m}PA>18BW;gXa%NrAad3oU5}0^|w`t~aYk@3i(j-Hb zTJxE$d{=X==1y2Rei#{&rW1@nTrQ^rgu?rPjA*uV#}V%%cjuOCZGi4QhlXP{m?YLh z>b6#XG?&kr3YKjRfKZj-9pd}eNirhl5jI6ih0*~Cd)o)Nh_;RXIm1L)LZMcVeDJiC z)4Oq9yX$kN?0e5EuC`H6r%eF0*K#XDusx>Vf00)4)XRv(Pcqgk{&{c-p0OI>&BEmY z;vy2lA(E)ae}=?lIKn2G;Im1uIX05cynXDQ!{ouisFb~{6jFXVy0bq=1k+g$`UaLi z{~($MS3T*p!AY+)4Rz~9`>;EYJ|W8BKf*qf2oz@2^O(67Dh`(56$ptM=Jd-Z4`roLQd{3h-p9m;4tX-S0-R&?fy>Y z1F;9~26iv{eAF#ZO-P-FK!i{s2dizr5Xcwv-nyueH?_wRuIDi#2wKCA1exy4RZX6c z9gD&w?ex9U#lec6oE#~WxhQD2Blk0ujFq)Ah|I@l@gzwj`+@bm(q8J3%sI9_#+CML zz)15@7s=n?CeZqzcR=wgM^`wAp;)!BO{s-+K3$1bdG|v*^kq2tPUGCdf02G)8FO#; z%0_}MCLuLl?Nq!1>gBbu3CS9$Y!oiMJc5R)P8$0!0!_^0ElA7J6;*+}e=q4H!z4fQ zk?Y>BQLkF8lzzP=BFepV*zRdvxjZ$aBdzR%$r&(16p5%TP}J{#GyHtZPcIR2C?{V&T+(p_m2p=qC*!``>G5i=AymZsT(1Qkfn z1^|Ul)sYYJc6I*R^5*=%{?eM}M7B?G*vp8YqtFQ%U^dq{@sE0De5|x#LUxgz{&i7ovq!;m5c(iYmct)%F|S|aY_Z!V3^%(uyMm?2fpfhd=q@X zcnNEaSl{{4c!%O9ntKjM1|j{ce)*KCfDEG>{Z$Gsobz%I5$)`f`=U79LKY$t(ZYwf zT|qQs*w*yq|tA-Qh)SFG08J-->JE$7+}-r~dTR=d7ADi3NwW$a0pI|H~q1!MFI7^yFqXch6Ks+xT!rbv`)UwddV0yMef#{@r#?*Nk$GZ((tb zU#{CW02VwmgF{b1p!5F37$P_;!X2F}^qeP(X4_7GlX4P^8Cuf@OyDP2vg<4@o{;PCsvX zt~%w_1RfmNS_61+i7RY~m%5wq-kMlr(hw|dAF?u z6Kf))j?A8-*-u~eRXd0vJcv=fni0}l6tJQQOOm#;jv0hqtdbZ)f;sW|?CwYc?}vm5 z;VbXxxuRjrFdic?|AM%6fEf-fKXvz^JdR71dR2Kn)n+zO&^A(dyl{lwmi1$q291vR zJ@}s8bbCU1TKFVLMP>8v;A;Y-L}@dm%Qp(|82CeqhbiAFu+{6>{~lEyU07WSD-is# zojQ6?@mV8DQ_EE2?RI{n{RUL;W`uQEhzcTNhek+LwqI$sZhPS1hzZhLEU4m@cono0 zQvh+g?Z1Eby019dS5jx=m>l8b|Mpyk$7h1HV7;pgqu>2*WY-)or|h@j92Q)Yi`Fx3 zCdS2^w%uh&1=iZX59*|sn1x4ZH2n{7l4)?MQbkc?vyr$6gcI)xUhdZ& ziNB_BNS=*lr8isOvllL+{V5l&^4YOk7|Fs37*|3JZsLl3W$?KLfqgG(OTz}}PQ*;v zhikG{L`kZMCs__lYR~z3xcI0_?UT+hxFB!HynOy5w0iyb?uKOg+wt=~Yg)Bh=er`ehi_WVvk2O_w+Bn2Wp8PYmNr{#xhS4dM0^@VzAZXj)3gXD|n~Lq+hnM@n`?Dxk>2OwGysPXFnaRQ5^V%em9qGa!xG)k z>c?;Dj*as1N-l#X0Y+KJFC(2sptQ{2Lm~wxw(O&$`v210Pib;FNpy`f$D#|-n?`=UZa~5s-Ciz z)!Ch1v25PHk8gdLL5C=q<`J`#POV7SQC@gSBwn8Tu|JT0=V!kPJ?<-2?fJ~nXbW0Yl)14^&vxXP z`?K>1*Zpsnz)z)A)XY>9~Viv6^m_!pmK&3iHU2 zRC?ECq;D5I109=iK%(I81++8)?l()UTKJ7gF^Y1gkGbQO+M+Dou@GC` zBOgW|nrCad-*UZ1h^pnR5(3lDakZ~DPV^E?JN0xXd|+V(O`)Vg-Yr4zRq^ey8OQXz z!0?c*o9)r9OTV&=#3GNEG5dGbNAO9{K+pE*9(SPMY_lcqWx3=S-O7CR{PZisA`u!I z(B)y<0-r}=0QjRDi)2h$$@iaagnV_;c6RG)GL|8V*q&?wAIt^t(FW6l zi>AsZ-}rx2H+xjz1gglH;OI-N7}#iJb4FOFd;Vph{Mu5qlWzC>h7^03GGhReMKV)R zJU{Du4t-vHP`mRX)5p4>E~p(V(qB0W-)D+~;!fn4a5CC-wD-$_kb~^+V?k%t1XZx$ z0ri}#bXXSXtDtSTnyZ}1&Db$I9G;ihW9@zhB{(pHuqP;hxl0V^zXGb9j$CYHvwdx= zeh*Sz-0lAz`j2)`^xqQWYHt~>=R5F4qg~_32)MQNHzjo;uYW0PL%Wm^FoA7rV&>G634|{nI&vulycs zDcll{rso#C&vuC2Z0DlrN`aY$_O7`))zkeMHqjy zSjrfQRp$1ysfZmBHLCk=@G^W}VC2bXL&L`Wb8lU|40vC4q?c$K~M_anvjhB*^iy4q~DUW|e%zWlNG+Kn4@yfDqt zhRECaH*(%TPxiO4`x^I=zc%!J+$vIcN#!hdSZ=Vu_O4;0&zIpRiio%g?ulM_abqB{ zE3yCQc9M)Df2bfD?x7jWlPEL^|2{q7yt6dOZQ zx+OOkaNe24ZutA87d)d-3rE6Iv=CaV^z+C>_D-S zrqh!EVV>=~{cI(h_dls2bRG;OttAzq)JDOTz3*D`dydcD_MQL&e?q|eY9d!B?XSu-#g3HlcMmSP zHx;}FiX>~c03jzlCme&&#Wg*;)}$nx`zHsvg`E(;7p-~Ud@1_dKS}~T+VotZ8OO-f z=XlVYE2SI$#n=aC7?k{L|NVIBzOCo8yzOW4$@(YvfOSMo$fEy2q|%T84%QaxlO}2Vm4nM!n3>CSftoS zIN|GdBKWn{dpo3U3sqQf^7C?aAjYw>%hf1Y#=V!(d`_lT-!m4gXY z4k_-=pRIU2^@+LNSZddm>9zo!aA~M8U1??ondq2nlY<_mD6S(1A zOg#UT)j4JmC;}D?4ulJb^|=0mqEB9G%!Ph5b{YM>&-7NfgF8OL<$`#Iyc5EmvDO?_ zgKtA*U6g&hDy=-wpn%UmSzUjdHrA?Z`KvnLaNX^tT z?^k}1H@|}-V1p2Mx3?~fj^^|OwlD=Zg5(nqZZ;Am-U`Wo>cw+&2>ra~R*A8uVk6AT z!(ScU{nf96cg*jb?1}YwI>YBN^VtUsg; zaJ@hIYxPa0HSyfdCwZXod_L3S*QAnr{v4PG^$W-%u`%=Q=8zy>IT2j&2qj4lyR@@a zqHbcW=-)H#I^r_Y9O^m(%u9j6%s?e_>^r!>yZ)bM7pjw+D!ED6g;ax+(Lf zXq<~12sd^z2@jrvoJ#MoP)k)#R8%BS_NB^#6;+3xf`;1!e9peRrK9PRs7AcYp3Gw| z`m00pko6o7fEk4;@NfpedFIn_t|B61uMhOXU#dB_vE@1-Ev;j?@Z)gO3KM1!fF;Vi zY01`yJvg2q)^P~=ZRbB6=u&P|w>NGa_@2E5g}W(T3OX6t;F!)|_;J*10Cy2tHWvLcsc0S`LK?l}_uJ+dL}0PD33-BNFN`R3mi zfs?$C_&dsJgY!>+_Hp<`lAIjorn;Yk@xjVo1}z=_u((bq9BUEKu%^Z9M)sCw$pUSf zMY<`t7+BWi`DBGQe!13Pnegk=%ntnQr8(tQX@pB|7psb>ba%HdqQQ{GL3LxI=I6MT5Tn49!|hblxv`lQr3i})wBMZtwq5gH>&qOXc0|nK$z1UduEUwlU`H)^8>}fW@_>CmI$kgDYvY_=!zd?HlI&8OKR4Wm*^jUU;0%4M*-oxNE6 z`tzx8rzA{(&km2e9F1#rSf|MW0B>tjR+q`!pr|T*&Dni&0^qr0L6x+xb{W&ipT1 zF};8y&J&xgwon-4ZTDjN1DQuJ{;_lcsCIkXL$?0p4+*rn5l70WLO+jQc+8Dqx9?t6 zj{fP#B}>4>CWFS5j9qWs((SFmTzRxHCt>aKJ!j!(+h6bt@Ug(n?a(T2*v;b&cx}0? z0%dRT3GSVr#U2Z#^)&mPa)$cpK@c(b>Wdlro!;{t_X}TSEjfSXBV0O>5R+x2zZxMF z=>JpCOX$a&8h3A2xMRx7Pw$l#Sn4I6G&3XxGNO}YgEn@WT;WhrfD{TNwKzmK_J_o4 zmBkmNItA6v?M5$`V;GeLoYppryHyVF&AFm2a`q(dPTZ;`2x6}>FJ7?$w^K%o956=} zi0ZpNaigHOaMu%!isEyMk;)xZ_4pp0ulZEGjkVsgvVUdZ0XaGKjZN|ZRX!l;d+cyt zvM^52^^|={pm+~cjI{FX{-1tc$lkwK5;V_k9u6i9!02|mvOkFB@XWCWRTjxMH;0^W zxxcjY@D&&K0cTTqWubFH$3I;d><=z~_^r$bX?ir_vdM?ck`Paq^~R1CK375PG@+DG zB`l~b#vBfYH54Mcpt-InLJw1NViB{QSQ{=c=_3@dV6hxGh_B(V-=44>MZ;fLySiXpH1q)9#7GiJk`NDj}K=&`lUtgs{U?izv zP(fK)8u!^2iQj9Az7qH3#pp@=#ZDlw z`rSwnYIQjJbqDNIqRqhM({t5+4hMhwsOula|35#`rlEMYba4X=_w&DL+w#_yE1grk zO_xcML{_a$L4aJ@^Hy(Xbfz&NV1d%8cFjR{Tt~mI69|0@`1N)qq&bVn5e-M zvbV6Cb4_s|l>H#16^>WZ(0g>aiYrf5*x^V-c9(%+=}tzk5TGNp#}!bMpWL})8+_$c zwfY7J^i$H?A@=4V3{y2VI8&kHf((IA(lrTr(}iqB_>w4IMo5EqyAcfpDG&?ic?PQ{0O zimi|wT;?#5b^AS#E(Fpm-Zw<%7CsEBj!l@*;7-x-Qr7|7wa@$@WpMFl{}(JGX!pp7 z9j7$5B*@&ApU^4n*0h;qda8Z&`|$fMH7N7S%Nr-z`$_n0!H(pTs|BiH%NC^|%29s{ z38uh=8cyli0u*W$!`C;;8I^#M?LqQqf6a63!6Q{8UV<65yiwHWER?L` zSK`cs3ttYV{nXla7x?iRCI9PEeC}l^K#J`)hY-xsGG+x!%sZcZ>~l{Q<+&d|Y8DLf zvx!bZFibbU{4-Fu?*wb;8QfK4Sm)n3{bv*Qd$GT4cSwnGh8i>cQ-ic*u*t89P$2Cc zEy1d5`7Q?2bM(-y(&a%?Bkm#rXD-{Mt5_~PMO&izRrg2j6W)5R*0fl1J$I=`5ZI!l$VU?~3g0*^@_9mWC9JvFz1F;288?l`mdw0}bD zDpM!}Na{NH@`MbQ6>5wOK|E2VZ7P^(P68@601i~uPi!$ViIZGH+hGhQhnTDvCD|HX zJz9jOELOg})g@-hU_b_wG67B%X2GXiFX1;gl9XCxd20QU>N%kOSL6mEpFcQ_%UF?T zGpIZcx2Fdq?cCPPmn;xhk~p{i_LP|$&y{aDMAb9$rW^^92v5-8#xpECmzCS$-*ao` z9`x4E3i%`0ZW~%xs&mbz8~BW=*azj#D#mws!L8=-5L>{!=+Fq zY?nU;1MqXXhcC-1l)66FQXR$xQ^j zAcrUV*P;iV(x*E6uUGv(R#Hj|mycz%31+t?V67ECJ@KZucjNWUn}jOU(Y!Ita{hPB zmTa)qRjGL~IO1`G$!p&M3dR8Yd15=t5n}A7{GAL+vYyDUT4tY6B@B{yaicYz0<)7( zyGAu3i=I-)&S6n}+6Vnndd`O8yTe6}LV2Eck2}U;?%gx{LuT-TA==1QQns52%L)!#+_)-gMF_U_L6uGzbLOT$y6P2TaZ_)?RXSqLyk>f&|)4_XW)P`XA~@Mf1t>*8g_4{ zPSr*B{dz*LEr4RJYRuZ)&7&%1!J^{7 zP~l=6+{=c-h5jUgJLas2_ca$p9F{eVeW;ymZe#h0>!?o@13{*~g!{6(=lB;&Jv97R z?91?E97Xdm&aQT4*4-jhRSoTO!)Epp3d_p@-#U)G!I5P1GvMa_Afdc~4}R1mW{`1i zesPSmq)hg3W#Ryy@yo|WQc5Q;1NeqBnx2DiN%s=$US=rGeAzzs;W<}5&U1BPmuhAY zAc}74LTu>0QqM=fVA~7?_hig6g(|PB2!M0&e_?w`A1+*N?;I4?vEdh? zt65nVY*biRPF(m%8lR^mHsq*up40*~c^;CD3A5}RwMv_4a9BC)x~UxaN;n~>P91=* zGN{nuvbM6Z_PuyNU2?%NrWb!ooTOKBI|+M#8lvZf%4B|bW>(btNcBmZJfn*`yCi!k z&q$wlZ}Mwqs;3KFnmHz;C~fFzyyfsH_EktTk|>;PvR7_0kn>{H_$lOBNxz(^)n$Pe zD78v8@U~h?vAKg;cdJlksbJ_7H+Mhr9Sh5-ys`0b*gntdXq+^TTEF;y)jHQ||5X66 zeQJD_1~+ZeTT)TvyE`MfNc|cr1A+@UL;Yc%xhqv5G`~Ff$DiRXrW* z{)Xd0XTyFkl#{H+lf9kWN(w*Tgd|3yv6y3BriN()8;jx?cpW5A7oib?mptlT;OKK4AmEn>QNVoZf{&aLwOgNvxyALOm}$HI4cYZ@Jdwfq0v3DZlY|Bp7XZ zat)fO{At8b#t~^ea)VpVCn~&bhsGeEudvg3oC{Bnn`}?fUWDh&{v8q#b^QD8-=(wj zk1L8SN#j?tmtu~$&e&6LldiGWq+SDanv_65u=RtLgpR8%fiZ(Nz$g=QF>J)wf}?Ug zu&(b`T6!P(tc9JQzF!mIg1JLGJeBJLVaRY=Az9tN;(Xd;FvcqG&drFV6i5o@i~P?v zSs>TrgyV2~>r^&PVLch3T*T^H1oyLVg!@+ktww%pAUc|3Wr!7S28AGAK3O*?RdjkI zzaobl=`B~=?@#TIRF{t#nd8#_eT*aU;xzI7>@xrz1eLlj9n1@RgL71coJcH!WyEZD zv%&H{RsRLAX|KbbAxBU0A7sd1a#-QFr(&PVaQ*3Q0DRqX#kN?C+?=rZ0LN{|9Y;is zQbj3jo8O!^?BlEWH9*}__YHCej3dx$=h#QXtt_ZozOgb;$*Oc2Hxfi4zGk%&eNb8E z3oG#KUM_k^y55w`xcnzOkIN2bPOrZ256klCytuydZ|r6N0QzjkfHH_EWWWZ0oMrv@ z8J`eA5s@RO>;EbR`?dZat8!K2-tjs!?UOnuIO{S6^~{P;KO+Jur!E z0H(;TU@V!gn$K6TY7X$W*jpX;IC!^aAA_O%yw-c~h>W{XTM?FXj1xt#EJ1JKy6P#G6ZjsV|urNuqe`{L&)w(cOs+;J|o+cN5ge;za)U zMJ2z$vrVl$Fv*_$2_-M=lrFH*wuUJV0-Dt9PTOA3lY2M?8^q9zzhud}INh)-A8C=W{2%hf6M5B()$8eMQ3`N>0crM)D>fla!!N;FsPj zu-Zvp_$1o;o$rr7!&QLqzgU-r9+HkHW6qaymzXSU@JXwhtW9iZ8u?^bR@iRmo#+1k zy>SJ2B_#B0FszF&*{(*(}*d}rN^Zs7sE83Hed#$J#`B1u(`CW9_qWw=RkP0F@2u*~j5V>BP z>@|`Tsf7{xV%S^`J<#ikOQz2ZYJO7Sx7Wb|-)|B5S^W|#TeO?A%2B9oI z^XO{$iSx4!*gAvU|CyZLMDp??3PW%mjbGfAF3m~Z1LCb7UQ()RgWb8Yi4@{xkC+F2 z;3VP#rThg5;Qc$J_ml)Y)Ne?~2F?MNMp|(Ywcfw>0%2)B-Z^wHgX<+PZji4VRr#tM zXZcWy@b?yHkeS@e>(_p)=WqfnB~qp%;VKnfJ~tY4h&_A4DwV^^TrP)pIJL@22!cZ6zP1l=bwf+YHmC`G8BZKsO zjMas-w)_B!8#_8_inVs9P8KRSu{iM!kCe+PF2Z4JKqVN~L61~!UsEi?z$rV`dW(f; z;qrG3#V$N>i#TP^75#Cv>CjX7#Tr;PLw1I>B@@o^iYbPZi)rd^;qy6B^*;cQjHQ{y zQxi9ik~GR4(x;io(^KOvTB0A$mUln4nG#pCxh?NEr_v6-e(f$niJbfSmY6%}tNg;I z+gJ@o=yjY<%d$7NeFBOKL7s^8wWd%e1^2p)Qwb-lZ$^Yu2a7XUu{6qea$H|7)1VV;vbfb*e>Fp z71xxC&aGuU!Vh>wS{HoH{Bf`X&}?fc4EyCb2;*_tzSejRIR0Q@s7~|+8pa`Cp5CP6 zKe>4!r=&`DM_0HK^5xDgF~GwIwc9^fm@)D2m4E65{*}RTD;ty_PC&-a(aKNY7l?Pc z8N}xUnXUL$4vP6I4^8M{gKYeq-){nacqm7W1;348oeR3^Xeh^pwU{L-P|%SJ(dj{f zy!qL^ex(qmJ>9sYm{Rp}{B)snuzT_#pez}x8TdQdW^Vlet zb73d9bi=tZR=1?rCIL-_vVX3Wg&^SMA`G=lIz_&uTQ*LW>OyAvd zXfZaH|9mY2r2gn>GZHn#{1V$jJO+aE4P7yG4n-)mJ^5wnu$hA$9ZR)ob@m z_p#9_mc=IV*=i436nJm1$wHjqMJxG1BEa44qc7=1l)2;z*$sPV1LX{7KKbm!Y0>GV zmBazNBFEP9unvv^j|7D8PpWCMk*iuN1mLS`4t<9$OvXFCoH124PZqRXb1+Uve&Vpj_$4W)x+2^wkZF)z-UICwGsMSJwma?V6%Z{;+vLb8;@CEKClUMv_YiG|z{ z!#)sU+sb4LBT@C;R{b6RnpAu%dDNvZ( zN>^WDZMP6zU45qoYRVbiTy7i?K+G}Y%ZrlYUtpV^2dOoauIqGJ@5zK4i{-W!{HMKR zhU-5$Zsbf`5~!4rE;fI?0gp+CFVwGb%RWA*Gu#WxY<^ahS95*r($j72A8~01$6KQkr6PZ0g@Vw5*W;Li)ebHKGLz*coE`SpBxLC_tc0BhCH~(aL2Is zQX*+4>3_P)@gmw1Z0iT~tE)8kFPBzGZg|gxWkk{Zbv9-g*_tIly1pSu3>m*%t^dnW z#+=7=D*2V1qg^u7i;-d}Vctj%y@;jA^lZRBIjiPe5@Mi3CB(^t8Nkuy(1zQ};;ZA( zmY)A2fVg1at>44K96Fa?lXz&bd*`*YE8VIZNcj`LRQO5ee>;1*Awb0b3>^_+&1gRP z&-MQ7)9ZSKWrj7}HTM-SR5s64f;@^)f2?z>Q4ENx9@$uce`tpt8$?3V;cVlKXqy$aCFOJJ7T&cA`{!Pj-|&h zr;iw$d|02Mm&K2?;vF&=7Q$C9tnFsr$7FG8@8neqDF#;jqf{DO#8*sZs@8JICd){0 zfArg9l=na3_mO~Dc zeiVf~SB7iWw)4twpc;5xwa1sxBnR%?&fd2IkM_44ZPC>SaS1p+@Tc^-F}1xyjyyKeQ@RxXy!~M6F1fW0o1^-cRGDmVgk-`D|cIssQ{UaG80BnhrJyJj>}Bp4-TKl zsGi98{3o1KKBWrITJSk^ z_jE;6^0zw~MX_>pbT~wZx8ML=)D1c7NR3yHK&h0OPKbHy3H+ z1m^x&ACFv!$_08u!!gmTWr(M~vCqZIMo3G~09xq6+bbJKBZR5o(x4fS0b&~1^9;$w z3F30l<`48kk98f8>G(I^=4#?Sz*~_=-gsgnZ_O(&oPd+HsU|njC<&pdlMA~JH1yp` zdfD&^{7~rw;Pcd1qcvL?K_#v%oiXAQGb_l0Ny+S{LVF@y5?0bFVBEEAZeM7#Kf8w&&qpmkS1*HXRT!83QORWH`rJS4$@m2t-c=O12vxnuMMDVHty;(pPEb7#l~IZAUs*@ zn&ZR<7cSosWB%@yB`!%tWqnqys~D`8JU^?ziyBd5L9xLOA~z$h0>}`)!_pQ6h$8Sj zV}A`)>n^qR#XFQIYRa9*wH=!rfKBXcKb-`KgHi+=SWdh)30XCR=dYw$8;1WYAhWPE?N z#?Q;M=3cFdNLD?2x^=d@+x8v zXV0q#TBRI~xV!+PBMv{WB{kS{d&mt>8Xd%L85PtL%jLtdlTsZ1-(xTT^rC&{$5Xi zv7wlBPNse!;w=hqgIs!c66Y`hi7R`86ihG=i(bouX190T^L28@FB;Wab5NWckH}_n z?n0wzs&-Xp_~A-2&Qs^n?I0FFR3I%uP)d=Y2^WhTxnqh8Dvy26js6PkTR$d??7;u? zwlT3RJ-)91dmB;uF|rp!H=`>bE>B*>nqb8$L5Ys(P2cg?S3`&hNxp|m>nbEu`Oz-x z^BiiBBwpV_)pdPmoK0ln2UL75m1lSFjoil7Gsb?&cc1H|W{sOwDiB?tYjyEv>wN1X zgL;KHPWpqSRVbdWpp#^H$fDMsc@ofm4v;oSI3a@q4&bpT{?x=Iu*1n;N96km+kehgx^kKTvJb~=RR8e z)qhC{^lRk><#k5*MwiWNlZ4wlj16;W`s%CDwRoI|%Ex9$Mz!0=ot+^E4+!_SyIY9I z{P=S}jx5y}o_8Uv!$C!9x#EB_GxUOo>NYv*{(>oQyfv0!_`DtWUy|tRQt^GlI zguLcE&vDi9|Gq45v!pu_sU3(MK~CRVlkLRPByfoPMqF1oNJW@R{u)vU``SxnPRb zM{N#(fk=J7PyO^B%Nul!T%{MHfV9ogblxd^bm)JpjWk^KK<2B^$@Ldn#W(Rs5B7xp^+i%sCH+li)kIWPfYLkhe%jENy6pZ}EmP18#N>13G8M+g|B=(m ze`4~UfmRuJ+1!kZ7=sNA(JaxE? zgkY%bHJ@n;mH>&z#~AoT_U5NRIL~b-W7I+YpG}5nM2`HFp5l>D#qdCE57ED)EGZ?f zP)ZJKii+5PBJ=Y^C7QTMj^UwH1K#fn77dZJTIb+?N!v1^t?8!>4iHFqyRVhVa^+JI z#sIq^tDLVKVu`-vg02C!z)>RRg`1I18`!?P5NAu@v_41GGsaSurun7)g%6BAF$g0P zYdzx1VZsn(v#-YogutFWJvugK+v3ZO^B-@!N-N`AKSmh@cFx!F6DO@< ztT`_3NYhyW{6;eFl2YCqA7iSUKzJ$$xs8(H#z7M{C9{IBQ#eku#e*Z2IFKEt7Im=@ zxoYyjOU z(`bo)OJ}^;$~mc0`DPr*k=u^G`_?xN-RL9Rflz(uQ5hgNEq2>iJj#LoUuX&#{{A>N z^l>jbr%BY;<@+BdfIElqUxg zx6NP6g=Q2g^l^Sa>=f&V+yZc=BJ+RjjmS|NwK+fEU{6w&L)NSa$SnEN*W=KdypNIv zto=Xz&+MlE%gO%R6uSXdE+}xyYGH9eFsCH^a4R&!?AIs%E1)TT4rbIgTn=>;j19vueC3qggfS;*+T=<;a}~^aA%4x9aT}_V=oo zS}?-9a-Tc=Wz+-TC;^--4lE@(V9SuK=y%Nc^qs>U67~`YpEvekB)u1(`aIfByGEg3 z$sLT8(Qqs%kRy?g|MU5gX>My*!4f+gFB_kEos^2u`Zh7q3>T4L2hy;w6IY(=(m||u zIXyvxmos4j4uHN+yR=23^v&ov|E6xG|` zhQ4^6Z6#Jzq~z(N^>h1;UEA76W!Gid=r!zxDp1h_N<%vg9kVVpIm`pA*KHUXe2e_1 zx7LhLNvH_hf?;Z(J~w{#V#wCx5}1EN@>G0!v8$cox;U45$~udy6a`R?*@|EcgPxvT zISy^C?R~`5S$lXNzk9k#cOPtixn&V2dIeb)c_8j8Q8(Ezo8i;Op|0t6R?$oP(h$lmshc$Jw^J~$Gx|pVC7m*vH@~Ddaxpx?l4La=Tx&Uw zWqLqJ$=#iR5rOQ)@a%Y-FQ?X}l59N1gRGhX*HbR-93e8}^S)5H2UBw#nX)9lXyyOU zMgrmEO98tn1~>6V26whHp?cnmxJ#)(^9#{MF#LXU&sE^xv&evB^4)=?BX0FU{jXrWxhU^H?ZnaGldkt}Uyn~vX;uFCei@Q#=)U%PmhD!h5+9Q59YVZp@*jB}Un9D7vzMGH7dMWU+zmFaBVQM|nRkj9_n z^q@HNxt1D3#M?(DKp{jyEh_mUN*#uu>)9(Yh61S?zkNF?#iIf|Wm@`1LNXT-c4S6U z?+^BFh6=*7GlI=e%obQ+xC4j7_E5(-JHO>}&QQM0N0p=2ZsBlM&c&8@YkM4sGqu%y zYNEOJV{(IN`}vr?RH}2ntU8*Snx6JAY8a*-4|;gSNDaRHjx}vsXL@sOC;jh)AFHVKL$?nzKDdpJ}RN zG*qrdxb@!e&!KOfb)&#VeM|rRoGU-Jn4ADX9U@os#5hOZi>k$ebX(p7f{!Nc>wh>KRWyQ|^rqBA9Z~x$Hhg&9>_C?oA9b$6a*xNE7y0`oo)>N%3FQ1+E?R z>LMHN*ZP1`1S0M-q;gD09$7*ymgQI%yKJh>kIqD#1Jv<{?--#E^kFgCW#Q}YDvxL6 zNBuFa070*Rub?+tz}doch>^bMylFHpfa_-QZU}_Csa$p)VjAIp(yB|n=a2P`GW;E4k(r`YsJaE_u6(tkJJsb*Q;?p=)ekJC!RwDEMVR3UkX6 z$6>aAf81soD<~{xTTE6jq(hri>N0T(X8n!Zi1>k1&(mHVF6S#G<>?+SgCJ{AQ8p-Iv z5eeLIY>F^ZC^@hFI*O$9lJTP#U$^l=0e`kcNZ(?v4a-=|P9(h7JzT>G$eq1D^q#2+ zPXh^AZ6`~W4C}<+WN|#atA*Dsao|;N8;S%uo>!TPtB6kabWccJ$p4Z6a}*aL`bPOE zR1Yf@o!%K)kf#X$_%}f)snmX=L=Cp}*&kNYSs+0Uy}6z%6Q9OP4io;17PUHh^BNpH zv)d*3fIvC-D^7p9*5=Fk9@}1&DN$Ex!~F&t>aC&b4uCwUPbma^6{I)Cu()d97B!{^ zP}@{rs;K3#<2a*Q!3*}D-ucv`^T!)#WdZO7UZsjnKB|uF$>^=Dl@7CqjQzFrcY?7O zZl=4JRDr?|y%RnI(c3?=HJd~oSwG zcT$sXjaB+zGiU%vqSPy*Z+(2IVixyeDDsYzKamI+!<>yH#iwC9-H&Nvs=nvXz1Yel zOFSZOILC8xg{keVw()UQa?`DhS8x0hd3>AaVG^{O*JXB#LJv^ zmyUX8k-Yw0rE%ajYsm^bQh#>!`Og#}zV`fPhID+q{w|}k-^V&(g2jK{kyE!>GZ9Yq zt2=IUAttpnYmT*oaZQ1#w*<<=t_VB??1xeMb9l>^2DfrbFH7>1d_VgJnoK{7O!Nx%eJ^# zUai8S4cWtH*Ahi017l?t#^mbKJy%5JvC-^QdMbev^M`%X?wFZv{ej5_LJ*hyMIf9A zP_+mAZ1`>yT7egGcu2u;P2QMeiH)Pptu~U|BsgzAY|6pIi@bUwIece&#~-(&72DgE zNX}>Jk#9$Tv8gticv3FIC305f8??A;cU{3D$BbtQf$p6)O`O$Q%MO#d$C%p`Mv%Z6t8pW|*mS5+4@(s4qO_?$ z?#9(FKUd8B21#_2Iu5NCgNwQq)B;Tj#}_@JMl8nV|`!8Wce-=dDh`8Q;0>lISyXNW(V1nNKglV%WnAZoS! z@AXihgW9_xi)rgk;QQq9%bzi*{4m%@S+=MKFWu0R|}|qAsw-f0NF%O?ex1`K-Feg zHHW)!D6WQ`g|+#=bNsgYrdAQZWbpJO(Cx@Ozw)}ZhTEJ}d_o(SMDgCRw}H3w*WE~6 zq+(^P@h|+KK}F$Kf&m|*C2ze#T=0%tUaYFbOd4vwZye9(#tUBLf`(OFNDeKoI%!J# zEw8>?Ia0Ss`;Pl3JLA5D8lDG+V z!Hqq#dWLhT2_0eFOn{|cs(}$f9v!l~P&mir_5>3tl8FBO)=J!n@T^~Nuiwli=^}Se zY#5S1Fet`HB#-0aXL2vHjn#ulV(3)OKJR-?SIo}R*c7=!Pg`HDW)tZOhP1Qn? zd?v21m-$8_+-6%FfH0k`f>WcE}nP=#r~+pXP(J`}pt!@Z1it ztH%?_3BrTfi)V=q@_=y5tTxA8ECI4VD-Y_=+76k7Sd`moIpIar?Xb?ngYic!h#FG< z(cr4^8AZRHGw#rFF4wyIB&5;G!dQbQD4t2wGv&c}T;vhJFIXQMW{_=Z^i4JkI zNwlr(xGY*{EO(-PH(RbQerh{6FXwEn&{jSe1@$<;vqj6Mqkr4)W&&}wdT`@M{SoQJ zE9PDU5pG0JLqG=$X`F9<$#mns5&{|eVO@Y1dVaY=zR(QdN6DMz9#mt~UUE`R^70?Q zIo9BSKGy}6$6)dOz$fVc0pgnON;p`*9L;pe0sbeuhpkrsDjTo6ZBzwYX5T?K6sI$%>4^l+ld;J(Iq z2)@qde}Id#coL+wIKrL9>xWEwk8fd}0$c*OoQQ-_bxqudjOIh$$FK<~cc$eMeDu}? zYWiLoHuD$6yMN*j-P|9*pyQ|Knj?C-@o=Th`PXu0z0V-*R!>mim6lJ#cTd%|Jz!EU zF*cY0ExtD1%dHAuFNwRegcX#u5|qBPM8Kr;G}l0(greIc+Sbj1LPURRvoB{Lcb&xc z*Cg~=D(}DT1j9s2*`6{WCo)}r1~S`NTpyZyshTUI7n5Fc1v|3vc3ZN^%={AJa%Y$% zJS=S1`sR7wCoDNYhLU^bFa|DlJ=5oF?lo*Sq}uxX-~QYyr81#F%MMlE^>HK!HJtKk z^GAsc&Z%-~L)ZuMURWH;iP4Ezv`WBaPcDNMyR9WRzz;YCF3&Tmf~`w){O)dLg1A7=oiiXbqX7Z(L>pkKNV zj-`COSU`S^Lq1yX)`}U16`pk8hGby z^VF&#&9J$Vl+TW%6A5T;JKKM~AQ4bZ#b*L)7)LSqJKSo;u|9s4;0EKD^0{SRB(u06 zs;}V_ZW8u;@;}jyRn4CqiqqSh`T)QPzb&ifWncU}y!?J(^q^*-M9V zv*t)^#o(99OH8|9&fe%(D-hSWhW7juhlBCpYOeB_fPZ~<4Wm~!J`;(Tn$!bG9pW}3 zt);_tYAetzS4{2+i#b@t>-N(dC~&r(YWK%fN`gu5ooc|ssU-iZXZB1@jX*UnR<-%5 zwBA&LdQ1=(R`~t?+5P1tC2Q4z1I8;$v7K1}@crJOT?P(}LOU}xe}dEPLILt{UNQwb zVAk?{I|-Uz4>pcuAqpVI_;Ptzr*dE14__NN!$O+vFH!)l7~M>Fa5nFvYr@ZJ{GcqW zE?=`m^DlT*Gz=0hK{$R7PdN!wlrD^0)z=1@?a$;9@U+qSziEA!65&7CNk=IWuDTq{3*++`>-b)eA=!t>!OHBu<7REc9}hry7qU_LO_QR zx|ymE2u6;EZ^ai>0gmiIQ|=<;Ox*lAHTgufheyD;F*^Nn%zryH)K7Yg`*0;&T6lHK zI;YfLNl^7Nw@r6ez1>0$K6>8^iR`ywj!1De&A=g-JCr51C{>m`;IwH7NF|I#-DD^4xXcJ?t;Y@Wf#RY(MQ z)E_@L(>H&@XO$5-w}q7afAvcyE_4KNn_MTx>-xzOb2UqpQ*9G&pZY;BR3^)v3`jl3 zrpdV~!v~`mgT6dV@abHa9&yAxQ}pBnAO)y;`?l_Oxjv@jJaUllTEt2)sbe}!q1=q` zmo(Xm+rcTDI8m(Gd@a3m)o>7;XYtC|6f5pZXqVtKHpa5=O3ppYj5%DzH%(E)xKm4m zt}yY8>aG&Sn49YgC45sxx0bC`6RuL1?TYN_MBf>RCdN@*vW44Hl@reh`jkN_1OU51 zZ+{=KkW&u>Z@<{Je41U+-Z&_%&q_(Z@&*+m&-U?1v)x}W z2T$o|XX~-YL6jv$z~GN2r}zU2p;x}3?CMhoaRw%R;eG3K5Q*SFp&OBC9*1h%=6`!k z0B5C01{tMkBblku0j{E^z*|nZyc3AvM#@F7lbW@qZm8p@w5rc@v6+TNA7r{0?UsL0 zRpept*A~4I8%q*gfYiA$zogEJ{Q>Orjcc(zix_g}hv*Ha4u`q9$~E|F_%3nfy?qe= z%Q}#r8gHY|C@#RbfHQCFCSbgRXE!%;-1PXedS*GM(`)=YSp5Apypi@XlwMWMBGaXA zFBj>-;?Ik}KpmPm)1y`JfQQ7*##M7(WKtR=?XJl+80v!_Ju~Q>lipt%To3(YRw-Qi zR1T2{5>#QvciUa*cMz47s|YTr{IU=?D>-b}er8;Okb)?)26|2FBlEx9^UWKo` z%q~pB!e7!9XkRep9*ZG3H^cI{OieOR63;0%qk|XwwYC1^yH^$3_n5_t0-&5f?mFJKn{y zEphiy9WBwO$%?&iWL~BpdN-tUS^X*VacD4Y(Wi{)7tnNaK=F&m`a`Zc{P(-1?jYi8 zKB(}df}SWWajjiwQ*$1ScrD?1>EgBMyxzgfuVO>h!1^e*W}co<7(YbINKoJQ>S-!g zd;QpX^L(FX5+tVPXi!K9DX1X=kO4l7%M3#j0;lHOjikc=YW*GdZ}&5mvtB1X*x{=- z-kL-voIU>cf$hTLYRx?u0g@<)ZeM78Jo;MV(Z7CY9>wKtaZswLqhw{(t{ptHBG|= zdLw^g`}^*=JzZG|p%bR&JeZH>UKf1}kZZ{Fza-P9wjE|ZwcSMc4gyki0N z9dnT>%)yoVYh!3r0NkKToI1I8=#v3oQIC=Ew7Ov~xwP|dBtB7@J6h-kgEzH6rhDy7 znb|$uTXF)}<=2Xo&Qrq&=rGGlQN0cB<1bk~O+<%uX@hGsQYlGtbDnJPowEFm#G}4s z74el(p?Zz*a-)LrKSN%^1%_uH$JX%}I3^S!V zvM9;I_LF{m2a{IWFQH=mezr=y;2>f$+Zn*b)P+b$_|Oj^G6) z1g4=vvU3TRXCoNsJEg&Pk0Z^}J-gc`4$4Jv<@H-@56-=^6o@>es0^p%&R+C{2*2wS zi}i1PpzV%`ofSu1sDh52X#Pc4=pTI>Wr?yrtJUvj5(dhGbAYz}R}vv0&ATB(v(&LWtK z`(>dK7r}_X-e&wUdgVMAEgW+@%2!Sx`^V`XV(z!$?Y~NV25A*iR%e$@lPK926pz|m zdWU>HW7`bvroUv7_E(jC`_U)1l5mfofJWYS>4QB`BQfSPa0IAazCzIsZBgTZ*WMeh z)u{N1=KxdN*&K&A)f>2W4u0XO@OnRxr&x9s zT810h+)S`GBu|MR9Q(oL4S-zVx5k0o@u~7*hp{1gZwN%a*r;JLh-@@25u zQr!UAioINRV2mep_v-aZiS#{_O_`J&pYWsA+5sG+Prh%c$9+N)ZwdI4zGm6+WsOq6 z|8eNoGMq4&hd=fh(8M3O9SlN5M$bpw>$n5P-aH&v6mSmu*HlCgbB9JRRs>7>LfRQ6 zx7iBnAn)%>t)GVJB6PQxC&_T$3PSK39mU!$$&JWxen57LLX@`_NwM^EYY-K!w0<0( z)yjwJOa-tte@nq^4GGx7C}G{`BhS3hD^`+@VFi1r!A#`^bHoEN^AT2zXqNkAw)|KO zO9|Br5xXeyiIHGd|E^J!!PJ4*o3SUpr9*}&{#a`w)A`DWNFGz%3me$bPC5(^k0M6j z%m((88Pa=$>Xs+0&gkaFW7Lg`=5e)PxRYw4($|#BDWi*K)lv^re0SXq+X)3JsRP4# z(6r!+#nX*d8|y!RTStmiH54%!0`m5rbr9amNvgA9`UF$xT^6`Zdf?fX-<9PL+DyBC z<#z7`dwsk_lQ0{HB&#otLzYXGH$Mg-jayxRg`?z}<>l+udAK#^e)*u4ZV6pK2`~f! za9SH5Am=0EAN;K-OMUyO@tN!e@3b4v&4V2zTj8SiHYM17m7nL59!C9Tglo&{%egb- z^Tp4laHv>_6O+-^@~U8MY&Mi-=G>oKsLo-{ogKcl*Waa#3K?4G7v0(Ha|4ccQaQBAP;T5DuR)>Uq1;A zN&XVOILQ0GHkkHv|j_5y;x1jSwH$9PRWsiU*(nw>`LQ z$0mZ=7i~s@DEzp@q8}TII{F0dm2X(Ppy~c{t;-2cEUzU*wUYc#mO2Xgnkd3@7_P#} zdbX%T_j7)w;zNrTQhM5^nc|C+N7qz_N}B^IVOa6Q!>+9-4i-+N#!`VC(oJBH4Q$ zdFIqHD-Ee?7r;V-!)5Q?Sfk?=DofyV+#U%J-XD( zIOn;8LN3!lq*sO6WA{&L+9$iQ7<}vM!9kNFLNVDz=%VL!XFmmp9{tq_l6)vBNxKl9 z`hIWt%M>6t)T)>Xm%y}E{pro^>%DufoZTPMIY*(Iok5>5&~nJ{ryuFk`LpRyXJ68E zkc@g4qUY66r>}N|z&|yJd!VE{Fq4IN>v&|^`#3?RVGDxY#z4YYucIstK+u}=vS$h& ze%<|mM5lY_dUgLhHy3bW3-MF)iD-+kyWzR-k0b6?EQ&cy_gr9se1@(yn`z+)+3Wkm zcOCWW)<4k%u){hN(i;NQD4z9o6hleu9+qCf83qihxUkMC^YueVSE`MLf&sByeB`>d zN67|Ped%2pQZJDoG_eWQ&=QrscIGDp^hWsVV~(i|pQXCb(^`E`evq#wq3tIr+4WxI z>fc44^vv2&83_>w>%b|D5@vsed?NJWKQ<84D%6a+eFIgRg@NwA*k-?4Gx&U1=q^!qLhWtmhgs*)6lLENgB9lO+D z@Kddr()e*^g+A89pjdS4jSoD#){B(KiEufs!)V>gkspTje2q_jt5RmG-~l#Wuh>hz zs}ZpHI6=f;NOpY#Y{Loa?+o+HljS=8Z3>jT@IVVhSP_$Xe#2CGMz}-+V3`_uxW+3| zaw1@Um|{S}+h+zK9x|Z3^||-w47%_c-oUeILiSlq{=Ql+`zGHEUPX-x8VO^HH_6&6 z_;{KleDGlWs;Pf)#g9=>GY1Vp**w)odvPB+h2)mikvF2;P&6_~Y3M$>2A}ACYqlAu z2&jbA49HQwJka@hTdQEer>Y!lelzd$$t))3VK2_Y3ljS14FxuOAyd2R=B59~;DTHP z!7R*I{l^9><69(!ET_E<_meX!yqh;u9|(S}s#$EMWe5&S4V3{^B(BD2QgM%M$g*@z zfsb{{pcVS?yk^RW{`f{Q>l~e89=C?9zzq&6+zj;X&DNjcG_!)s;=|d>j%xNaz-y7O zsw4yuWRp9z4xXGndEm3IHc0+bN&b?t;{4)N=+sdp^AWyIwmF1S;-f+6*-*%TmDggZ zyO9&RaI?8S`WmOCa^QtaJ6#Gt$%8J){G)wWGoV_OmHscS9IT_$ zx5HIKdjDU&WlKH@knPPgWdXR{FrlnpBYo{2rLjetybc8;f8Tt~S=YAT&3=3@#A=?Q z;6MnBi!@U#T(;k#r51~2l3Fimrd+zlw5ZX{R!fU<)_{Oat0rGqFe!aGWjn(M z%DK^X>-;^2&fJE01rQP1GOh~~23vo|5_*|sFaEF~T@Q4EHlK+$iHWtO?S$lA04o15 z+NRpdwf^dP*$=Gap`^TuX2G~};QKr?5fqHYOZkhkR`zL9?WN5lpJNCJWe$C_PrCC7jF<5X4?ezji)4NJ{G@BlJIt!i`f+IpA63 z-$77%u67OD(g!)YV{|}CbBR~zX-0{BfwUU?DjZ8ZzBjia(r6z4hBZ}>_s5g?s) zaXdmlLY3o5Zox<1Q%b?|Z-+o)>IQ9cO1@v%n2P5PDiGUlwQg&xk+K5I&r-*1dcV9i z@>$B4HI6~ysof8Ph}!!xCjWi%Zub#6Sf*)Xq&@q3Ke3I++i&-uKT6UYUFiN*hGmT+ zsp_wQzkS^UMlm<%o~eB=uvXot)Zy}t?Ap*+C3W4Q`v#jj5%wgx+ABA<<1gQMIsMV{5Cj7$tiI2@9}nLVfbz+~w394nGyxw=uo;;m(0W8mY6S8L6|ry#&l1*`I>) z&oK2hrMrC+!)D??cDoF)xLfwJ6|=a{=hS`e6QTTwOq1wNb^h0~;x}aYOb++{G3!1Y z(kN>Ir=v`E?`}Atx!4zt8c9Z{FQlCAhY+fJ3{X&vF+s^arY)dwCy$(H`;r!_ms)Vo zdMnYE3k{1|1Adg1KyHichl!l<>M2`rG7XHO6)AYVD&HSg10+}xMc6Rhh(m95Q;B-q z#aW`+^JMV)Y%4j3s_Mzsb z06?|X_gS$g5~qE8i5#9CyG_I*s2I;hcF5!kRmIK9ope{+-Jy;tKF$2M={2v=x%q0f zaXb$b7YSFiB`;|_QxQgc2Y6scaK(L+H@QlU3cm4)x-Vie|eVBON`teS5m$uech|5Au*`o?%_Wsx*;v`{j1iDDuS+;rl^$2 zpIH=Kq&e#C{%TR5T(Nl)9W^SB4^6`Y7XmuFyvWvwZGC+_wO9CY7mLfXpAhk3F#6Ln zKfmDoP?%WKsXyZcy1>xpq7L9hZm{e%Wc7T%o>t#h(rXy<3CXkyg4L49Y^5xgpl%=Q zQg6lI5tF}}E%35_%S;9JX(?;m!l7NP;Z{^p;OGF7i>OWFXVU%!>%(4a+=pVnRPtAt(zE#AV-TQaDsdmPWgG7-sZ|jmea*zVif!I^ntmvRJ8CVYxEQ^cN zM*%%}gnP=Iu&I*?N;1zej%UB$e!T_g{bwL>gGo8|r^$}U24)lbx{!|IZ`o*(|_%Rvx(yVxUsc~MAN&AD0YcDwtH3Tf{YxXmVG zH5GzFU#u69G3!Y?r1^R^y2vd4O`n&(o!#S2aE>%y+`rouQYol(_PF3x>_37t(Bu8kbU`h z@ieGN3}|vhOZOi>Z6d&?M?x{|l8=FrAC&i^>?~GM>8{eaF;$A&OFayghD3wPi7rn| zv7NJL)AE&(bF#z?=mUeNPfYflCB-}O8%m|q(4uAOw>~fZMSFAN4Bvd_3e1_8jqFF4 z0IdI9H}Z+$c6?yECzS*uSbs0%+iUcv6d!qWah$X?J8p%hryE}UfCTDI#R*eE=QOOB zOp5uazWPF!{<2MWnpzK?4wvKQ+X`OX%atvYcR$y;%daS5(`XgNI*pO=swl(8PfD5; zGurMte?Ka-w1#mwl(zx6!EBHNjcQYh%pZ%{%E85>d^0~vFhi4u;-c3ak)-Y2rrVC7 zT>IFt6BrfQ@?9*6!!{t~>^_2Mz)ttbXnY$ARozlVGs zdZq;w4%`aOJg~Z5%0QvU}18~k21G(DGe z@gT9%JFoP?&*wvzxNte=VnY&PB!*Rs$6&I`^aDz30uV196)^y;!b|;&(+3%rz*D@s zi>9psaJz*Ami`ZJ*MKD{ZL-Z;G&x`C@@eCUGCb5&{df#x>U68^?p@M)^RLusv+eQL zVXZtF=bA0r1ULRC5vVLX(wNIUnJiE_^@GJ!yX502L^$+mbz!F+d-FTx%3=N16cxo9 z#}DqcO@!6Rm<@1U8J#!UXjudd<@+kUx2Wd%`#(V=HXK3OI)ut`6c?#fpIEhOtfkpk z)VNc$x-~6n?h`wXBjZoD4Cxo56R6r#XY`j_@zClrMB{*y;br-IYgP6@w+|eEj3=ia z4Jk3z9ScX#C0p3!++6Z_L&n?uNN^B3qd#AD^)NTj7AW^DF2WVocrPXQgTmVkhQrrB zu59_Bhs|LZ>kHo=$B~k(HSLZUB7yg*)s3eIT5}iFZW`!OZRD-}{SKJObXO<8o^=jK zIRaH6diAd-v%a=W+d)xTn@)#9_cWbB-a6>Wk}mng-kS!CurZC)rc|WUZFSjkWD%>&wb(%y%V3528BXpD4o69lu~8zYQqsLD9Zantgec7o-g=@y2eo-exQTrBSx#xa zZorf6nzQ*eVN1T69c?+kmF0xCh6(NEqCjX}I~4@gM4r?Rf@%xnN8&#@WL`AjUrW9G zLd)6~rdCqAH?9p*96eL!vI;i4g(sVh%+D*W%Zmq|U3c6pz{<@yB0gxs6(s_euG)lM zb}-HgE?2hvlWV)-?tvCOEM7W6?L-g~+Bh_NCLy_)X8`GK;_$NgBVNQx& zq+;er;7((bt$@iaBYY)%@8]Grl>DChi+tx*yMRPuwyg$$4)|RbkY@D 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 z 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

      5T1CP}ue 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

      _SpXUiZShi}af~ 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

      dIth8P_90w)=-Gf3#F`$OQbqFZT2rG9(qd*W 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�uo5$=M0{8kSZerB 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

      pL7r7PxKW0C#E8pXKGzxgR* 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

      vM{OP}Mt+mKawtn}KRusYX&FxtY|aswkOv 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

      iYs>JnVsDnjK{X&xt7DK&(iM4kgT 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 AQUCw| literal 0 HcmV?d00001 diff --git a/public/assets/scene-rooftop.jpg b/public/assets/scene-rooftop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3f397e7936a3eb210501fbf4e6e9e09740a5c7e8 GIT binary patch literal 361864 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≀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 z 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 -MFv#MT>JE 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ॻRvzFKiv2CKi8yx5}fOHFTMqhf{b1xx+! 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 z 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%0Du<>3JwK#S~R>O%&aigaR)FX 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

      FN3ixs;|AQW`>{_`U+{{Z*^beuk6Jq0i?&!17P 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 literal 0 HcmV?d00001 diff --git a/public/assets/scene-studio.jpg b/public/assets/scene-studio.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f5a427823ffbd7a17d05db800c0cbe7f2e6e17d1 GIT binary patch literal 237643 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

      xEEK@B{RxAi7#+LbzWIwYsR8{h`RS- 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%0D*tp5SV$JoBVj`dZz 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%0AT;t<6}vceTa&#uAvEx0D5+av=>R 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 #AbY^HQ|?n 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 literal 0 HcmV?d00001 diff --git a/scripts/alertmanager-smoke.mjs b/scripts/alertmanager-smoke.mjs new file mode 100755 index 0000000..0842fc1 --- /dev/null +++ b/scripts/alertmanager-smoke.mjs @@ -0,0 +1,310 @@ +#!/usr/bin/env node + +import { randomUUID } from 'node:crypto' +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const scriptPath = fileURLToPath(import.meta.url) +const acknowledgement = 'I_ACCEPT_TEST_ALERT_NOTIFICATIONS' +const defaultReceiver = 'frameflow-operator-webhook' + +export class AlertmanagerSmokeError extends Error { + constructor(message, options = {}) { + super(message, options) + this.name = 'AlertmanagerSmokeError' + } +} + +function required(value, name) { + if (typeof value !== 'string' || value.trim() === '') throw new AlertmanagerSmokeError(`${name} is required`) + return value.trim() +} + +function integerValue(value, name, minimum, maximum) { + const parsed = Number(value) + if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) { + throw new AlertmanagerSmokeError(`${name} must be an integer from ${minimum} to ${maximum}`) + } + return parsed +} + +export function resolveAlertmanagerUrl(value) { + let url + try { + url = new URL(required(value, 'FRAMEFLOW_ALERTMANAGER_URL')) + } catch (error) { + if (error instanceof AlertmanagerSmokeError) throw error + throw new AlertmanagerSmokeError('FRAMEFLOW_ALERTMANAGER_URL must be a valid URL') + } + if (url.username || url.password || url.search || url.hash) { + throw new AlertmanagerSmokeError('Alertmanager URL cannot contain credentials, a query, or a fragment') + } + if (!['http:', 'https:'].includes(url.protocol)) { + throw new AlertmanagerSmokeError('Alertmanager URL must use HTTP or HTTPS') + } + const localHostnames = new Set(['localhost', '127.0.0.1', '::1', '[::1]']) + if (url.protocol === 'http:' && !localHostnames.has(url.hostname)) { + throw new AlertmanagerSmokeError('HTTP is allowed only for a loopback Alertmanager URL') + } + if (url.pathname !== '/' && url.pathname !== '') { + throw new AlertmanagerSmokeError('Alertmanager URL must not contain a path') + } + return url.origin +} + +export function usage() { + return `Usage: npm run smoke:alertmanager -- [options] + +Sends a real FrameFlowDeliveryTest alert and resolution through Alertmanager, +then verifies successful webhook notification counters for both events. + +Required environment: + FRAMEFLOW_ALERT_TEST_ACK=${acknowledgement} + +Optional environment: + FRAMEFLOW_ALERTMANAGER_URL=http://127.0.0.1:9093 + FRAMEFLOW_ALERT_TEST_RECEIVER=${defaultReceiver} + FRAMEFLOW_ALERT_TEST_TIMEOUT_SECONDS=60 + +Options: + --url Alertmanager origin; HTTP is loopback-only + --receiver Receiver label used by notification metrics + --timeout-seconds <15-300> + --json + --help + +This command causes real firing and resolved webhook notifications. A passing +report proves that the configured webhook returned success to Alertmanager; it +does not prove downstream processing after that acknowledgement. +` +} + +export function parseAlertmanagerSmokeOptions(argv = process.argv.slice(2), environment = process.env) { + const values = {} + const flags = new Set() + const valueOptions = new Set(['--url', '--receiver', '--timeout-seconds']) + const flagOptions = new Set(['--json', '--help']) + for (let index = 0; index < argv.length; index += 1) { + const argument = argv[index] + if (valueOptions.has(argument)) { + const value = argv[index + 1] + if (!value || value.startsWith('--')) throw new AlertmanagerSmokeError(`${argument} requires a value`) + values[argument] = value + index += 1 + } else if (flagOptions.has(argument)) { + flags.add(argument) + } else { + throw new AlertmanagerSmokeError(`Unknown option: ${argument}`) + } + } + if (flags.has('--help')) return { help: true } + if (environment.FRAMEFLOW_ALERT_TEST_ACK !== acknowledgement) { + throw new AlertmanagerSmokeError(`Alert smoke requires FRAMEFLOW_ALERT_TEST_ACK=${acknowledgement}`) + } + const receiver = required(values['--receiver'] ?? environment.FRAMEFLOW_ALERT_TEST_RECEIVER ?? defaultReceiver, 'receiver') + if (!/^[a-zA-Z0-9_.-]{1,100}$/.test(receiver)) { + throw new AlertmanagerSmokeError('receiver must contain only letters, digits, dot, underscore, or hyphen') + } + const timeoutSeconds = integerValue(values['--timeout-seconds'] ?? environment.FRAMEFLOW_ALERT_TEST_TIMEOUT_SECONDS ?? '60', 'timeout-seconds', 15, 300) + return { + alertmanagerUrl: resolveAlertmanagerUrl(values['--url'] ?? environment.FRAMEFLOW_ALERTMANAGER_URL ?? 'http://127.0.0.1:9093'), + receiver, + timeoutMs: timeoutSeconds * 1000, + requestTimeoutMs: Math.min(10_000, timeoutSeconds * 1000), + pollIntervalMs: 500, + json: flags.has('--json'), + } +} + +function unescapePrometheusLabel(value) { + return value.replace(/\\([\\"n])/g, (_match, escaped) => escaped === 'n' ? '\n' : escaped) +} + +function parsePrometheusLabels(value) { + const labels = {} + const matcher = /([a-zA-Z_][a-zA-Z0-9_]*)="((?:\\.|[^"\\])*)"/g + for (const match of value.matchAll(matcher)) labels[match[1]] = unescapePrometheusLabel(match[2]) + return labels +} + +export function notificationCounters(metricsText, receiver) { + const counters = { total: 0, failed: 0 } + for (const line of String(metricsText).split('\n')) { + const match = line.match(/^(alertmanager_notifications(?:_failed)?_total)\{([^}]*)\}\s+([^\s]+)$/) + if (!match) continue + const labels = parsePrometheusLabels(match[2]) + if (labels.integration !== 'webhook' || labels.receiver_name !== receiver) continue + const value = Number(match[3]) + if (!Number.isFinite(value)) continue + if (match[1] === 'alertmanager_notifications_failed_total') counters.failed += value + else counters.total += value + } + return counters +} + +function safeResponseText(value) { + return String(value ?? '').replace(/[\r\n\t]+/g, ' ').slice(0, 500) +} + +async function fetchWithTimeout(fetchImpl, url, options, timeoutMs) { + const controller = new AbortController() + const timer = setTimeout(() => controller.abort(new Error(`request timed out after ${timeoutMs}ms`)), timeoutMs) + try { + return await fetchImpl(url, { ...options, signal: controller.signal }) + } finally { + clearTimeout(timer) + } +} + +async function expectOk(fetchImpl, url, options, timeoutMs) { + const response = await fetchWithTimeout(fetchImpl, url, options, timeoutMs) + if (!response.ok) { + throw new AlertmanagerSmokeError(`${options.method ?? 'GET'} ${new URL(url).pathname} failed (${response.status}): ${safeResponseText(await response.text())}`) + } + return response +} + +async function postAlert(fetchImpl, options, alert) { + await expectOk(fetchImpl, `${options.alertmanagerUrl}/api/v2/alerts`, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify([alert]), + }, options.requestTimeoutMs) +} + +async function listTestAlerts(fetchImpl, options, testId) { + const matcher = encodeURIComponent(`test_id="${testId}"`) + const response = await expectOk(fetchImpl, `${options.alertmanagerUrl}/api/v2/alerts?active=true&silenced=true&inhibited=true&unprocessed=true&filter=${matcher}`, {}, options.requestTimeoutMs) + const body = await response.json() + if (!Array.isArray(body)) throw new AlertmanagerSmokeError('Alertmanager returned an invalid alert list') + return body.filter((alert) => alert?.labels?.test_id === testId) +} + +async function readNotificationCounters(fetchImpl, options) { + const response = await expectOk(fetchImpl, `${options.alertmanagerUrl}/metrics`, {}, options.requestTimeoutMs) + return notificationCounters(await response.text(), options.receiver) +} + +async function waitUntil(check, description, options, dependencies) { + const deadline = dependencies.now() + options.timeoutMs + let lastError = null + do { + try { + const result = await check() + if (result?.fatal) throw result.error + if (result?.done) return result.value + } catch (error) { + lastError = error + } + if (dependencies.now() >= deadline) break + await dependencies.sleep(Math.min(options.pollIntervalMs, Math.max(1, deadline - dependencies.now()))) + } while (dependencies.now() <= deadline) + const suffix = lastError instanceof Error ? `: ${lastError.message}` : '' + throw new AlertmanagerSmokeError(`Timed out waiting for ${description}${suffix}`) +} + +async function waitForAlertState(fetchImpl, options, testId, expectedActive, dependencies) { + return waitUntil(async () => { + const alerts = await listTestAlerts(fetchImpl, options, testId) + const active = alerts.some((alert) => Date.parse(alert.endsAt) > dependencies.now()) + return active === expectedActive ? { done: true, value: alerts } : { done: false } + }, expectedActive ? 'the test alert to become active' : 'the test alert to resolve', options, dependencies) +} + +async function waitForSuccessfulNotification(fetchImpl, options, baseline, phase, dependencies) { + return waitUntil(async () => { + const counters = await readNotificationCounters(fetchImpl, options) + if (counters.failed > baseline.failed) { + return { + fatal: true, + error: new AlertmanagerSmokeError(`${phase} webhook notification failed according to Alertmanager metrics`), + } + } + return counters.total > baseline.total ? { done: true, value: counters } : { done: false } + }, `a successful ${phase} webhook notification`, options, dependencies) +} + +export async function runAlertmanagerSmoke(options, dependencies = {}) { + const fetchImpl = dependencies.fetchImpl ?? fetch + const now = dependencies.now ?? Date.now + const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds))) + const createId = dependencies.createId ?? randomUUID + const runtime = { now, sleep } + const testId = createId() + const startsAt = new Date(now()).toISOString() + const firingAlert = { + labels: { + alertname: 'FrameFlowDeliveryTest', + severity: 'info', + service: 'frameflow', + test_id: testId, + }, + annotations: { + summary: 'FrameFlow controlled Alertmanager delivery test', + description: `Controlled firing notification for deployment acceptance test ${testId}.`, + }, + startsAt, + endsAt: new Date(now() + 15 * 60_000).toISOString(), + generatorURL: `${options.alertmanagerUrl}/#/alerts`, + } + const baseline = await readNotificationCounters(fetchImpl, options) + let firingPosted = false + let resolutionPosted = false + + try { + await postAlert(fetchImpl, options, firingAlert) + firingPosted = true + await waitForAlertState(fetchImpl, options, testId, true, runtime) + const afterFiring = await waitForSuccessfulNotification(fetchImpl, options, baseline, 'firing', runtime) + + const resolvedAt = new Date(now()).toISOString() + await postAlert(fetchImpl, options, { ...firingAlert, endsAt: resolvedAt }) + resolutionPosted = true + await waitForAlertState(fetchImpl, options, testId, false, runtime) + const afterResolved = await waitForSuccessfulNotification(fetchImpl, options, afterFiring, 'resolved', runtime) + + return { + status: 'passed', + testId, + receiver: options.receiver, + alertmanagerUrl: options.alertmanagerUrl, + startsAt, + resolvedAt, + firingWebhookAccepted: true, + resolvedWebhookAccepted: true, + notificationDelta: afterResolved.total - baseline.total, + failedNotificationDelta: afterResolved.failed - baseline.failed, + downstreamProcessingProven: false, + } + } catch (error) { + if (firingPosted && !resolutionPosted) { + try { + await postAlert(fetchImpl, options, { ...firingAlert, endsAt: new Date(now()).toISOString() }) + } catch (cleanupError) { + throw new AlertmanagerSmokeError(`${error instanceof Error ? error.message : String(error)}; cleanup resolution also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`, { cause: error }) + } + } + throw error + } +} + +async function main() { + const options = parseAlertmanagerSmokeOptions() + if (options.help) { + process.stdout.write(usage()) + return + } + const report = await runAlertmanagerSmoke(options) + if (options.json) { + process.stdout.write(`${JSON.stringify(report, null, 2)}\n`) + return + } + process.stdout.write(`Alertmanager webhook smoke passed.\nTest ID: ${report.testId}\nReceiver: ${report.receiver}\nFiring and resolved webhooks returned success; confirm downstream processing with the test ID.\n`) +} + +if (process.argv[1] && resolve(process.argv[1]) === scriptPath) { + main().catch((error) => { + process.stderr.write(`Alertmanager smoke failed: ${error instanceof Error ? error.message : String(error)}\n`) + process.exitCode = 1 + }) +} diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100755 index 0000000..feb8e7e --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_dir="$(cd "${script_dir}/.." && pwd)" +env_file="${FRAMEFLOW_ENV_FILE:-${repo_dir}/.env.production}" +backup_parent="${1:-${repo_dir}/backups}" +metrics_dir="${FRAMEFLOW_BACKUP_METRICS_DIR:-/var/lib/frameflow/metrics}" +timestamp="$(date -u +%Y%m%dT%H%M%SZ)" +backup_dir="${backup_parent%/}/frameflow-${timestamp}" +started_at_seconds="$(date +%s)" +metrics_tmp="" + +cleanup() { + if [[ -n "${metrics_tmp}" && -f "${metrics_tmp}" ]]; then + rm -f "${metrics_tmp}" + fi +} +trap cleanup EXIT + +if [[ ! -f "${env_file}" ]]; then + echo "Production environment file not found: ${env_file}" >&2 + exit 1 +fi + +compose=(docker compose --env-file "${env_file}" -f "${repo_dir}/docker-compose.prod.yml") +mkdir -p "${backup_parent}" +if ! mkdir "${backup_dir}"; then + echo "Refusing to overwrite an existing backup directory: ${backup_dir}" >&2 + exit 1 +fi + +postgres_container="$("${compose[@]}" ps -q postgres)" +redis_container="$("${compose[@]}" ps -q redis)" +minio_container="$("${compose[@]}" ps -q minio)" + +for container in "${postgres_container}" "${redis_container}" "${minio_container}"; do + if [[ -z "${container}" ]]; then + echo "PostgreSQL, Redis, and MinIO must be running before backup." >&2 + exit 1 + fi +done + +echo "Creating PostgreSQL logical backup..." +"${compose[@]}" exec -T postgres sh -c 'exec pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > "${backup_dir}/postgres.dump" + +echo "Flushing and archiving Redis persistence..." +"${compose[@]}" exec -T redis sh -c ' + if [ -n "${REDIS_PASSWORD:-}" ]; then + redis-cli --no-auth-warning -a "$REDIS_PASSWORD" SAVE >/dev/null + else + redis-cli SAVE >/dev/null + fi +' +docker run --rm --volumes-from "${redis_container}" -v "${backup_dir}:/backup" alpine:3.20 \ + tar -czf /backup/redis-data.tar.gz -C /data . + +echo "Archiving MinIO object data..." +docker run --rm --volumes-from "${minio_container}" -v "${backup_dir}:/backup" alpine:3.20 \ + tar -czf /backup/minio-data.tar.gz -C /data . + +{ + echo "created_at=${timestamp}" + echo "compose_project=$(docker inspect --format '{{ index .Config.Labels "com.docker.compose.project" }}' "${postgres_container}")" + echo "postgres_container=${postgres_container}" + echo "redis_container=${redis_container}" + echo "minio_container=${minio_container}" +} > "${backup_dir}/manifest.txt" + +if command -v sha256sum >/dev/null 2>&1; then + (cd "${backup_dir}" && sha256sum postgres.dump redis-data.tar.gz minio-data.tar.gz > SHA256SUMS) +else + (cd "${backup_dir}" && shasum -a 256 postgres.dump redis-data.tar.gz minio-data.tar.gz > SHA256SUMS) +fi + +"${repo_dir}/scripts/verify-backup.sh" "${backup_dir}" + +completed_at_seconds="$(date +%s)" +backup_size_bytes=0 +for backup_file in postgres.dump redis-data.tar.gz minio-data.tar.gz manifest.txt SHA256SUMS; do + file_size="$(wc -c < "${backup_dir}/${backup_file}" | tr -d '[:space:]')" + backup_size_bytes=$((backup_size_bytes + file_size)) +done + +mkdir -p "${metrics_dir}" +metrics_tmp="$(mktemp "${metrics_dir%/}/frameflow_backup.prom.tmp.XXXXXX")" +cat > "${metrics_tmp}" <&2 <<'EOF' +Usage: rehearse-restore.sh [--keep-on-failure] + +Restores a verified FrameFlow backup into isolated, randomly named Docker +resources. No host ports are published. Resources are removed automatically +unless --keep-on-failure is supplied and the rehearsal fails. +EOF + exit "${1:-2}" +} + +fail() { + echo "Restore rehearsal failed: $1" >&2 + exit 1 +} + +keep_on_failure=0 +while [[ $# -gt 0 ]]; do + case "$1" in + --keep-on-failure) + keep_on_failure=1 + shift + ;; + --help|-h) + usage 0 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac +done + +[[ $# -eq 1 ]] || usage + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +backup_input="$1" +timeout_seconds="${FRAMEFLOW_RESTORE_TIMEOUT_SECONDS:-120}" +metrics_dir="${FRAMEFLOW_RESTORE_METRICS_DIR:-${FRAMEFLOW_BACKUP_METRICS_DIR:-/var/lib/frameflow/metrics}}" +started_at_seconds="$(date +%s)" +metrics_tmp="" + +[[ "${timeout_seconds}" =~ ^[0-9]+$ ]] || fail "FRAMEFLOW_RESTORE_TIMEOUT_SECONDS must be an integer" +(( timeout_seconds >= 5 && timeout_seconds <= 3600 )) \ + || fail "FRAMEFLOW_RESTORE_TIMEOUT_SECONDS must be between 5 and 3600" + +# Verification deliberately precedes every Docker call. +"${script_dir}/verify-backup.sh" "${backup_input}" +backup_dir="$(cd "${backup_input}" && pwd -P)" + +command -v docker >/dev/null 2>&1 || fail "docker is required" +docker version >/dev/null 2>&1 || fail "the Docker engine is unavailable" + +random_hex() { + local bytes="$1" + local value + value="$(LC_ALL=C od -An -N "${bytes}" -tx1 /dev/urandom | tr -d '[:space:]')" + [[ "${value}" =~ ^[0-9a-f]+$ ]] || fail "could not generate a random resource identifier" + printf '%s' "${value}" +} + +timestamp="$(date -u +%Y%m%d%H%M%S)" +suffix="$(random_hex 4)" +run_id="${timestamp}-${suffix}" +prefix="frameflow-restore-${run_id}" +label_flag="com.frameflow.restore-rehearsal" +label_id="com.frameflow.restore-rehearsal.id" +expected_labels="true|${run_id}" +labels=(--label "${label_flag}=true" --label "${label_id}=${run_id}") + +network_name="${prefix}-network" +postgres_volume="${prefix}-postgres" +redis_volume="${prefix}-redis" +minio_volume="${prefix}-minio" +postgres_container="${prefix}-postgres" +redis_container="${prefix}-redis" +minio_container="${prefix}-minio" +redis_extract_container="${prefix}-redis-extract" +minio_extract_container="${prefix}-minio-extract" +minio_check_container="${prefix}-minio-check" + +postgres_image="postgres:16-alpine" +redis_image="redis:7.4-alpine" +alpine_image="alpine:3.20" +minio_image="minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e" +mc_image="minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727" + +postgres_db="frameflow" +postgres_user="frameflow_restore" +postgres_password="$(random_hex 24)" +redis_password="$(random_hex 24)" +minio_access_key="restore${suffix}" +minio_secret_key="$(random_hex 32)" + +resources_cleaned=0 + +resource_labels() { + local kind="$1" + local name="$2" + case "${kind}" in + container) + docker container inspect --format "{{ index .Config.Labels \"${label_flag}\" }}|{{ index .Config.Labels \"${label_id}\" }}" "${name}" 2>/dev/null + ;; + network|volume) + docker "${kind}" inspect --format "{{ index .Labels \"${label_flag}\" }}|{{ index .Labels \"${label_id}\" }}" "${name}" 2>/dev/null + ;; + *) + return 2 + ;; + esac +} + +remove_labeled_resource() { + local kind="$1" + local name="$2" + local actual + + if ! actual="$(resource_labels "${kind}" "${name}")"; then + return 0 + fi + if [[ "${actual}" != "${expected_labels}" ]]; then + echo "Refusing to remove ${kind} ${name}: rehearsal label mismatch" >&2 + return 1 + fi + + case "${kind}" in + container) docker rm -f "${name}" >/dev/null ;; + network) docker network rm "${name}" >/dev/null ;; + volume) docker volume rm "${name}" >/dev/null ;; + esac +} + +cleanup_resources() { + local result=0 + local name + + for name in \ + "${minio_check_container}" \ + "${minio_extract_container}" \ + "${redis_extract_container}" \ + "${minio_container}" \ + "${redis_container}" \ + "${postgres_container}"; do + if ! remove_labeled_resource container "${name}"; then + result=1 + fi + done + + if ! remove_labeled_resource network "${network_name}"; then + result=1 + fi + for name in "${minio_volume}" "${redis_volume}" "${postgres_volume}"; do + if ! remove_labeled_resource volume "${name}"; then + result=1 + fi + done + return "${result}" +} + +cleanup_on_exit() { + local status=$? + trap - EXIT + + if [[ -n "${metrics_tmp}" && -f "${metrics_tmp}" ]]; then + rm -f "${metrics_tmp}" + fi + + if (( status != 0 && keep_on_failure == 1 )); then + cat >&2 </dev/null 2>&1; do + (( SECONDS < deadline )) || fail "PostgreSQL did not become ready within ${timeout_seconds} seconds" + sleep 1 + done +} + +wait_for_redis() { + local deadline=$((SECONDS + timeout_seconds)) + until docker exec "${redis_container}" redis-cli --no-auth-warning -a "${redis_password}" ping 2>/dev/null | grep -q '^PONG$'; do + (( SECONDS < deadline )) || fail "Redis did not become ready within ${timeout_seconds} seconds" + sleep 1 + done +} + +wait_for_minio() { + local deadline=$((SECONDS + timeout_seconds)) + until docker exec "${minio_container}" curl -fsS http://127.0.0.1:9000/minio/health/live >/dev/null 2>&1; do + (( SECONDS < deadline )) || fail "MinIO did not become ready within ${timeout_seconds} seconds" + sleep 1 + done +} + +echo "Creating isolated restore resources for rehearsal ${run_id}..." +docker network create --internal "${labels[@]}" "${network_name}" >/dev/null +docker volume create "${labels[@]}" "${postgres_volume}" >/dev/null +docker volume create "${labels[@]}" "${redis_volume}" >/dev/null +docker volume create "${labels[@]}" "${minio_volume}" >/dev/null + +echo "Restoring PostgreSQL into an empty rehearsal volume..." +docker run -d \ + --name "${postgres_container}" \ + --network "${network_name}" \ + "${labels[@]}" \ + -e POSTGRES_DB="${postgres_db}" \ + -e POSTGRES_USER="${postgres_user}" \ + -e POSTGRES_PASSWORD="${postgres_password}" \ + -v "${postgres_volume}:/var/lib/postgresql/data" \ + "${postgres_image}" >/dev/null +wait_for_postgres +docker exec -i "${postgres_container}" \ + pg_restore -U "${postgres_user}" -d "${postgres_db}" \ + --exit-on-error --no-owner --no-privileges \ + < "${backup_dir}/postgres.dump" + +core_tables_ok="$(docker exec "${postgres_container}" psql -v ON_ERROR_STOP=1 -U "${postgres_user}" -d "${postgres_db}" -Atc \ + "select case when to_regclass('drizzle.__drizzle_migrations') is not null + and to_regclass('public.users') is not null + and to_regclass('public.workspaces') is not null + and to_regclass('public.projects') is not null + and to_regclass('public.episodes') is not null + and to_regclass('public.assets') is not null + and to_regclass('public.asset_versions') is not null + and to_regclass('public.shots') is not null + and to_regclass('public.shot_versions') is not null + and to_regclass('public.generation_jobs') is not null + and to_regclass('public.renders') is not null + and to_regclass('public.provider_verifications') is not null + then 'ok' else 'missing' end")" +[[ "${core_tables_ok}" == "ok" ]] || fail "PostgreSQL restore is missing required tables" + +docker exec "${postgres_container}" psql -v ON_ERROR_STOP=1 -U "${postgres_user}" -d "${postgres_db}" -Atc \ + "select count(*) from users; + select count(*) from workspaces; + select count(*) from projects; + select count(*) from episodes; + select count(*) from assets; + select count(*) from shots; + select count(*) from generation_jobs; + select count(*) from renders; + select count(*) from provider_verifications;" >/dev/null + +migration_count="$(docker exec "${postgres_container}" psql -v ON_ERROR_STOP=1 -U "${postgres_user}" -d "${postgres_db}" -Atc \ + 'select count(*) from drizzle.__drizzle_migrations')" +table_count="$(docker exec "${postgres_container}" psql -v ON_ERROR_STOP=1 -U "${postgres_user}" -d "${postgres_db}" -Atc \ + "select count(*) from pg_tables where schemaname in ('public', 'drizzle')")" +[[ "${migration_count}" =~ ^[0-9]+$ && "${table_count}" =~ ^[0-9]+$ ]] \ + || fail "PostgreSQL verification returned invalid counts" +(( migration_count > 0 )) || fail "PostgreSQL migration history is empty" + +echo "Restoring Redis persistence into an empty rehearsal volume..." +docker run --rm \ + --name "${redis_extract_container}" \ + "${labels[@]}" \ + -v "${redis_volume}:/target" \ + --mount "type=bind,src=${backup_dir},dst=/backup,readonly" \ + --entrypoint /bin/sh \ + "${alpine_image}" -ec \ + 'test -z "$(find /target -mindepth 1 -maxdepth 1 -print -quit)" && tar -xzf /backup/redis-data.tar.gz -C /target' +docker run -d \ + --name "${redis_container}" \ + --network "${network_name}" \ + "${labels[@]}" \ + -v "${redis_volume}:/data" \ + "${redis_image}" redis-server --appendonly yes --requirepass "${redis_password}" >/dev/null +wait_for_redis +redis_key_count="$(docker exec "${redis_container}" redis-cli --no-auth-warning -a "${redis_password}" --raw DBSIZE)" +redis_persistence="$(docker exec "${redis_container}" redis-cli --no-auth-warning -a "${redis_password}" --raw INFO persistence | tr -d '\r')" +[[ "${redis_key_count}" =~ ^[0-9]+$ ]] || fail "Redis verification returned an invalid key count" +grep -q '^loading:0$' <<< "${redis_persistence}" || fail "Redis is still loading restored persistence" +grep -q '^aof_last_write_status:ok$' <<< "${redis_persistence}" || fail "Redis AOF persistence is not healthy" + +echo "Restoring MinIO data into an empty rehearsal volume..." +docker run --rm \ + --name "${minio_extract_container}" \ + "${labels[@]}" \ + -v "${minio_volume}:/target" \ + --mount "type=bind,src=${backup_dir},dst=/backup,readonly" \ + --entrypoint /bin/sh \ + "${alpine_image}" -ec \ + 'test -z "$(find /target -mindepth 1 -maxdepth 1 -print -quit)" && tar -xzf /backup/minio-data.tar.gz -C /target' +docker run -d \ + --name "${minio_container}" \ + --network "${network_name}" \ + "${labels[@]}" \ + -e MINIO_ROOT_USER="${minio_access_key}" \ + -e MINIO_ROOT_PASSWORD="${minio_secret_key}" \ + -v "${minio_volume}:/data" \ + "${minio_image}" server /data --console-address :9001 >/dev/null +wait_for_minio +minio_object_count="$(docker run --rm \ + --name "${minio_check_container}" \ + --network "${network_name}" \ + "${labels[@]}" \ + -e MC_HOST_RESTORE="http://${minio_access_key}:${minio_secret_key}@${minio_container}:9000" \ + --entrypoint /bin/sh \ + "${mc_image}" -ec \ + 'mc admin info RESTORE >/dev/null && mc ls RESTORE >/dev/null && mc ls --recursive RESTORE | wc -l | tr -d "[:space:]"')" +[[ "${minio_object_count}" =~ ^[0-9]+$ ]] || fail "MinIO verification returned an invalid object count" + +echo "Cleaning isolated restore resources..." +cleanup_resources || fail "one or more rehearsal resources failed label verification or cleanup" +resources_cleaned=1 + +completed_at_seconds="$(date +%s)" +mkdir -p "${metrics_dir}" +metrics_tmp="$(mktemp "${metrics_dir%/}/frameflow_restore.prom.tmp.XXXXXX")" +cat > "${metrics_tmp}" <&2 <<'EOF' +Usage: scheduled-maintenance.sh + +Requires FRAMEFLOW_BACKUP_MOUNTPOINT and FRAMEFLOW_BACKUP_DESTINATION. +The destination must be a writable directory inside the active mount point. +EOF + exit "${1:-2}" +} + +fail() { + echo "Scheduled maintenance failed: $1" >&2 + exit 1 +} + +[[ $# -eq 1 ]] || usage +case "$1" in + backup|restore-latest) mode="$1" ;; + --help|-h) usage 0 ;; + *) usage ;; +esac + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +mount_point="${FRAMEFLOW_BACKUP_MOUNTPOINT:-}" +backup_destination="${FRAMEFLOW_BACKUP_DESTINATION:-}" + +[[ -n "${mount_point}" ]] || fail "FRAMEFLOW_BACKUP_MOUNTPOINT is required" +[[ -n "${backup_destination}" ]] || fail "FRAMEFLOW_BACKUP_DESTINATION is required" + +for path in "${mount_point}" "${backup_destination}"; do + [[ "${path}" == /* ]] || fail "backup paths must be absolute: ${path}" + [[ "${path}" != "/" ]] || fail "the filesystem root cannot be used for backups" + [[ ! "${path}" =~ [[:space:]] ]] || fail "backup paths must not contain whitespace: ${path}" + [[ -d "${path}" ]] || fail "backup directory does not exist: ${path}" + [[ ! -L "${path}" ]] || fail "backup paths must not be symbolic links: ${path}" +done + +mount_point="$(cd "${mount_point}" && pwd -P)" +backup_destination="$(cd "${backup_destination}" && pwd -P)" +if [[ "${backup_destination}" != "${mount_point}" && "${backup_destination}" != "${mount_point}/"* ]]; then + fail "backup destination must be inside FRAMEFLOW_BACKUP_MOUNTPOINT" +fi +[[ -w "${backup_destination}" ]] || fail "backup destination is not writable: ${backup_destination}" + +command -v findmnt >/dev/null 2>&1 || fail "findmnt is required to verify the backup mount" +mounted_target="$(findmnt -rn -M "${mount_point}" -o TARGET 2>/dev/null)" \ + || fail "backup mount is not active: ${mount_point}" +[[ "${mounted_target}" == "${mount_point}" ]] \ + || fail "backup mount resolved to an unexpected target: ${mounted_target}" + +case "${mode}" in + backup) + exec "${script_dir}/backup.sh" "${backup_destination}" + ;; + restore-latest) + latest_name="" + latest_path="" + while IFS= read -r -d '' candidate; do + [[ ! -L "${candidate}" ]] || continue + candidate_name="${candidate##*/}" + [[ "${candidate_name}" =~ ^frameflow-[0-9]{8}T[0-9]{6}Z$ ]] || continue + if [[ -z "${latest_name}" || "${candidate_name}" > "${latest_name}" ]]; then + latest_name="${candidate_name}" + latest_path="${candidate}" + fi + done < <(find "${backup_destination}" -mindepth 1 -maxdepth 1 -type d -name 'frameflow-*' -print0) + + [[ -n "${latest_path}" ]] || fail "no timestamped FrameFlow backup was found" + echo "Selected latest backup for restore rehearsal: ${latest_path}" + "${script_dir}/verify-backup.sh" "${latest_path}" + exec "${script_dir}/rehearse-restore.sh" "${latest_path}" + ;; +esac diff --git a/scripts/smoke-test.mjs b/scripts/smoke-test.mjs new file mode 100755 index 0000000..9eada6e --- /dev/null +++ b/scripts/smoke-test.mjs @@ -0,0 +1,927 @@ +#!/usr/bin/env node + +import { createHash, randomUUID } from 'node:crypto' +import { readFile } from 'node:fs/promises' +import { basename, extname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const scriptPath = fileURLToPath(import.meta.url) +const defaultImagePath = fileURLToPath(new URL('../public/assets/scene-rooftop.jpg', import.meta.url)) +const terminalJobStatuses = new Set(['SUCCEEDED', 'FAILED', 'CANCELLED']) +const billableAiAcknowledgement = 'I_ACCEPT_BILLABLE_AI_CHARGES' +export const requiredLiveAiWorkflowIds = ['script', 'storyboard', 'image-openai', 'image-replicate', 'tts', 'video', 'lipsync'] + +export class SmokeTestError extends Error { + constructor(message, options = {}) { + super(message, options) + this.name = 'SmokeTestError' + this.report = options.report + } +} + +function required(value, name) { + if (typeof value !== 'string' || value.trim() === '') throw new SmokeTestError(`${name} is required`) + return value.trim() +} + +function booleanValue(value) { + return ['1', 'true', 'yes', 'on'].includes(String(value ?? '').trim().toLowerCase()) +} + +function integerValue(value, name, minimum, maximum) { + const parsed = Number(value) + if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) { + throw new SmokeTestError(`${name} must be an integer from ${minimum} to ${maximum}`) + } + return parsed +} + +function jsonObjectValue(value, name) { + if (value === undefined || value === null || String(value).trim() === '') return {} + let parsed + try { + parsed = JSON.parse(String(value)) + } catch { + throw new SmokeTestError(`${name} must be valid JSON`) + } + if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') { + throw new SmokeTestError(`${name} must be a JSON object`) + } + return parsed +} + +export function resolveEndpoints(value, options = {}) { + const input = required(value, 'FRAMEFLOW_SMOKE_BASE_URL') + let url + try { + url = new URL(input) + } catch { + throw new SmokeTestError('FRAMEFLOW_SMOKE_BASE_URL must be a valid URL') + } + if (url.username || url.password || url.search || url.hash) { + throw new SmokeTestError('Smoke-test base URL cannot contain credentials, a query, or a fragment') + } + if (!['http:', 'https:'].includes(url.protocol)) throw new SmokeTestError('Smoke-test base URL must use HTTP or HTTPS') + const localHostnames = new Set(['localhost', '127.0.0.1', '::1', '[::1]']) + if (url.protocol === 'http:' && (!options.allowHttp || !localHostnames.has(url.hostname))) { + throw new SmokeTestError('HTTPS is required; HTTP can only be enabled explicitly for localhost') + } + const path = url.pathname.replace(/\/+$/, '') + if (path && path !== '/api/v1') { + throw new SmokeTestError('Smoke-test base URL path must be empty or /api/v1') + } + const origin = url.origin + return { origin, apiBase: `${origin}/api/v1` } +} + +export function parseSmokeOptions(argv = process.argv.slice(2), environment = process.env) { + const values = {} + const flags = new Set() + const valueOptions = new Set(['--base-url', '--email', '--workspace-id', '--image', '--timeout-seconds', '--ai-video-seconds']) + const flagOptions = new Set(['--allow-http', '--keep-project', '--include-ai', '--json', '--help']) + for (let index = 0; index < argv.length; index += 1) { + const argument = argv[index] + if (valueOptions.has(argument)) { + const value = argv[index + 1] + if (!value || value.startsWith('--')) throw new SmokeTestError(`${argument} requires a value`) + values[argument] = value + index += 1 + } else if (flagOptions.has(argument)) { + flags.add(argument) + } else { + throw new SmokeTestError(`Unknown option: ${argument}`) + } + } + if (flags.has('--help')) return { help: true } + + const allowHttp = flags.has('--allow-http') || booleanValue(environment.FRAMEFLOW_SMOKE_ALLOW_HTTP) + const endpoints = resolveEndpoints(values['--base-url'] ?? environment.FRAMEFLOW_SMOKE_BASE_URL, { allowHttp }) + const email = required(values['--email'] ?? environment.FRAMEFLOW_SMOKE_EMAIL, 'FRAMEFLOW_SMOKE_EMAIL').toLowerCase() + const password = required(environment.FRAMEFLOW_SMOKE_PASSWORD, 'FRAMEFLOW_SMOKE_PASSWORD') + const timeoutSeconds = integerValue(values['--timeout-seconds'] ?? environment.FRAMEFLOW_SMOKE_TIMEOUT_SECONDS ?? '180', 'timeout-seconds', 30, 900) + const includeAi = flags.has('--include-ai') + if (includeAi && environment.FRAMEFLOW_SMOKE_BILLABLE_AI_ACK !== billableAiAcknowledgement) { + throw new SmokeTestError(`--include-ai requires FRAMEFLOW_SMOKE_BILLABLE_AI_ACK=${billableAiAcknowledgement}`) + } + return { + ...endpoints, + email, + password, + workspaceId: values['--workspace-id'] ?? environment.FRAMEFLOW_SMOKE_WORKSPACE_ID ?? null, + imagePath: resolve(values['--image'] ?? environment.FRAMEFLOW_SMOKE_IMAGE ?? defaultImagePath), + timeoutMs: timeoutSeconds * 1000, + requestTimeoutMs: Math.min(60_000, timeoutSeconds * 1000), + keepProject: flags.has('--keep-project') || booleanValue(environment.FRAMEFLOW_SMOKE_KEEP_PROJECT), + includeAi, + aiVideoSeconds: integerValue(values['--ai-video-seconds'] ?? environment.FRAMEFLOW_SMOKE_AI_VIDEO_SECONDS ?? '5', 'ai-video-seconds', 1, 30), + aiVideoParams: jsonObjectValue(environment.FRAMEFLOW_SMOKE_VIDEO_PARAMS_JSON, 'FRAMEFLOW_SMOKE_VIDEO_PARAMS_JSON'), + aiLipsyncParams: jsonObjectValue(environment.FRAMEFLOW_SMOKE_LIPSYNC_PARAMS_JSON, 'FRAMEFLOW_SMOKE_LIPSYNC_PARAMS_JSON'), + json: flags.has('--json'), + } +} + +function safeError(error) { + const message = error instanceof Error ? error.message : String(error) + return message.replace(/([?&](?:X-Amz-[^=\s]+|token|signature)=)[^&\s]+/gi, '$1[redacted]').slice(0, 2000) +} + +function assertCondition(condition, message) { + if (!condition) throw new SmokeTestError(message) +} + +function sha256(value) { + return createHash('sha256').update(value).digest('hex') +} + +function imageContentType(path) { + const extension = extname(path).toLowerCase() + if (extension === '.jpg' || extension === '.jpeg') return 'image/jpeg' + if (extension === '.png') return 'image/png' + if (extension === '.webp') return 'image/webp' + throw new SmokeTestError('Smoke-test image must be JPEG, PNG, or WebP') +} + +function responseBody(response) { + if (response.status === 204) return Promise.resolve(null) + const contentType = response.headers.get('content-type') ?? '' + if (contentType.includes('application/json')) return response.json() + return response.text() +} + +async function fetchWithTimeout(fetchImpl, url, options, timeoutMs) { + const controller = new AbortController() + const timer = setTimeout(() => controller.abort(new Error(`Request timed out after ${timeoutMs}ms`)), timeoutMs) + try { + return await fetchImpl(url, { ...options, signal: controller.signal }) + } finally { + clearTimeout(timer) + } +} + +function createApiClient(options, fetchImpl) { + let accessToken = null + const cookies = new Map() + + function captureCookies(headers) { + const values = typeof headers.getSetCookie === 'function' + ? headers.getSetCookie() + : headers.get('set-cookie') ? [headers.get('set-cookie')] : [] + for (const value of values) { + const pair = value?.split(';', 1)[0] + const separator = pair?.indexOf('=') ?? -1 + if (!pair || separator < 1) continue + const name = pair.slice(0, separator).trim() + const cookieValue = pair.slice(separator + 1).trim() + if (!cookieValue || /(?:^|;)\s*max-age=0(?:;|$)/i.test(value)) cookies.delete(name) + else cookies.set(name, cookieValue) + } + } + + async function raw(path, request = {}) { + const headers = new Headers(request.headers) + const url = path.startsWith('http://') || path.startsWith('https://') ? path : `${options.apiBase}${path}` + const authenticatedApiRequest = request.auth !== false && (url === options.apiBase || url.startsWith(`${options.apiBase}/`)) + if (accessToken && authenticatedApiRequest) headers.set('authorization', `Bearer ${accessToken}`) + if (authenticatedApiRequest && cookies.size > 0) { + headers.set('cookie', [...cookies].map(([name, value]) => `${name}=${value}`).join('; ')) + } + let body = request.body + if (request.json !== undefined) { + headers.set('content-type', 'application/json') + body = JSON.stringify(request.json) + } + const response = await fetchWithTimeout(fetchImpl, url, { + method: request.method ?? 'GET', + headers, + body, + redirect: request.redirect ?? 'follow', + }, request.timeoutMs ?? options.requestTimeoutMs) + captureCookies(response.headers) + return response + } + async function request(path, input = {}) { + const response = await raw(path, input) + const body = await responseBody(response) + if (!response.ok) { + const message = body?.error?.message ?? (typeof body === 'string' && body) ?? `HTTP ${response.status}` + throw new SmokeTestError(`${input.method ?? 'GET'} ${path} failed (${response.status}): ${message}`) + } + return body + } + return { + raw, + request, + setAccessToken(value) { accessToken = value }, + clearSession() { + accessToken = null + cookies.clear() + }, + } +} + +export async function waitForJob(getJob, jobId, options = {}) { + const timeoutMs = options.timeoutMs ?? 180_000 + const pollIntervalMs = options.pollIntervalMs ?? 500 + const sleep = options.sleep ?? ((milliseconds) => new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds))) + const now = options.now ?? Date.now + const startedAt = now() + let lastStatus = null + while (now() - startedAt <= timeoutMs) { + const job = await getJob(jobId) + lastStatus = job?.status ?? null + if (lastStatus === 'SUCCEEDED') return job + if (terminalJobStatuses.has(lastStatus)) { + throw new SmokeTestError(`Job ${jobId} ended in ${lastStatus}: ${job.errorMessage ?? job.errorCode ?? 'unknown error'}`) + } + await sleep(pollIntervalMs) + } + throw new SmokeTestError(`Job ${jobId} did not finish within ${timeoutMs}ms (last status: ${lastStatus ?? 'unknown'})`) +} + +export async function waitForNotifications(getNotifications, resourceIds, options = {}) { + const timeoutMs = options.timeoutMs ?? 10_000 + const pollIntervalMs = options.pollIntervalMs ?? 250 + const sleep = options.sleep ?? ((milliseconds) => new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds))) + const now = options.now ?? Date.now + const expected = new Set(resourceIds) + const startedAt = now() + let lastItems = [] + while (now() - startedAt <= timeoutMs) { + const page = await getNotifications() + lastItems = Array.isArray(page?.items) ? page.items : [] + const matched = lastItems.filter((notification) => expected.has(notification.resourceId)) + if (new Set(matched.map((notification) => notification.resourceId)).size === expected.size) return matched + await sleep(pollIntervalMs) + } + const matchedIds = new Set(lastItems.map((notification) => notification.resourceId)) + const missing = [...expected].filter((resourceId) => !matchedIds.has(resourceId)) + throw new SmokeTestError(`Notifications did not arrive within ${timeoutMs}ms (missing resources: ${missing.join(', ')})`) +} + +function selectWorkspace(workspaces, requestedId) { + assertCondition(Array.isArray(workspaces) && workspaces.length > 0, 'Smoke account has no workspace membership') + const workspace = requestedId + ? workspaces.find((candidate) => candidate.id === requestedId) + : workspaces.length === 1 ? workspaces[0] : null + if (!workspace) { + throw new SmokeTestError(requestedId + ? `Smoke account is not a member of workspace ${requestedId}` + : 'Smoke account belongs to multiple workspaces; set FRAMEFLOW_SMOKE_WORKSPACE_ID') + } + assertCondition(['OWNER', 'ADMIN'].includes(workspace.role), 'Full smoke test requires an OWNER or ADMIN workspace role') + return workspace +} + +async function downloadBytes(fetchImpl, url, timeoutMs, expectedType) { + const response = await fetchWithTimeout(fetchImpl, url, { redirect: 'follow' }, timeoutMs) + assertCondition(response.ok, `Media download failed with HTTP ${response.status}`) + const contentType = response.headers.get('content-type') ?? '' + if (expectedType) assertCondition(contentType.toLowerCase().includes(expectedType), `Unexpected media content type: ${contentType || 'missing'}`) + return Buffer.from(await response.arrayBuffer()) +} + +function readinessSummary(readiness) { + return { + infrastructure: readiness.infrastructure, + ai: { + status: readiness.ai?.status ?? 'UNKNOWN', + verificationMode: readiness.ai?.verificationMode ?? 'UNKNOWN', + summary: readiness.ai?.summary ?? null, + workflows: (readiness.ai?.workflows ?? []).map((workflow) => ({ + id: workflow.id, + provider: workflow.provider, + model: workflow.model, + status: workflow.status, + })), + providers: (readiness.ai?.providers ?? []).map((provider) => ({ + id: provider.id, + status: provider.status, + verification: provider.verification, + configuredCapabilities: provider.configuredCapabilities, + totalCapabilities: provider.totalCapabilities, + })), + }, + } +} + +export function assertLiveAiReady(readiness, minimumCredits = 700, billing = null) { + const capabilityRows = [ + ...(readiness?.ai?.providers ?? []).flatMap((provider) => provider.capabilities ?? []), + ...(readiness?.ai?.workflows ?? []), + ] + const workflows = new Map(capabilityRows.map((workflow) => [workflow.id, workflow])) + const missing = requiredLiveAiWorkflowIds.filter((id) => workflows.get(id)?.status !== 'CONFIGURED') + if (missing.length > 0) { + const details = missing.map((id) => { + const workflow = workflows.get(id) + const requirements = workflow?.missingRequirements?.join(', ') + return requirements ? `${id} (${requirements})` : id + }) + throw new SmokeTestError(`Live AI smoke test requires configured workflows: ${details.join('; ')}`) + } + if (billing && Number(billing.remainingCredits) < minimumCredits) { + throw new SmokeTestError(`Live AI smoke test requires at least ${minimumCredits} remaining credits`) + } + return requiredLiveAiWorkflowIds.map((id) => { + const workflow = workflows.get(id) + return { id, provider: workflow.provider, model: workflow.model } + }) +} + +export async function runProductionSmoke(options, dependencies = {}) { + const fetchImpl = dependencies.fetch ?? fetch + const readFileImpl = dependencies.readFile ?? readFile + const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds))) + const now = dependencies.now ?? Date.now + const log = dependencies.log ?? ((message) => console.error(message)) + const api = createApiClient(options, fetchImpl) + const startedAt = now() + const runId = randomUUID() + const marker = `FRAMEFLOW_SMOKE_${runId}` + const report = { + status: 'running', + runId, + baseUrl: options.origin, + startedAt: new Date(startedAt).toISOString(), + workspaceId: null, + projectId: null, + projectArchived: false, + checks: [], + services: null, + billing: null, + aiVerification: { + mode: options.includeAi ? 'LIVE_PROVIDER_CALLS' : 'CONFIGURATION_ONLY', + jobs: [], + artifacts: {}, + }, + artifacts: {}, + } + let projectId = null + let loggedIn = false + let smokeSessionId = null + let primaryError = null + + async function step(id, label, action, summarize) { + const stepStartedAt = now() + log(`[...] ${label}`) + try { + const value = await action() + const check = { id, label, status: 'passed', durationMs: Math.max(0, now() - stepStartedAt) } + const details = summarize?.(value) + if (details !== undefined) check.details = details + report.checks.push(check) + log(`[ ok] ${label} (${check.durationMs}ms)`) + return value + } catch (error) { + const check = { id, label, status: 'failed', durationMs: Math.max(0, now() - stepStartedAt), error: safeError(error) } + report.checks.push(check) + log(`[fail] ${label}: ${check.error}`) + throw error + } + } + + async function runAiJob(projectIdForJob, episodeIdForJob, type, input) { + const queued = await api.request(`/projects/${projectIdForJob}/jobs`, { + method: 'POST', + json: { + type, + episodeId: episodeIdForJob, + idempotencyKey: `smoke-ai-${runId}-${report.aiVerification.jobs.length}-${type.toLowerCase()}`, + input, + maxAttempts: 1, + }, + }) + const job = await waitForJob((jobId) => api.request(`/jobs/${jobId}`), queued.job.id, { + timeoutMs: options.timeoutMs, + sleep, + }) + assertCondition(['openai', 'replicate'].includes(job.provider), `${type} did not record a live AI provider`) + assertCondition(job.providerModel, `${type} did not record a provider model`) + report.aiVerification.jobs.push({ id: job.id, type, provider: job.provider, model: job.providerModel }) + return job + } + + try { + await step('liveness', 'API liveness', async () => { + const response = await fetchWithTimeout(fetchImpl, `${options.origin}/health/live`, {}, options.requestTimeoutMs) + const body = await responseBody(response) + assertCondition(response.ok && body?.status === 'ok', `Liveness failed with HTTP ${response.status}`) + return body + }) + + await step('readiness', 'API dependency readiness', async () => { + const response = await fetchWithTimeout(fetchImpl, `${options.origin}/health/ready`, {}, options.requestTimeoutMs) + const body = await responseBody(response) + assertCondition(response.ok && body?.status === 'ready', `Readiness failed with HTTP ${response.status}`) + const unavailable = Object.entries(body.dependencies ?? {}).filter(([, status]) => status !== 'ok') + assertCondition(unavailable.length === 0, `Unavailable dependencies: ${unavailable.map(([name]) => name).join(', ')}`) + return body + }, (body) => body.dependencies) + + const session = await step('login', 'Dedicated smoke-account login', async () => { + const value = await api.request('/auth/login', { + method: 'POST', + auth: false, + json: { email: options.email, password: options.password }, + }) + assertCondition(value?.accessToken && value?.user?.id, 'Login response is missing the authenticated session') + api.setAccessToken(value.accessToken) + loggedIn = true + const sessions = await api.request('/auth/sessions') + const currentSession = sessions.find((candidate) => candidate.current) + assertCondition(currentSession?.id, 'Login refresh session cookie was not retained by the smoke runner') + smokeSessionId = currentSession.id + return value + }, (value) => ({ userId: value.user.id, sessionId: smokeSessionId, workspaceCount: value.workspaces.length })) + + const workspace = selectWorkspace(session.workspaces, options.workspaceId) + report.workspaceId = workspace.id + const serviceReadiness = await step('service-readiness', 'Worker, storage, FFmpeg, and AI configuration', async () => { + const value = await api.request(`/workspaces/${workspace.id}/service-readiness`) + assertCondition(value?.infrastructure?.status === 'AVAILABLE', 'Authenticated service readiness is degraded') + assertCondition(value.infrastructure.available === value.infrastructure.total, 'Not every production service is available') + return value + }, (value) => ({ + infrastructure: value.infrastructure.services.map((service) => ({ id: service.id, status: service.status, latencyMs: service.latencyMs })), + ai: value.ai.summary, + })) + report.services = readinessSummary(serviceReadiness) + + const billingReadModel = await step('billing', 'Billing and usage read model', async () => { + const value = await api.request(`/workspaces/${workspace.id}/billing/summary`) + assertCondition(value?.plan && value?.provider?.status, 'Billing summary is incomplete') + return value + }, (value) => ({ plan: value.plan, provider: value.provider.status, webhookConfigured: value.provider.webhookConfigured, remainingCredits: value.remainingCredits })) + report.billing = { + plan: billingReadModel.plan, + provider: billingReadModel.provider.status, + webhookConfigured: billingReadModel.provider.webhookConfigured, + remainingCredits: billingReadModel.remainingCredits, + } + + if (options.includeAi) { + await step('ai-preflight', 'Billable AI authorization, configuration, and credit preflight', async () => { + const workflows = assertLiveAiReady(serviceReadiness, 700, billingReadModel) + return { acknowledgement: 'accepted', minimumCredits: 700, workflows } + }, (value) => value) + } + + const project = await step('project', 'Project persistence', async () => api.request(`/workspaces/${workspace.id}/projects`, { + method: 'POST', + json: { + name: `[SMOKE] ${new Date(startedAt).toISOString()} ${runId.slice(0, 8)}`, + logline: 'Automated production smoke test. Safe to archive after completion.', + genre: 'SMOKE_TEST', + visualBible: { smokeTest: { runId, createdAt: new Date(startedAt).toISOString() } }, + }, + }), (value) => ({ projectId: value.id })) + projectId = project.id + report.projectId = projectId + + const episode = await step('script', 'Episode and immutable script persistence', async () => { + const createdEpisode = await api.request(`/projects/${projectId}/episodes`, { + method: 'POST', + json: { episodeNumber: 1, title: 'Production smoke episode', synopsis: marker, targetDurationSeconds: 15 }, + }) + const script = await api.request(`/episodes/${createdEpisode.id}/scripts`, { + method: 'POST', + json: { + title: 'Production smoke script', + content: { smokeTest: true, runId, scenes: [{ number: 1, text: marker }] }, + plainText: `SCENE 1 - SMOKE TEST\n${marker}`, + changeSummary: 'Production smoke test', + }, + }) + const persisted = await api.request(`/episodes/${createdEpisode.id}`) + assertCondition(persisted.currentScript?.id === script.id, 'Current script version was not persisted') + assertCondition(persisted.currentScript?.plainText?.includes(marker), 'Persisted script marker is missing') + return { episode: createdEpisode, script } + }, (value) => ({ episodeId: value.episode.id, scriptVersion: value.script.version })) + + const sourceImage = await readFileImpl(options.imagePath) + const sourceHash = sha256(sourceImage) + const contentType = imageContentType(options.imagePath) + const imageAssetVersion = await step('upload', 'Object upload and signed download integrity', async () => { + const form = new FormData() + form.append('file', new Blob([sourceImage], { type: contentType }), basename(options.imagePath)) + const upload = await api.request(`/projects/${projectId}/uploads`, { method: 'POST', body: form }) + assertCondition(upload.byteSize === sourceImage.length, 'Uploaded object byte size does not match the source') + const asset = await api.request(`/projects/${projectId}/assets`, { + method: 'POST', + json: { type: 'SHOT', name: `Smoke source ${runId.slice(0, 8)}`, description: marker, tags: ['smoke-test'], metadata: { smokeRunId: runId } }, + }) + const version = await api.request(`/assets/${asset.id}/versions`, { + method: 'POST', + json: { storageKey: upload.key, mimeType: upload.contentType, byteSize: upload.byteSize, prompt: marker, provider: 'smoke-test', providerModel: 'uploaded-source-v1' }, + }) + const signed = await api.request(`/assets/${asset.id}/versions/${version.id}/url`) + const downloaded = await downloadBytes(fetchImpl, signed.url, options.requestTimeoutMs, contentType) + assertCondition(sha256(downloaded) === sourceHash, 'Signed object download does not match the uploaded image') + return { asset, version, upload } + }, (value) => ({ assetId: value.asset.id, assetVersionId: value.version.id, byteSize: value.upload.byteSize, sha256: sourceHash })) + + const shot = await step('shot', 'Shot and immutable media-version persistence', async () => { + const created = await api.request(`/episodes/${episode.episode.id}/shots`, { + method: 'POST', + json: { shotNumber: 1, sceneNumber: 1, title: 'Smoke render shot', description: marker, shotType: '全景', cameraMotion: '静止', durationMs: 2000, characterAssetIds: [], sortOrder: 100 }, + }) + const version = await api.request(`/shots/${created.id}/versions`, { + method: 'POST', + json: { imageAssetVersionId: imageAssetVersion.version.id, subtitleText: marker, generationParams: { smokeRunId: runId } }, + }) + const persisted = await api.request(`/shots/${created.id}`) + assertCondition(persisted.versions?.[0]?.id === version.id, 'Current shot version was not persisted') + return { shot: created, version } + }, (value) => ({ shotId: value.shot.id, shotVersion: value.version.version })) + + await step('queue', 'Redis/BullMQ worker execution', async () => { + const queued = await api.request(`/projects/${projectId}/jobs`, { + method: 'POST', + json: { type: 'PIPELINE_HEALTHCHECK', episodeId: episode.episode.id, idempotencyKey: `smoke-health-${runId}`, input: { marker }, maxAttempts: 1 }, + }) + const job = await waitForJob((jobId) => api.request(`/jobs/${jobId}`), queued.job.id, { timeoutMs: options.timeoutMs, sleep }) + assertCondition(job.output?.ok === true && job.output?.echo?.marker === marker, 'Worker healthcheck output is invalid') + return job + }, (job) => ({ jobId: job.id, provider: job.provider, providerModel: job.providerModel })) + + const renderResult = await step('render', 'FFmpeg render and immutable source manifest', async () => { + const queued = await api.request(`/episodes/${episode.episode.id}/renders`, { + method: 'POST', + json: { + idempotencyKey: `smoke-render-${runId}`, + settings: { width: 640, height: 360, fps: 24, quality: 'draft', burnSubtitles: false, normalizeAudio: false, musicVolume: 0, subtitleStyle: { fontSize: 20, textColor: '#FFFFFF', outlineColor: '#000000', outlineWidth: 2, bottomMargin: 24, bold: true } }, + }, + }) + const job = await waitForJob((jobId) => api.request(`/jobs/${jobId}`), queued.job.id, { timeoutMs: options.timeoutMs, sleep }) + const render = await api.request(`/renders/${queued.render.id}`) + assertCondition(render.status === 'REVIEW', `Render ended in unexpected status ${render.status}`) + assertCondition(render.sourceShotCount === 1, 'Render source manifest does not contain exactly one shot') + assertCondition(render.subtitleFormats?.includes('srt') && render.subtitleFormats?.includes('vtt'), 'Render subtitle sidecars are missing') + assertCondition(render.downloadUrl, 'Render download URL is missing') + const video = await downloadBytes(fetchImpl, render.downloadUrl, options.requestTimeoutMs, 'video/mp4') + assertCondition(video.length > 1000, 'Rendered video is unexpectedly small') + return { render, job, videoHash: sha256(video), videoBytes: video.length } + }, (value) => ({ renderId: value.render.id, jobId: value.job.id, byteSize: value.videoBytes, subtitleFormats: value.render.subtitleFormats, sourceShotCount: value.render.sourceShotCount })) + report.artifacts.renderId = renderResult.render.id + report.artifacts.videoSha256 = renderResult.videoHash + + await step('subtitles', 'SRT and VTT sidecar downloads', async () => { + const results = {} + for (const format of ['srt', 'vtt']) { + const subtitle = await api.request(`/renders/${renderResult.render.id}/subtitles/${format}`) + const bytes = await downloadBytes(fetchImpl, subtitle.downloadUrl, options.requestTimeoutMs) + const text = bytes.toString('utf8') + assertCondition(text.includes(marker), `${format.toUpperCase()} subtitle does not contain the smoke marker`) + results[format] = { bytes: bytes.length, sha256: sha256(bytes) } + } + return results + }, (value) => value) + + await step('review', 'Render review and approval', async () => { + const review = await api.request(`/workspaces/${workspace.id}/reviews`, { + method: 'POST', + json: { targetType: 'RENDER', targetId: renderResult.render.id, assignedToId: session.user.id, summary: `Automated approval for ${marker}` }, + }) + const decision = await api.request(`/reviews/${review.id}/decision`, { + method: 'POST', + json: { status: 'APPROVED', summary: 'Production smoke render passed automated checks.' }, + }) + const approved = await api.request(`/renders/${renderResult.render.id}`) + assertCondition(decision.status === 'APPROVED' && approved.status === 'APPROVED', 'Render approval was not persisted') + return { review, approved } + }, (value) => ({ reviewId: value.review.id, renderStatus: value.approved.status })) + + const deliveryResult = await step('delivery', 'Approved download delivery through the worker', async () => { + const queued = await api.request(`/renders/${renderResult.render.id}/deliveries`, { + method: 'POST', + json: { platform: 'DOWNLOAD', destination: { smokeRunId: runId } }, + }) + const job = await waitForJob((jobId) => api.request(`/jobs/${jobId}`), queued.job.id, { timeoutMs: options.timeoutMs, sleep }) + const delivery = await api.request(`/deliveries/${queued.delivery.id}`) + assertCondition(delivery.status === 'PUBLISHED' && delivery.downloadUrl, 'Download delivery was not published') + const redirect = await api.raw(`/deliveries/${delivery.id}/download`, { redirect: 'manual' }) + assertCondition([301, 302, 303, 307, 308].includes(redirect.status), `Delivery endpoint returned HTTP ${redirect.status} instead of a redirect`) + const location = redirect.headers.get('location') + assertCondition(location, 'Delivery redirect is missing its signed location') + const video = await downloadBytes(fetchImpl, location, options.requestTimeoutMs, 'video/mp4') + assertCondition(sha256(video) === renderResult.videoHash, 'Delivered video differs from the approved render') + return { delivery, job, bytes: video.length } + }, (value) => ({ deliveryId: value.delivery.id, jobId: value.job.id, status: value.delivery.status, byteSize: value.bytes })) + report.artifacts.deliveryId = deliveryResult.delivery.id + + await step('notifications', 'Persistent job notifications and read state', async () => { + const expectedJobIds = [renderResult.job.id, deliveryResult.job.id] + const rows = await waitForNotifications( + () => api.request(`/workspaces/${workspace.id}/notifications?limit=100`), + expectedJobIds, + { timeoutMs: Math.min(options.timeoutMs, 10_000), sleep, now }, + ) + for (const jobId of expectedJobIds) { + const notification = rows.find((candidate) => candidate.resourceId === jobId) + assertCondition(notification?.kind === 'JOB_SUCCEEDED' && notification.tone === 'SUCCESS', `Successful job notification is invalid for ${jobId}`) + const expectedPage = jobId === deliveryResult.job.id ? 'publish' : 'jobs' + assertCondition(notification.page === expectedPage, `Job notification points to ${notification.page} instead of ${expectedPage}`) + const read = await api.request(`/notifications/${notification.id}`, { method: 'PATCH', json: { read: true } }) + assertCondition(read.readAt, `Notification ${notification.id} did not persist its read state`) + } + return rows + }, (rows) => ({ notifications: rows.length, resources: rows.map((notification) => notification.resourceId) })) + + await step('audit', 'Audit-log persistence', async () => { + const page = await api.request(`/workspaces/${workspace.id}/audit-logs?limit=100&actorId=${session.user.id}`) + const actions = new Set((page.items ?? []).map((item) => item.action)) + for (const action of ['project.create', 'upload.create', 'render.create', 'review.decide', 'delivery.create']) { + assertCondition(actions.has(action), `Audit log is missing ${action}`) + } + return { actions: actions.size } + }, (value) => value) + + if (options.includeAi) { + const aiSetup = await step('ai-setup', 'Live AI validation workspace data', async () => { + const aiEpisode = await api.request(`/projects/${projectId}/episodes`, { + method: 'POST', + json: { + episodeNumber: 2, + title: 'Live provider validation', + synopsis: `A single character says a short line in a controlled studio. ${marker}`, + targetDurationSeconds: 15, + }, + }) + const character = await api.request(`/projects/${projectId}/assets`, { + method: 'POST', + json: { + type: 'CHARACTER', + name: `Provider test character ${runId.slice(0, 8)}`, + description: 'Adult presenter, centered portrait, neutral studio lighting, production-safe wardrobe.', + tags: ['smoke-test', 'provider-validation'], + metadata: { smokeRunId: runId }, + }, + }) + return { episode: aiEpisode, character } + }, (value) => ({ episodeId: value.episode.id, characterAssetId: value.character.id })) + + const openAiImage = await step('ai-image-openai', 'OpenAI character image generation', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'ASSET_GENERATE', { + assetId: aiSetup.character.id, + prompt: `Clean comic-drama character reference sheet. Adult presenter, centered bust portrait, neutral gray studio, consistent facial landmarks. ${marker}`, + negativePrompt: 'text, watermark, extra limbs, child', + width: 1024, + height: 1024, + provider: 'openai', + referenceAssetVersionIds: [], + params: { consistencyStrength: 82 }, + }) + const asset = await api.request(`/assets/${aiSetup.character.id}`) + const version = asset.versions?.find((candidate) => candidate.id === job.output?.assetVersionId) + assertCondition(version?.storageKey && version.provider === 'openai', 'OpenAI image version was not persisted as current asset media') + const signed = await api.request(`/assets/${asset.id}/versions/${version.id}/url`) + const bytes = await downloadBytes(fetchImpl, signed.url, options.requestTimeoutMs, 'image/') + assertCondition(bytes.length > 1000, 'OpenAI image output is unexpectedly small') + return { job, asset, version, bytes } + }, (value) => ({ jobId: value.job.id, assetVersionId: value.version.id, model: value.job.providerModel, byteSize: value.bytes.length })) + report.aiVerification.artifacts.openAiImageAssetVersionId = openAiImage.version.id + + const replicateImage = await step('ai-image-replicate', 'Replicate character-consistency variant', async () => { + const profile = await api.request(`/assets/${aiSetup.character.id}/consistency-profile`, { + method: 'PUT', + json: { + referenceAssetVersionIds: [openAiImage.version.id], + identityPrompt: 'Preserve facial proportions, eye shape, hairstyle, and adult age.', + costumePrompt: 'Preserve the dark production jacket and simple collar.', + stylePrompt: 'Polished cinematic comic-drama illustration.', + negativePrompt: 'identity drift, age change, child, text, watermark', + consistencyStrength: 90, + identityLocked: true, + }, + }) + assertCondition(profile.consistencyProfile?.identityLocked, 'Character identity profile was not locked') + const job = await runAiJob(projectId, aiSetup.episode.id, 'ASSET_GENERATE', { + assetId: aiSetup.character.id, + prompt: `The same adult presenter turns slightly toward camera under warm key light. ${marker}`, + negativePrompt: 'text, watermark', + width: 1024, + height: 1024, + provider: 'replicate', + referenceAssetVersionIds: [openAiImage.version.id], + params: { consistencyStrength: 90 }, + }) + const asset = await api.request(`/assets/${aiSetup.character.id}`) + const version = asset.versions?.find((candidate) => candidate.id === job.output?.assetVersionId) + const appliedProfiles = version?.generationParams?.appliedCharacterConsistencyProfiles + assertCondition(version?.storageKey && version.provider === 'replicate', 'Replicate image version was not persisted') + assertCondition(Array.isArray(appliedProfiles) && appliedProfiles.some((snapshot) => snapshot.assetId === aiSetup.character.id && snapshot.identityLocked), 'Replicate variant did not capture the locked character profile') + assertCondition(version.generationParams?.referenceAssetVersionIds?.includes(openAiImage.version.id), 'Replicate variant did not record its identity reference') + const signed = await api.request(`/assets/${asset.id}/versions/${version.id}/url`) + const bytes = await downloadBytes(fetchImpl, signed.url, options.requestTimeoutMs, 'image/') + assertCondition(bytes.length > 1000, 'Replicate image output is unexpectedly small') + return { job, asset, version, bytes } + }, (value) => ({ jobId: value.job.id, assetVersionId: value.version.id, model: value.job.providerModel, byteSize: value.bytes.length })) + report.aiVerification.artifacts.replicateImageAssetVersionId = replicateImage.version.id + + await step('ai-script', 'OpenAI script generation and immutable persistence', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'SCRIPT_GENERATE', { + provider: 'openai', + includeExistingScript: false, + instruction: 'Write one production-safe interior scene for a 15-second Chinese comic drama. Use one adult presenter, one short spoken line, and a clear visual action.', + }) + const episode = await api.request(`/episodes/${aiSetup.episode.id}`) + assertCondition(episode.currentScript?.id === job.output?.scriptVersionId, 'Generated script was not activated as the current version') + assertCondition(episode.currentScript?.plainText?.trim(), 'Generated script has no plain text') + return { job, script: episode.currentScript } + }, (value) => ({ jobId: value.job.id, scriptVersionId: value.script.id, version: value.script.version, model: value.job.providerModel })) + + const storyboard = await step('ai-storyboard', 'OpenAI storyboard generation and shot persistence', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'STORYBOARD_GENERATE', { + provider: 'openai', + replaceExisting: false, + instruction: `Create the smallest viable storyboard for provider validation. Prefer exactly one shot featuring ${aiSetup.character.name}, with one short spoken line and a total duration near five seconds.`, + }) + const rows = await api.request(`/episodes/${aiSetup.episode.id}/shots`) + assertCondition(Array.isArray(rows) && rows.length > 0, 'Generated storyboard contains no shots') + assertCondition(job.output?.shotCount === rows.length, 'Storyboard job output does not match persisted shots') + const [selected, ...extra] = rows + for (const row of extra) await api.request(`/shots/${row.shot.id}`, { method: 'DELETE' }) + const validationText = 'FrameFlow AI provider validation passed.' + const version = await api.request(`/shots/${selected.shot.id}/versions`, { + method: 'POST', + json: { + imageAssetVersionId: replicateImage.version.id, + subtitleText: validationText, + generationParams: { smokeRunId: runId, source: 'live-provider-smoke' }, + }, + }) + return { job, shot: selected.shot, version, removedShots: extra.length, validationText } + }, (value) => ({ jobId: value.job.id, shotId: value.shot.id, generatedShots: value.job.output.shotCount, removedShots: value.removedShots, model: value.job.providerModel })) + + await step('ai-tts', 'OpenAI TTS generation and audio storage', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'TTS_GENERATE', { + shotId: storyboard.shot.id, + text: storyboard.validationText, + voice: 'alloy', + speed: 1, + provider: 'openai', + }) + const media = await api.request(`/shots/${storyboard.shot.id}/media`) + assertCondition(job.output?.audioStorageKey && media.audioUrl, 'TTS output was not bound to the current shot version') + const bytes = await downloadBytes(fetchImpl, media.audioUrl, options.requestTimeoutMs, 'audio/') + assertCondition(bytes.length > 500, 'TTS audio output is unexpectedly small') + return { job, media, bytes } + }, (value) => ({ jobId: value.job.id, model: value.job.providerModel, byteSize: value.bytes.length })) + + await step('ai-video', 'Replicate image-to-video generation and storage', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'VIDEO_GENERATE', { + shotId: storyboard.shot.id, + prompt: 'Subtle natural head turn and blinking, locked camera, stable adult character identity.', + imageAssetVersionId: replicateImage.version.id, + durationSeconds: options.aiVideoSeconds, + provider: 'replicate', + params: options.aiVideoParams, + }) + const media = await api.request(`/shots/${storyboard.shot.id}/media`) + assertCondition(job.output?.videoStorageKey && media.videoUrl, 'Video output was not bound to the current shot version') + const bytes = await downloadBytes(fetchImpl, media.videoUrl, options.requestTimeoutMs, 'video/') + assertCondition(bytes.length > 1000, 'Generated video output is unexpectedly small') + return { job, media, bytes } + }, (value) => ({ jobId: value.job.id, model: value.job.providerModel, durationSeconds: options.aiVideoSeconds, byteSize: value.bytes.length })) + + const lipsync = await step('ai-lipsync', 'Replicate lip-sync generation and media continuity', async () => { + const job = await runAiJob(projectId, aiSetup.episode.id, 'LIPSYNC_GENERATE', { + shotId: storyboard.shot.id, + provider: 'replicate', + params: options.aiLipsyncParams, + }) + const media = await api.request(`/shots/${storyboard.shot.id}/media`) + assertCondition(job.output?.videoStorageKey && media.videoUrl && media.audioUrl, 'Lip-sync output did not preserve video and audio continuity') + const [video, audio] = await Promise.all([ + downloadBytes(fetchImpl, media.videoUrl, options.requestTimeoutMs, 'video/'), + downloadBytes(fetchImpl, media.audioUrl, options.requestTimeoutMs, 'audio/'), + ]) + assertCondition(video.length > 1000 && audio.length > 500, 'Lip-sync media outputs are unexpectedly small') + return { job, media, video, audio } + }, (value) => ({ jobId: value.job.id, model: value.job.providerModel, videoBytes: value.video.length, audioBytes: value.audio.length })) + report.aiVerification.artifacts.lipsyncShotVersionId = lipsync.media.versionId + + const aiRender = await step('ai-render', 'FFmpeg render from live AI media', async () => { + const queued = await api.request(`/episodes/${aiSetup.episode.id}/renders`, { + method: 'POST', + json: { + idempotencyKey: `smoke-ai-render-${runId}`, + settings: { width: 640, height: 360, fps: 24, quality: 'draft', burnSubtitles: false, normalizeAudio: false, musicVolume: 0, subtitleStyle: { fontSize: 20, textColor: '#FFFFFF', outlineColor: '#000000', outlineWidth: 2, bottomMargin: 24, bold: true } }, + }, + }) + const job = await waitForJob((jobId) => api.request(`/jobs/${jobId}`), queued.job.id, { timeoutMs: options.timeoutMs, sleep }) + const render = await api.request(`/renders/${queued.render.id}`) + assertCondition(job.status === 'SUCCEEDED' && render.status === 'REVIEW', 'AI media render did not finish in review state') + assertCondition(render.sourceShotCount === 1 && render.downloadUrl, 'AI media render source manifest is invalid') + const video = await downloadBytes(fetchImpl, render.downloadUrl, options.requestTimeoutMs, 'video/mp4') + assertCondition(video.length > 1000, 'AI media render is unexpectedly small') + return { job, render, video } + }, (value) => ({ jobId: value.job.id, renderId: value.render.id, sourceShotCount: value.render.sourceShotCount, byteSize: value.video.length })) + report.aiVerification.artifacts.renderId = aiRender.render.id + report.aiVerification.artifacts.videoSha256 = sha256(aiRender.video) + + await step('ai-usage', 'Live AI usage-ledger reconciliation', async () => { + const billingAfter = await api.request(`/workspaces/${workspace.id}/billing/summary`) + const providerJobIds = new Set(report.aiVerification.jobs.map((job) => job.id)) + const billedJobIds = new Set((billingAfter.recent ?? []).filter((entry) => providerJobIds.has(entry.jobId)).map((entry) => entry.jobId)) + const missingJobIds = [...providerJobIds].filter((jobId) => !billedJobIds.has(jobId)) + assertCondition(missingJobIds.length === 0, `Usage ledger is missing ${missingJobIds.length} live AI jobs`) + const creditsUsed = Number(billingAfter.usedCredits) - Number(billingReadModel.usedCredits) + assertCondition(creditsUsed > 0, 'Live AI provider calls did not increase recorded usage') + report.aiVerification.creditsUsed = creditsUsed + return { jobs: providerJobIds.size, ledgerJobs: billedJobIds.size, creditsUsed } + }, (value) => value) + } + } catch (error) { + primaryError = error + } finally { + if (projectId && !options.keepProject) { + try { + await step('cleanup', 'Archive smoke-test project', async () => { + const archived = await api.request(`/projects/${projectId}`, { method: 'DELETE' }) + assertCondition(archived.status === 'ARCHIVED', 'Smoke project was not archived') + report.projectArchived = true + return archived + }, (value) => ({ projectId: value.id, status: value.status })) + } catch (cleanupError) { + if (!primaryError) primaryError = cleanupError + } + } + if (loggedIn) { + try { + await step('logout', 'Revoke smoke-account refresh session', async () => { + await api.request('/auth/logout', { method: 'POST' }) + const sessions = await api.request('/auth/sessions') + assertCondition(!sessions.some((candidate) => candidate.id === smokeSessionId), 'Smoke refresh session remains active after logout') + api.clearSession() + return { sessionId: smokeSessionId, revoked: true } + }, (value) => value) + } catch (logoutError) { + if (!primaryError) primaryError = logoutError + } + } + } + + report.status = primaryError ? 'failed' : 'passed' + report.completedAt = new Date(now()).toISOString() + report.durationMs = Math.max(0, now() - startedAt) + if (options.keepProject && projectId) report.projectArchived = false + if (primaryError) { + report.error = safeError(primaryError) + throw new SmokeTestError(report.error, { cause: primaryError, report }) + } + return report +} + +export function usage() { + return `FrameFlow production smoke test + +Usage: + FRAMEFLOW_SMOKE_BASE_URL=https://studio.example.com \\ + FRAMEFLOW_SMOKE_EMAIL=smoke@example.com \\ + FRAMEFLOW_SMOKE_PASSWORD='...' \\ + npm run smoke:production -- [options] + +Options: + --base-url URL Application origin or /api/v1 URL + --email EMAIL Dedicated verified smoke-account email + --workspace-id UUID Required when the account has multiple workspaces + --image PATH JPEG, PNG, or WebP render source + --timeout-seconds N Per-job timeout from 30 to 900 (default: 180) + --include-ai Run live, billable OpenAI and Replicate validation + --ai-video-seconds N Live AI video duration from 1 to 30 (default: 5) + --keep-project Keep the generated smoke project instead of archiving it + --allow-http Allow HTTP only for localhost development + --json Print the complete report as JSON + --help Show this help + +The password is accepted only through FRAMEFLOW_SMOKE_PASSWORD so it is not exposed in the process list. +Default mode never invokes AI provider jobs; configuration-only readiness is included in the report. + +--include-ai starts real provider jobs that can incur charges. It is accepted only when +FRAMEFLOW_SMOKE_BILLABLE_AI_ACK=I_ACCEPT_BILLABLE_AI_CHARGES is also set, all seven AI +workflows are configured, and the workspace has at least 700 remaining credits. Provider +jobs use maxAttempts=1. Optional model-specific JSON objects can be supplied through +FRAMEFLOW_SMOKE_VIDEO_PARAMS_JSON and FRAMEFLOW_SMOKE_LIPSYNC_PARAMS_JSON.` +} + +async function main() { + let options + try { + options = parseSmokeOptions() + if (options.help) { + console.log(usage()) + return + } + const report = await runProductionSmoke(options) + if (options.json) console.log(JSON.stringify(report, null, 2)) + else console.log(`Production smoke test passed in ${report.durationMs}ms. Project ${report.projectId}${report.projectArchived ? ' was archived' : ' was retained'}.`) + } catch (error) { + const report = error instanceof SmokeTestError ? error.report : null + if (options?.json && report) console.error(JSON.stringify(report, null, 2)) + else console.error(`Production smoke test failed: ${safeError(error)}`) + process.exitCode = 1 + } +} + +if (process.argv[1] && resolve(process.argv[1]) === scriptPath) await main() diff --git a/scripts/stripe-smoke.mjs b/scripts/stripe-smoke.mjs new file mode 100755 index 0000000..f8ce38f --- /dev/null +++ b/scripts/stripe-smoke.mjs @@ -0,0 +1,305 @@ +#!/usr/bin/env node + +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import Stripe from 'stripe' + +const scriptPath = fileURLToPath(import.meta.url) +export const requiredStripeWebhookEvents = [ + 'checkout.session.completed', + 'customer.subscription.created', + 'customer.subscription.updated', + 'customer.subscription.deleted', +] + +export class StripeSmokeError extends Error { + constructor(message, options = {}) { + super(message, options) + this.name = 'StripeSmokeError' + } +} + +function required(value, name) { + if (typeof value !== 'string' || value.trim() === '') throw new StripeSmokeError(`${name} is required`) + return value.trim() +} + +function integerValue(value, name, minimum, maximum) { + const parsed = Number(value) + if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) { + throw new StripeSmokeError(`${name} must be an integer from ${minimum} to ${maximum}`) + } + return parsed +} + +function booleanValue(value) { + return ['1', 'true', 'yes', 'on'].includes(String(value ?? '').trim().toLowerCase()) +} + +export function resolveStripeAppOrigin(value, options = {}) { + let url + try { + url = new URL(required(value, 'FRAMEFLOW_STRIPE_APP_ORIGIN')) + } catch (error) { + if (error instanceof StripeSmokeError) throw error + throw new StripeSmokeError('FRAMEFLOW_STRIPE_APP_ORIGIN must be a valid URL') + } + if (url.username || url.password || url.search || url.hash || url.pathname !== '/') { + throw new StripeSmokeError('Stripe app origin must be a bare origin without credentials, path, query, or fragment') + } + if (!['http:', 'https:'].includes(url.protocol)) throw new StripeSmokeError('Stripe app origin must use HTTP or HTTPS') + const localHostnames = new Set(['localhost', '127.0.0.1', '::1', '[::1]']) + if (url.protocol === 'http:' && (!options.allowHttp || !localHostnames.has(url.hostname))) { + throw new StripeSmokeError('HTTPS is required; HTTP can only be enabled explicitly for localhost') + } + return url.origin +} + +export function usage() { + return `Usage: npm run smoke:stripe -- [options] + +Performs read-only Stripe account, recurring Price, Product, Customer Portal, +and webhook-endpoint configuration checks. It never creates a customer, +Checkout Session, Portal Session, charge, subscription, or webhook event. + +Required environment: + STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET + STRIPE_PRO_PRICE_ID + STRIPE_STUDIO_PRICE_ID + FRAMEFLOW_STRIPE_APP_ORIGIN (falls back to API_PUBLIC_ORIGIN or WEB_ORIGIN) + +Optional environment: + STRIPE_PORTAL_CONFIGURATION_ID + FRAMEFLOW_STRIPE_SMOKE_TIMEOUT_SECONDS=30 + +Options: + --app-origin + --timeout-seconds <10-120> + --allow-http Loopback development only + --require-live Reject test keys and test-mode Stripe resources + --json + --help + +The signing secret is never sent or printed. Stripe does not expose webhook +signing secrets through its API, so a passing report proves endpoint/event +configuration but not that STRIPE_WEBHOOK_SECRET matches that endpoint. +` +} + +export function parseStripeSmokeOptions(argv = process.argv.slice(2), environment = process.env) { + const values = {} + const flags = new Set() + const valueOptions = new Set(['--app-origin', '--timeout-seconds']) + const flagOptions = new Set(['--allow-http', '--require-live', '--json', '--help']) + for (let index = 0; index < argv.length; index += 1) { + const argument = argv[index] + if (valueOptions.has(argument)) { + const value = argv[index + 1] + if (!value || value.startsWith('--')) throw new StripeSmokeError(`${argument} requires a value`) + values[argument] = value + index += 1 + } else if (flagOptions.has(argument)) { + flags.add(argument) + } else { + throw new StripeSmokeError(`Unknown option: ${argument}`) + } + } + if (flags.has('--help')) return { help: true } + + const secretKey = required(environment.STRIPE_SECRET_KEY, 'STRIPE_SECRET_KEY') + const keyMatch = /^(?:sk|rk)_(test|live)_/.exec(secretKey) + if (!keyMatch) throw new StripeSmokeError('STRIPE_SECRET_KEY must be a Stripe secret or restricted key') + const mode = keyMatch[1] + const requireLive = flags.has('--require-live') || booleanValue(environment.FRAMEFLOW_STRIPE_REQUIRE_LIVE) + if (requireLive && mode !== 'live') throw new StripeSmokeError('--require-live requires a live-mode Stripe key') + + const webhookSecret = required(environment.STRIPE_WEBHOOK_SECRET, 'STRIPE_WEBHOOK_SECRET') + if (!webhookSecret.startsWith('whsec_')) throw new StripeSmokeError('STRIPE_WEBHOOK_SECRET must use the Stripe whsec_ format') + const proPriceId = required(environment.STRIPE_PRO_PRICE_ID, 'STRIPE_PRO_PRICE_ID') + const studioPriceId = required(environment.STRIPE_STUDIO_PRICE_ID, 'STRIPE_STUDIO_PRICE_ID') + if (!proPriceId.startsWith('price_') || !studioPriceId.startsWith('price_')) { + throw new StripeSmokeError('Stripe plan IDs must use the price_ format') + } + if (proPriceId === studioPriceId) throw new StripeSmokeError('PRO and STUDIO must use different Stripe Price IDs') + const portalConfigurationId = environment.STRIPE_PORTAL_CONFIGURATION_ID?.trim() || null + if (portalConfigurationId && !portalConfigurationId.startsWith('bpc_')) { + throw new StripeSmokeError('STRIPE_PORTAL_CONFIGURATION_ID must use the bpc_ format') + } + + const allowHttp = flags.has('--allow-http') || booleanValue(environment.FRAMEFLOW_STRIPE_ALLOW_HTTP) + const originValue = values['--app-origin'] + ?? environment.FRAMEFLOW_STRIPE_APP_ORIGIN + ?? environment.API_PUBLIC_ORIGIN + ?? environment.WEB_ORIGIN?.split(',')[0]?.trim() + const timeoutSeconds = integerValue(values['--timeout-seconds'] ?? environment.FRAMEFLOW_STRIPE_SMOKE_TIMEOUT_SECONDS ?? '30', 'timeout-seconds', 10, 120) + return { + secretKey, + webhookSecretConfigured: true, + proPriceId, + studioPriceId, + portalConfigurationId, + appOrigin: resolveStripeAppOrigin(originValue, { allowHttp }), + mode, + requireLive, + timeoutMs: timeoutSeconds * 1000, + json: flags.has('--json'), + } +} + +async function listStripeCollection(fetchPage, parameters = {}) { + const rows = [] + let startingAfter + for (let page = 0; page < 20; page += 1) { + const response = await fetchPage({ ...parameters, limit: 100, ...(startingAfter ? { starting_after: startingAfter } : {}) }) + if (!response || !Array.isArray(response.data)) throw new StripeSmokeError('Stripe returned an invalid list response') + rows.push(...response.data) + if (!response.has_more) return rows + startingAfter = response.data.at(-1)?.id + if (!startingAfter) throw new StripeSmokeError('Stripe pagination returned no continuation ID') + } + throw new StripeSmokeError('Stripe list exceeded the 2,000-resource verification limit') +} + +function assertMode(resource, mode, label) { + if (typeof resource?.livemode !== 'boolean') throw new StripeSmokeError(`${label} did not report livemode`) + if (resource.livemode !== (mode === 'live')) throw new StripeSmokeError(`${label} does not match the Stripe key mode`) +} + +async function verifyPrice(client, priceId, plan, mode) { + const price = await client.prices.retrieve(priceId, { expand: ['product'] }) + if (price?.object !== 'price' || price.id !== priceId) throw new StripeSmokeError(`${plan} Stripe Price could not be retrieved`) + assertMode(price, mode, `${plan} Price`) + if (price.active !== true) throw new StripeSmokeError(`${plan} Stripe Price is not active`) + if (price.type !== 'recurring' || !price.recurring) throw new StripeSmokeError(`${plan} Stripe Price must be recurring`) + if (price.recurring.usage_type !== 'licensed') throw new StripeSmokeError(`${plan} Stripe Price must use licensed recurring usage`) + const product = price.product + if (!product || typeof product === 'string' || product.deleted || product.object !== 'product') { + throw new StripeSmokeError(`${plan} Stripe Product was not expanded or has been deleted`) + } + if (product.active !== true) throw new StripeSmokeError(`${plan} Stripe Product is not active`) + assertMode(product, mode, `${plan} Product`) + return { + plan, + priceId: price.id, + productId: product.id, + productName: product.name, + currency: price.currency, + unitAmount: price.unit_amount, + billingScheme: price.billing_scheme, + interval: price.recurring.interval, + intervalCount: price.recurring.interval_count, + } +} + +async function verifyPortal(client, configurationId, mode) { + let configuration + if (configurationId) { + configuration = await client.billingPortal.configurations.retrieve(configurationId) + } else { + const configurations = await listStripeCollection( + (parameters) => client.billingPortal.configurations.list(parameters), + { active: true }, + ) + configuration = configurations.find((candidate) => candidate.is_default === true) + } + if (!configuration || configuration.object !== 'billing_portal.configuration') { + throw new StripeSmokeError('No active default Stripe Customer Portal configuration was found') + } + if (configuration.active !== true) throw new StripeSmokeError('Stripe Customer Portal configuration is not active') + assertMode(configuration, mode, 'Customer Portal configuration') + return { + id: configuration.id, + isDefault: configuration.is_default === true, + active: true, + } +} + +async function verifyWebhook(client, appOrigin, mode) { + const expectedUrl = `${appOrigin}/api/v1/billing/webhooks/stripe` + const endpoints = await listStripeCollection((parameters) => client.webhookEndpoints.list(parameters)) + const endpoint = endpoints.find((candidate) => candidate.url === expectedUrl && candidate.status === 'enabled') + if (!endpoint) throw new StripeSmokeError(`No enabled Stripe webhook endpoint matches ${expectedUrl}`) + assertMode(endpoint, mode, 'Webhook endpoint') + const enabledEvents = new Set(endpoint.enabled_events ?? []) + const missingEvents = enabledEvents.has('*') + ? [] + : requiredStripeWebhookEvents.filter((event) => !enabledEvents.has(event)) + if (missingEvents.length > 0) { + throw new StripeSmokeError(`Stripe webhook endpoint is missing events: ${missingEvents.join(', ')}`) + } + return { + id: endpoint.id, + url: endpoint.url, + status: endpoint.status, + requiredEvents: requiredStripeWebhookEvents, + } +} + +export async function runStripeSmoke(options, dependencies = {}) { + const client = dependencies.client ?? new Stripe(options.secretKey, { + maxNetworkRetries: 1, + timeout: options.timeoutMs, + }) + const account = await client.accounts.retrieve() + if (!account || account.object !== 'account' || typeof account.id !== 'string') { + throw new StripeSmokeError('Stripe account could not be retrieved') + } + if (options.requireLive && account.charges_enabled !== true) { + throw new StripeSmokeError('Stripe live charges are not enabled for this account') + } + if (options.requireLive && account.details_submitted !== true) { + throw new StripeSmokeError('Stripe account onboarding details are incomplete') + } + + const [pro, studio, portal, webhook] = await Promise.all([ + verifyPrice(client, options.proPriceId, 'PRO', options.mode), + verifyPrice(client, options.studioPriceId, 'STUDIO', options.mode), + verifyPortal(client, options.portalConfigurationId, options.mode), + verifyWebhook(client, options.appOrigin, options.mode), + ]) + return { + status: 'passed', + mode: options.mode, + account: { + id: account.id, + country: account.country ?? null, + defaultCurrency: account.default_currency ?? null, + chargesEnabled: account.charges_enabled === true, + payoutsEnabled: account.payouts_enabled === true, + detailsSubmitted: account.details_submitted === true, + }, + prices: { PRO: pro, STUDIO: studio }, + portal, + webhook, + webhookSigningSecretConfigured: options.webhookSecretConfigured, + webhookSigningSecretMatchedToEndpoint: false, + sideEffectsCreated: false, + } +} + +function safeError(error) { + const message = error instanceof Error ? error.message : String(error) + return message.replace(/(?:sk|rk)_(?:test|live)_[a-zA-Z0-9]+|whsec_[a-zA-Z0-9]+/g, '[redacted]').slice(0, 1000) +} + +async function main() { + const options = parseStripeSmokeOptions() + if (options.help) { + process.stdout.write(usage()) + return + } + const report = await runStripeSmoke(options) + if (options.json) { + process.stdout.write(`${JSON.stringify(report, null, 2)}\n`) + return + } + process.stdout.write(`Stripe read-only smoke passed in ${report.mode} mode.\nAccount: ${report.account.id}\nWebhook: ${report.webhook.url}\nNo Stripe resources were created. Run a signed webhook acceptance event before launch.\n`) +} + +if (process.argv[1] && resolve(process.argv[1]) === scriptPath) { + main().catch((error) => { + process.stderr.write(`Stripe smoke failed: ${safeError(error)}\n`) + process.exitCode = 1 + }) +} diff --git a/scripts/verify-backup.sh b/scripts/verify-backup.sh new file mode 100755 index 0000000..9051406 --- /dev/null +++ b/scripts/verify-backup.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +usage() { + echo "Usage: $0 " >&2 + exit 2 +} + +fail() { + echo "Backup verification failed: $1" >&2 + exit 1 +} + +[[ $# -eq 1 ]] || usage +[[ -d "$1" ]] || fail "directory not found: $1" +[[ ! -L "$1" ]] || fail "backup directory must not be a symbolic link" + +backup_dir="$(cd "$1" && pwd -P)" +required_files=(postgres.dump redis-data.tar.gz minio-data.tar.gz manifest.txt SHA256SUMS) + +for filename in "${required_files[@]}"; do + path="${backup_dir}/${filename}" + [[ -f "${path}" ]] || fail "missing ${filename}" + [[ ! -L "${path}" ]] || fail "${filename} must not be a symbolic link" + [[ -s "${path}" ]] || fail "${filename} is empty" +done + +created_at="$(sed -n 's/^created_at=//p' "${backup_dir}/manifest.txt")" +compose_project="$(sed -n 's/^compose_project=//p' "${backup_dir}/manifest.txt")" +[[ "${created_at}" =~ ^[0-9]{8}T[0-9]{6}Z$ ]] || fail "manifest has an invalid created_at value" +[[ "${compose_project}" =~ ^[a-zA-Z0-9][a-zA-Z0-9_.-]*$ ]] || fail "manifest has an invalid compose_project value" + +postgres_seen=0 +redis_seen=0 +minio_seen=0 +checksum_rows=0 +while read -r digest filename extra; do + [[ -z "${extra:-}" ]] || fail "SHA256SUMS contains an invalid row" + [[ "${digest}" =~ ^[[:xdigit:]]{64}$ ]] || fail "SHA256SUMS contains an invalid digest" + filename="${filename#\*}" + case "${filename}" in + postgres.dump) postgres_seen=$((postgres_seen + 1)) ;; + redis-data.tar.gz) redis_seen=$((redis_seen + 1)) ;; + minio-data.tar.gz) minio_seen=$((minio_seen + 1)) ;; + *) fail "SHA256SUMS references an unexpected file: ${filename}" ;; + esac + checksum_rows=$((checksum_rows + 1)) +done < "${backup_dir}/SHA256SUMS" + +[[ ${checksum_rows} -eq 3 && ${postgres_seen} -eq 1 && ${redis_seen} -eq 1 && ${minio_seen} -eq 1 ]] \ + || fail "SHA256SUMS must reference each data artifact exactly once" + +if command -v sha256sum >/dev/null 2>&1; then + (cd "${backup_dir}" && sha256sum -c SHA256SUMS) >/dev/null \ + || fail "artifact checksum mismatch" +else + (cd "${backup_dir}" && shasum -a 256 -c SHA256SUMS) >/dev/null \ + || fail "artifact checksum mismatch" +fi + +postgres_magic="$(LC_ALL=C head -c 5 "${backup_dir}/postgres.dump")" +[[ "${postgres_magic}" == "PGDMP" ]] || fail "PostgreSQL dump does not use the required custom format" + +verify_archive_paths() { + local archive_name="$1" + local listing_file + local entry + local normalized + listing_file="$(mktemp "${TMPDIR:-/tmp}/frameflow-archive-list.XXXXXX")" + if ! tar -tzf "${backup_dir}/${archive_name}" > "${listing_file}"; then + rm -f "${listing_file}" + fail "${archive_name} is not a readable gzip tar archive" + fi + if [[ ! -s "${listing_file}" ]]; then + rm -f "${listing_file}" + fail "${archive_name} contains no entries" + fi + while IFS= read -r entry; do + [[ "${entry}" != /* ]] || { + rm -f "${listing_file}" + fail "${archive_name} contains an absolute path" + } + normalized="${entry#./}" + case "/${normalized}/" in + *"/../"*) + rm -f "${listing_file}" + fail "${archive_name} contains a parent-directory path" + ;; + esac + done < "${listing_file}" + rm -f "${listing_file}" +} + +verify_archive_paths redis-data.tar.gz +verify_archive_paths minio-data.tar.gz + +echo "Backup verification passed: ${backup_dir}" +echo "Source Compose project: ${compose_project}; created at: ${created_at}" diff --git a/server/drizzle.config.ts b/server/drizzle.config.ts new file mode 100644 index 0000000..aa7ee13 --- /dev/null +++ b/server/drizzle.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'drizzle-kit' + +export default defineConfig({ + dialect: 'postgresql', + schema: './src/db/schema.ts', + out: './drizzle', + dbCredentials: { + url: process.env.DATABASE_URL ?? 'postgresql://frameflow:frameflow@127.0.0.1:54329/frameflow', + }, + strict: true, + verbose: true, +}) diff --git a/server/drizzle/0000_last_spectrum.sql b/server/drizzle/0000_last_spectrum.sql new file mode 100644 index 0000000..35d0e77 --- /dev/null +++ b/server/drizzle/0000_last_spectrum.sql @@ -0,0 +1,356 @@ +CREATE TYPE "public"."asset_status" AS ENUM('DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'ARCHIVED');--> statement-breakpoint +CREATE TYPE "public"."asset_type" AS ENUM('CHARACTER', 'SCENE', 'PROP', 'VOICE', 'MUSIC');--> statement-breakpoint +CREATE TYPE "public"."delivery_status" AS ENUM('DRAFT', 'QUEUED', 'PUBLISHING', 'PUBLISHED', 'FAILED');--> statement-breakpoint +CREATE TYPE "public"."episode_status" AS ENUM('OUTLINE', 'SCRIPTING', 'STORYBOARDING', 'PRODUCTION', 'REVIEW', 'PUBLISHED');--> statement-breakpoint +CREATE TYPE "public"."job_status" AS ENUM('QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED');--> statement-breakpoint +CREATE TYPE "public"."job_type" AS ENUM('SCRIPT_GENERATE', 'ASSET_GENERATE', 'TTS_GENERATE', 'VIDEO_GENERATE', 'LIPSYNC_GENERATE', 'EPISODE_RENDER', 'DELIVERY_PUBLISH');--> statement-breakpoint +CREATE TYPE "public"."membership_role" AS ENUM('OWNER', 'ADMIN', 'EDITOR', 'REVIEWER', 'VIEWER');--> statement-breakpoint +CREATE TYPE "public"."project_status" AS ENUM('DRAFT', 'ACTIVE', 'ARCHIVED');--> statement-breakpoint +CREATE TYPE "public"."render_status" AS ENUM('QUEUED', 'RENDERING', 'REVIEW', 'APPROVED', 'FAILED');--> statement-breakpoint +CREATE TYPE "public"."review_status" AS ENUM('OPEN', 'APPROVED', 'CHANGES_REQUESTED', 'CANCELLED');--> statement-breakpoint +CREATE TYPE "public"."review_target_type" AS ENUM('SCRIPT_VERSION', 'ASSET_VERSION', 'SHOT_VERSION', 'RENDER');--> statement-breakpoint +CREATE TYPE "public"."shot_status" AS ENUM('DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'RENDERED');--> statement-breakpoint +CREATE TYPE "public"."usage_kind" AS ENUM('TEXT_INPUT_TOKEN', 'TEXT_OUTPUT_TOKEN', 'IMAGE', 'AUDIO_SECOND', 'VIDEO_SECOND', 'RENDER_SECOND', 'STORAGE_BYTE_MONTH');--> statement-breakpoint +CREATE TABLE "asset_versions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "asset_id" uuid NOT NULL, + "version" integer NOT NULL, + "storage_key" text, + "thumbnail_key" text, + "mime_type" varchar(120), + "byte_size" integer, + "width" integer, + "height" integer, + "duration_ms" integer, + "prompt" text DEFAULT '' NOT NULL, + "negative_prompt" text DEFAULT '' NOT NULL, + "provider" varchar(80), + "provider_model" varchar(160), + "seed" varchar(80), + "generation_params" jsonb DEFAULT '{}'::jsonb NOT NULL, + "is_current" boolean DEFAULT false NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "assets" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "project_id" uuid NOT NULL, + "type" "asset_type" NOT NULL, + "name" varchar(180) NOT NULL, + "description" text DEFAULT '' NOT NULL, + "status" "asset_status" DEFAULT 'DRAFT' NOT NULL, + "tags" jsonb DEFAULT '[]'::jsonb NOT NULL, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "audit_logs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid, + "actor_id" uuid, + "action" varchar(120) NOT NULL, + "resource_type" varchar(80) NOT NULL, + "resource_id" uuid, + "ip_address" varchar(64), + "user_agent" text, + "before" jsonb, + "after" jsonb, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "deliveries" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "render_id" uuid NOT NULL, + "platform" varchar(80) NOT NULL, + "status" "delivery_status" DEFAULT 'DRAFT' NOT NULL, + "destination" jsonb DEFAULT '{}'::jsonb NOT NULL, + "external_id" varchar(255), + "published_url" text, + "scheduled_at" timestamp with time zone, + "published_at" timestamp with time zone, + "created_by_id" uuid NOT NULL, + "error_message" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "episodes" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "project_id" uuid NOT NULL, + "episode_number" integer NOT NULL, + "title" varchar(200) NOT NULL, + "synopsis" text DEFAULT '' NOT NULL, + "target_duration_seconds" integer DEFAULT 180 NOT NULL, + "status" "episode_status" DEFAULT 'OUTLINE' NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "generation_jobs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "project_id" uuid, + "episode_id" uuid, + "created_by_id" uuid NOT NULL, + "type" "job_type" NOT NULL, + "status" "job_status" DEFAULT 'QUEUED' NOT NULL, + "progress" integer DEFAULT 0 NOT NULL, + "provider" varchar(80), + "provider_model" varchar(160), + "external_id" varchar(255), + "idempotency_key" varchar(180) NOT NULL, + "input" jsonb NOT NULL, + "output" jsonb, + "error_code" varchar(100), + "error_message" text, + "attempts" integer DEFAULT 0 NOT NULL, + "max_attempts" integer DEFAULT 3 NOT NULL, + "started_at" timestamp with time zone, + "completed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "memberships" ( + "workspace_id" uuid NOT NULL, + "user_id" uuid NOT NULL, + "role" "membership_role" DEFAULT 'VIEWER' NOT NULL, + "invited_by_id" uuid, + "joined_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "memberships_workspace_id_user_id_pk" PRIMARY KEY("workspace_id","user_id") +); +--> statement-breakpoint +CREATE TABLE "projects" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "created_by_id" uuid NOT NULL, + "name" varchar(180) NOT NULL, + "slug" varchar(100) NOT NULL, + "logline" text DEFAULT '' NOT NULL, + "genre" varchar(80) DEFAULT '都市悬疑' NOT NULL, + "visual_bible" jsonb DEFAULT '{}'::jsonb NOT NULL, + "status" "project_status" DEFAULT 'DRAFT' NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "refresh_tokens" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "token_hash" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "revoked_at" timestamp with time zone, + "replaced_by_id" uuid, + "user_agent" text, + "ip_address" varchar(64), + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "renders" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "episode_id" uuid NOT NULL, + "version" integer NOT NULL, + "status" "render_status" DEFAULT 'QUEUED' NOT NULL, + "storage_key" text, + "thumbnail_key" text, + "mime_type" varchar(120) DEFAULT 'video/mp4' NOT NULL, + "byte_size" integer, + "duration_ms" integer, + "width" integer NOT NULL, + "height" integer NOT NULL, + "fps" integer DEFAULT 24 NOT NULL, + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, + "quality_report" jsonb, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "review_comments" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "review_request_id" uuid NOT NULL, + "author_id" uuid NOT NULL, + "body" text NOT NULL, + "timecode_ms" integer, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "review_requests" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "target_type" "review_target_type" NOT NULL, + "target_id" uuid NOT NULL, + "status" "review_status" DEFAULT 'OPEN' NOT NULL, + "requested_by_id" uuid NOT NULL, + "assigned_to_id" uuid, + "resolved_by_id" uuid, + "summary" text DEFAULT '' NOT NULL, + "resolved_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "script_versions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "episode_id" uuid NOT NULL, + "version" integer NOT NULL, + "title" varchar(200) NOT NULL, + "content" jsonb NOT NULL, + "plain_text" text DEFAULT '' NOT NULL, + "change_summary" text DEFAULT '' NOT NULL, + "is_current" boolean DEFAULT false NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "shot_versions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "shot_id" uuid NOT NULL, + "version" integer NOT NULL, + "image_asset_version_id" uuid, + "video_storage_key" text, + "audio_storage_key" text, + "subtitle_text" text DEFAULT '' NOT NULL, + "generation_params" jsonb DEFAULT '{}'::jsonb NOT NULL, + "is_current" boolean DEFAULT false NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "shots" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "episode_id" uuid NOT NULL, + "shot_number" integer NOT NULL, + "scene_number" integer NOT NULL, + "title" varchar(180) NOT NULL, + "description" text DEFAULT '' NOT NULL, + "shot_type" varchar(50) DEFAULT '中景' NOT NULL, + "camera_motion" varchar(50) DEFAULT '静止' NOT NULL, + "duration_ms" integer DEFAULT 3000 NOT NULL, + "status" "shot_status" DEFAULT 'DRAFT' NOT NULL, + "character_asset_ids" jsonb DEFAULT '[]'::jsonb NOT NULL, + "scene_asset_id" uuid, + "sort_order" integer NOT NULL, + "created_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "usage_ledger" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "user_id" uuid, + "job_id" uuid, + "kind" "usage_kind" NOT NULL, + "quantity" numeric(20, 4) NOT NULL, + "credits" numeric(20, 4) NOT NULL, + "provider_cost_usd" numeric(20, 6), + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "occurred_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "users" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "email" varchar(320) NOT NULL, + "display_name" varchar(120) NOT NULL, + "password_hash" text NOT NULL, + "avatar_key" text, + "email_verified_at" timestamp with time zone, + "disabled_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "workspaces" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" varchar(160) NOT NULL, + "slug" varchar(80) NOT NULL, + "owner_id" uuid NOT NULL, + "plan" varchar(32) DEFAULT 'PRO' NOT NULL, + "monthly_credit_limit" integer DEFAULT 10000 NOT NULL, + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "asset_versions" ADD CONSTRAINT "asset_versions_asset_id_assets_id_fk" FOREIGN KEY ("asset_id") REFERENCES "public"."assets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "asset_versions" ADD CONSTRAINT "asset_versions_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "assets" ADD CONSTRAINT "assets_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "assets" ADD CONSTRAINT "assets_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_actor_id_users_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_render_id_renders_id_fk" FOREIGN KEY ("render_id") REFERENCES "public"."renders"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "episodes" ADD CONSTRAINT "episodes_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "episodes" ADD CONSTRAINT "episodes_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD CONSTRAINT "generation_jobs_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD CONSTRAINT "generation_jobs_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD CONSTRAINT "generation_jobs_episode_id_episodes_id_fk" FOREIGN KEY ("episode_id") REFERENCES "public"."episodes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD CONSTRAINT "generation_jobs_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "memberships" ADD CONSTRAINT "memberships_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "memberships" ADD CONSTRAINT "memberships_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "memberships" ADD CONSTRAINT "memberships_invited_by_id_users_id_fk" FOREIGN KEY ("invited_by_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "projects" ADD CONSTRAINT "projects_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "projects" ADD CONSTRAINT "projects_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "refresh_tokens" ADD CONSTRAINT "refresh_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "renders" ADD CONSTRAINT "renders_episode_id_episodes_id_fk" FOREIGN KEY ("episode_id") REFERENCES "public"."episodes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "renders" ADD CONSTRAINT "renders_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_comments" ADD CONSTRAINT "review_comments_review_request_id_review_requests_id_fk" FOREIGN KEY ("review_request_id") REFERENCES "public"."review_requests"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_comments" ADD CONSTRAINT "review_comments_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_requests" ADD CONSTRAINT "review_requests_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_requests" ADD CONSTRAINT "review_requests_requested_by_id_users_id_fk" FOREIGN KEY ("requested_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_requests" ADD CONSTRAINT "review_requests_assigned_to_id_users_id_fk" FOREIGN KEY ("assigned_to_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "review_requests" ADD CONSTRAINT "review_requests_resolved_by_id_users_id_fk" FOREIGN KEY ("resolved_by_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "script_versions" ADD CONSTRAINT "script_versions_episode_id_episodes_id_fk" FOREIGN KEY ("episode_id") REFERENCES "public"."episodes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "script_versions" ADD CONSTRAINT "script_versions_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shot_versions" ADD CONSTRAINT "shot_versions_shot_id_shots_id_fk" FOREIGN KEY ("shot_id") REFERENCES "public"."shots"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shot_versions" ADD CONSTRAINT "shot_versions_image_asset_version_id_asset_versions_id_fk" FOREIGN KEY ("image_asset_version_id") REFERENCES "public"."asset_versions"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shot_versions" ADD CONSTRAINT "shot_versions_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shots" ADD CONSTRAINT "shots_episode_id_episodes_id_fk" FOREIGN KEY ("episode_id") REFERENCES "public"."episodes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shots" ADD CONSTRAINT "shots_scene_asset_id_assets_id_fk" FOREIGN KEY ("scene_asset_id") REFERENCES "public"."assets"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "shots" ADD CONSTRAINT "shots_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "usage_ledger" ADD CONSTRAINT "usage_ledger_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "usage_ledger" ADD CONSTRAINT "usage_ledger_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "usage_ledger" ADD CONSTRAINT "usage_ledger_job_id_generation_jobs_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."generation_jobs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "workspaces" ADD CONSTRAINT "workspaces_owner_id_users_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "asset_versions_asset_version_unique" ON "asset_versions" USING btree ("asset_id","version");--> statement-breakpoint +CREATE INDEX "asset_versions_current_idx" ON "asset_versions" USING btree ("asset_id","is_current");--> statement-breakpoint +CREATE INDEX "assets_project_type_idx" ON "assets" USING btree ("project_id","type");--> statement-breakpoint +CREATE INDEX "assets_project_status_idx" ON "assets" USING btree ("project_id","status");--> statement-breakpoint +CREATE INDEX "audit_logs_workspace_time_idx" ON "audit_logs" USING btree ("workspace_id","created_at");--> statement-breakpoint +CREATE INDEX "audit_logs_actor_idx" ON "audit_logs" USING btree ("actor_id");--> statement-breakpoint +CREATE INDEX "deliveries_render_idx" ON "deliveries" USING btree ("render_id");--> statement-breakpoint +CREATE INDEX "deliveries_status_idx" ON "deliveries" USING btree ("status");--> statement-breakpoint +CREATE UNIQUE INDEX "episodes_project_number_unique" ON "episodes" USING btree ("project_id","episode_number");--> statement-breakpoint +CREATE INDEX "episodes_project_idx" ON "episodes" USING btree ("project_id");--> statement-breakpoint +CREATE UNIQUE INDEX "generation_jobs_idempotency_unique" ON "generation_jobs" USING btree ("workspace_id","idempotency_key");--> statement-breakpoint +CREATE INDEX "generation_jobs_workspace_status_idx" ON "generation_jobs" USING btree ("workspace_id","status");--> statement-breakpoint +CREATE INDEX "generation_jobs_project_idx" ON "generation_jobs" USING btree ("project_id");--> statement-breakpoint +CREATE INDEX "memberships_user_idx" ON "memberships" USING btree ("user_id");--> statement-breakpoint +CREATE UNIQUE INDEX "projects_workspace_slug_unique" ON "projects" USING btree ("workspace_id","slug");--> statement-breakpoint +CREATE INDEX "projects_workspace_idx" ON "projects" USING btree ("workspace_id");--> statement-breakpoint +CREATE UNIQUE INDEX "refresh_tokens_hash_unique" ON "refresh_tokens" USING btree ("token_hash");--> statement-breakpoint +CREATE INDEX "refresh_tokens_user_idx" ON "refresh_tokens" USING btree ("user_id");--> statement-breakpoint +CREATE UNIQUE INDEX "renders_episode_version_unique" ON "renders" USING btree ("episode_id","version");--> statement-breakpoint +CREATE INDEX "renders_episode_status_idx" ON "renders" USING btree ("episode_id","status");--> statement-breakpoint +CREATE INDEX "review_comments_request_idx" ON "review_comments" USING btree ("review_request_id");--> statement-breakpoint +CREATE INDEX "review_requests_workspace_status_idx" ON "review_requests" USING btree ("workspace_id","status");--> statement-breakpoint +CREATE INDEX "review_requests_target_idx" ON "review_requests" USING btree ("target_type","target_id");--> statement-breakpoint +CREATE UNIQUE INDEX "script_versions_episode_version_unique" ON "script_versions" USING btree ("episode_id","version");--> statement-breakpoint +CREATE INDEX "script_versions_episode_current_idx" ON "script_versions" USING btree ("episode_id","is_current");--> statement-breakpoint +CREATE UNIQUE INDEX "shot_versions_shot_version_unique" ON "shot_versions" USING btree ("shot_id","version");--> statement-breakpoint +CREATE INDEX "shot_versions_current_idx" ON "shot_versions" USING btree ("shot_id","is_current");--> statement-breakpoint +CREATE UNIQUE INDEX "shots_episode_number_unique" ON "shots" USING btree ("episode_id","shot_number");--> statement-breakpoint +CREATE INDEX "shots_episode_sort_idx" ON "shots" USING btree ("episode_id","sort_order");--> statement-breakpoint +CREATE INDEX "usage_ledger_workspace_time_idx" ON "usage_ledger" USING btree ("workspace_id","occurred_at");--> statement-breakpoint +CREATE INDEX "usage_ledger_job_idx" ON "usage_ledger" USING btree ("job_id");--> statement-breakpoint +CREATE UNIQUE INDEX "users_email_unique" ON "users" USING btree ("email");--> statement-breakpoint +CREATE UNIQUE INDEX "workspaces_slug_unique" ON "workspaces" USING btree ("slug");--> statement-breakpoint +CREATE INDEX "workspaces_owner_idx" ON "workspaces" USING btree ("owner_id"); \ No newline at end of file diff --git a/server/drizzle/0001_perfect_gravity.sql b/server/drizzle/0001_perfect_gravity.sql new file mode 100644 index 0000000..0ec0b02 --- /dev/null +++ b/server/drizzle/0001_perfect_gravity.sql @@ -0,0 +1 @@ +ALTER TYPE "public"."job_type" ADD VALUE 'PIPELINE_HEALTHCHECK' BEFORE 'SCRIPT_GENERATE'; \ No newline at end of file diff --git a/server/drizzle/0002_yielding_spencer_smythe.sql b/server/drizzle/0002_yielding_spencer_smythe.sql new file mode 100644 index 0000000..d585dfe --- /dev/null +++ b/server/drizzle/0002_yielding_spencer_smythe.sql @@ -0,0 +1 @@ +ALTER TYPE "public"."asset_type" ADD VALUE 'SHOT'; \ No newline at end of file diff --git a/server/drizzle/0003_hard_norrin_radd.sql b/server/drizzle/0003_hard_norrin_radd.sql new file mode 100644 index 0000000..d311941 --- /dev/null +++ b/server/drizzle/0003_hard_norrin_radd.sql @@ -0,0 +1 @@ +ALTER TYPE "public"."job_type" ADD VALUE 'STORYBOARD_GENERATE' BEFORE 'ASSET_GENERATE'; \ No newline at end of file diff --git a/server/drizzle/0004_goofy_karnak.sql b/server/drizzle/0004_goofy_karnak.sql new file mode 100644 index 0000000..b15fd92 --- /dev/null +++ b/server/drizzle/0004_goofy_karnak.sql @@ -0,0 +1 @@ +ALTER TABLE "generation_jobs" ADD COLUMN "estimated_credits" numeric(20, 4) DEFAULT '0' NOT NULL; \ No newline at end of file diff --git a/server/drizzle/0005_brave_betty_ross.sql b/server/drizzle/0005_brave_betty_ross.sql new file mode 100644 index 0000000..ed7ddf5 --- /dev/null +++ b/server/drizzle/0005_brave_betty_ross.sql @@ -0,0 +1,21 @@ +CREATE TABLE "workspace_invitations" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "email" varchar(320) NOT NULL, + "role" "membership_role" DEFAULT 'VIEWER' NOT NULL, + "token_hash" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "accepted_at" timestamp with time zone, + "accepted_by_id" uuid, + "revoked_at" timestamp with time zone, + "invited_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "workspace_invitations" ADD CONSTRAINT "workspace_invitations_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "workspace_invitations" ADD CONSTRAINT "workspace_invitations_accepted_by_id_users_id_fk" FOREIGN KEY ("accepted_by_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "workspace_invitations" ADD CONSTRAINT "workspace_invitations_invited_by_id_users_id_fk" FOREIGN KEY ("invited_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "workspace_invitations_token_hash_unique" ON "workspace_invitations" USING btree ("token_hash");--> statement-breakpoint +CREATE INDEX "workspace_invitations_workspace_email_idx" ON "workspace_invitations" USING btree ("workspace_id","email");--> statement-breakpoint +CREATE INDEX "workspace_invitations_workspace_created_idx" ON "workspace_invitations" USING btree ("workspace_id","created_at"); \ No newline at end of file diff --git a/server/drizzle/0006_wooden_texas_twister.sql b/server/drizzle/0006_wooden_texas_twister.sql new file mode 100644 index 0000000..5d9b2db --- /dev/null +++ b/server/drizzle/0006_wooden_texas_twister.sql @@ -0,0 +1,24 @@ +CREATE TYPE "public"."production_run_status" AS ENUM('QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED');--> statement-breakpoint +CREATE TABLE "production_runs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "episode_id" uuid NOT NULL, + "render_id" uuid NOT NULL, + "status" "production_run_status" DEFAULT 'QUEUED' NOT NULL, + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, + "total_jobs" integer NOT NULL, + "created_by_id" uuid NOT NULL, + "started_at" timestamp with time zone, + "completed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD COLUMN "production_run_id" uuid;--> statement-breakpoint +ALTER TABLE "production_runs" ADD CONSTRAINT "production_runs_episode_id_episodes_id_fk" FOREIGN KEY ("episode_id") REFERENCES "public"."episodes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "production_runs" ADD CONSTRAINT "production_runs_render_id_renders_id_fk" FOREIGN KEY ("render_id") REFERENCES "public"."renders"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "production_runs" ADD CONSTRAINT "production_runs_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "production_runs_render_unique" ON "production_runs" USING btree ("render_id");--> statement-breakpoint +CREATE INDEX "production_runs_episode_status_idx" ON "production_runs" USING btree ("episode_id","status");--> statement-breakpoint +CREATE INDEX "production_runs_episode_created_idx" ON "production_runs" USING btree ("episode_id","created_at");--> statement-breakpoint +ALTER TABLE "generation_jobs" ADD CONSTRAINT "generation_jobs_production_run_id_production_runs_id_fk" FOREIGN KEY ("production_run_id") REFERENCES "public"."production_runs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "generation_jobs_production_run_idx" ON "generation_jobs" USING btree ("production_run_id"); \ No newline at end of file diff --git a/server/drizzle/0007_sudden_roland_deschain.sql b/server/drizzle/0007_sudden_roland_deschain.sql new file mode 100644 index 0000000..8adc300 --- /dev/null +++ b/server/drizzle/0007_sudden_roland_deschain.sql @@ -0,0 +1,15 @@ +CREATE TYPE "public"."account_token_type" AS ENUM('EMAIL_VERIFICATION', 'PASSWORD_RESET');--> statement-breakpoint +CREATE TABLE "account_action_tokens" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "type" "account_token_type" NOT NULL, + "token_hash" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "consumed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "account_action_tokens" ADD CONSTRAINT "account_action_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "account_action_tokens_hash_unique" ON "account_action_tokens" USING btree ("token_hash");--> statement-breakpoint +CREATE INDEX "account_action_tokens_user_type_idx" ON "account_action_tokens" USING btree ("user_id","type");--> statement-breakpoint +CREATE INDEX "account_action_tokens_expiry_idx" ON "account_action_tokens" USING btree ("expires_at"); \ No newline at end of file diff --git a/server/drizzle/0008_red_trish_tilby.sql b/server/drizzle/0008_red_trish_tilby.sql new file mode 100644 index 0000000..a73f3f0 --- /dev/null +++ b/server/drizzle/0008_red_trish_tilby.sql @@ -0,0 +1,4 @@ +ALTER TYPE "public"."delivery_status" ADD VALUE 'CANCELLED';--> statement-breakpoint +ALTER TABLE "deliveries" ADD COLUMN "job_id" uuid;--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_job_id_generation_jobs_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."generation_jobs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "deliveries_job_idx" ON "deliveries" USING btree ("job_id"); \ No newline at end of file diff --git a/server/drizzle/0009_chilly_mockingbird.sql b/server/drizzle/0009_chilly_mockingbird.sql new file mode 100644 index 0000000..380cb8c --- /dev/null +++ b/server/drizzle/0009_chilly_mockingbird.sql @@ -0,0 +1,34 @@ +CREATE TABLE "billing_subscriptions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "provider" varchar(32) DEFAULT 'stripe' NOT NULL, + "customer_id" varchar(255) NOT NULL, + "subscription_id" varchar(255), + "price_id" varchar(255), + "plan" varchar(32), + "status" varchar(48) DEFAULT 'no_subscription' NOT NULL, + "current_period_end" timestamp with time zone, + "cancel_at_period_end" boolean DEFAULT false NOT NULL, + "last_event_created_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "billing_webhook_events" ( + "event_id" varchar(255) PRIMARY KEY NOT NULL, + "provider" varchar(32) DEFAULT 'stripe' NOT NULL, + "event_type" varchar(160) NOT NULL, + "livemode" boolean DEFAULT false NOT NULL, + "workspace_id" uuid, + "provider_created_at" timestamp with time zone NOT NULL, + "processed_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "billing_subscriptions" ADD CONSTRAINT "billing_subscriptions_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "billing_webhook_events" ADD CONSTRAINT "billing_webhook_events_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "billing_subscriptions_workspace_unique" ON "billing_subscriptions" USING btree ("workspace_id");--> statement-breakpoint +CREATE UNIQUE INDEX "billing_subscriptions_customer_unique" ON "billing_subscriptions" USING btree ("customer_id");--> statement-breakpoint +CREATE UNIQUE INDEX "billing_subscriptions_subscription_unique" ON "billing_subscriptions" USING btree ("subscription_id");--> statement-breakpoint +CREATE INDEX "billing_subscriptions_status_idx" ON "billing_subscriptions" USING btree ("status");--> statement-breakpoint +CREATE INDEX "billing_webhook_events_workspace_idx" ON "billing_webhook_events" USING btree ("workspace_id","processed_at");--> statement-breakpoint +CREATE INDEX "billing_webhook_events_type_idx" ON "billing_webhook_events" USING btree ("event_type"); \ No newline at end of file diff --git a/server/drizzle/0010_sharp_odin.sql b/server/drizzle/0010_sharp_odin.sql new file mode 100644 index 0000000..3d71edc --- /dev/null +++ b/server/drizzle/0010_sharp_odin.sql @@ -0,0 +1,3 @@ +ALTER TABLE "renders" ADD COLUMN "subtitle_srt_key" text;--> statement-breakpoint +ALTER TABLE "renders" ADD COLUMN "subtitle_vtt_key" text;--> statement-breakpoint +ALTER TABLE "renders" ADD COLUMN "source_manifest" jsonb; \ No newline at end of file diff --git a/server/drizzle/0011_futuristic_stature.sql b/server/drizzle/0011_futuristic_stature.sql new file mode 100644 index 0000000..9df427b --- /dev/null +++ b/server/drizzle/0011_futuristic_stature.sql @@ -0,0 +1,25 @@ +CREATE TYPE "public"."notification_tone" AS ENUM('INFO', 'SUCCESS', 'WARNING', 'ERROR');--> statement-breakpoint +CREATE TABLE "notifications" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "user_id" uuid NOT NULL, + "kind" varchar(80) NOT NULL, + "tone" "notification_tone" DEFAULT 'INFO' NOT NULL, + "title" varchar(240) NOT NULL, + "body" text DEFAULT '' NOT NULL, + "page" varchar(48) NOT NULL, + "resource_type" varchar(80), + "resource_id" uuid, + "dedupe_key" varchar(255) NOT NULL, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "read_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "notifications" ADD CONSTRAINT "notifications_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "notifications" ADD CONSTRAINT "notifications_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "notifications_user_dedupe_unique" ON "notifications" USING btree ("user_id","dedupe_key");--> statement-breakpoint +CREATE INDEX "notifications_user_created_idx" ON "notifications" USING btree ("user_id","created_at");--> statement-breakpoint +CREATE INDEX "notifications_user_unread_idx" ON "notifications" USING btree ("user_id","read_at","created_at");--> statement-breakpoint +CREATE INDEX "notifications_workspace_created_idx" ON "notifications" USING btree ("workspace_id","created_at"); \ No newline at end of file diff --git a/server/drizzle/0012_warm_old_lace.sql b/server/drizzle/0012_warm_old_lace.sql new file mode 100644 index 0000000..c6da466 --- /dev/null +++ b/server/drizzle/0012_warm_old_lace.sql @@ -0,0 +1,62 @@ +CREATE TYPE "public"."publishing_channel_status" AS ENUM('CONNECTED', 'EXPIRED', 'REVOKED', 'ERROR');--> statement-breakpoint +CREATE TABLE "publishing_channel_accounts" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "platform" varchar(32) NOT NULL, + "external_account_id" varchar(255) NOT NULL, + "display_name" varchar(180) NOT NULL, + "avatar_url" text, + "status" "publishing_channel_status" DEFAULT 'CONNECTED' NOT NULL, + "access_token_ciphertext" text, + "refresh_token_ciphertext" text, + "token_expires_at" timestamp with time zone, + "scopes" jsonb DEFAULT '[]'::jsonb NOT NULL, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, + "connected_by_id" uuid NOT NULL, + "last_verified_at" timestamp with time zone DEFAULT now() NOT NULL, + "error_code" varchar(100), + "error_message" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "publishing_oauth_states" ( + "state_hash" varchar(64) PRIMARY KEY NOT NULL, + "workspace_id" uuid NOT NULL, + "platform" varchar(32) NOT NULL, + "code_verifier_ciphertext" text, + "return_path" text DEFAULT '/?publishing=connected' NOT NULL, + "created_by_id" uuid NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "consumed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "publishing_webhook_events" ( + "event_key" varchar(320) PRIMARY KEY NOT NULL, + "event_id" varchar(255) NOT NULL, + "platform" varchar(32) NOT NULL, + "delivery_id" uuid, + "status" varchar(32) NOT NULL, + "provider_occurred_at" timestamp with time zone NOT NULL, + "payload" jsonb DEFAULT '{}'::jsonb NOT NULL, + "applied" boolean DEFAULT false NOT NULL, + "processed_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "deliveries" ADD COLUMN "channel_account_id" uuid;--> statement-breakpoint +ALTER TABLE "deliveries" ADD COLUMN "last_provider_event_at" timestamp with time zone;--> statement-breakpoint +ALTER TABLE "publishing_channel_accounts" ADD CONSTRAINT "publishing_channel_accounts_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "publishing_channel_accounts" ADD CONSTRAINT "publishing_channel_accounts_connected_by_id_users_id_fk" FOREIGN KEY ("connected_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "publishing_oauth_states" ADD CONSTRAINT "publishing_oauth_states_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "publishing_oauth_states" ADD CONSTRAINT "publishing_oauth_states_created_by_id_users_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "publishing_webhook_events" ADD CONSTRAINT "publishing_webhook_events_delivery_id_deliveries_id_fk" FOREIGN KEY ("delivery_id") REFERENCES "public"."deliveries"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "publishing_channel_accounts_external_unique" ON "publishing_channel_accounts" USING btree ("workspace_id","platform","external_account_id");--> statement-breakpoint +CREATE INDEX "publishing_channel_accounts_workspace_idx" ON "publishing_channel_accounts" USING btree ("workspace_id","platform");--> statement-breakpoint +CREATE INDEX "publishing_channel_accounts_status_idx" ON "publishing_channel_accounts" USING btree ("workspace_id","status");--> statement-breakpoint +CREATE INDEX "publishing_oauth_states_expiry_idx" ON "publishing_oauth_states" USING btree ("expires_at");--> statement-breakpoint +CREATE INDEX "publishing_oauth_states_workspace_idx" ON "publishing_oauth_states" USING btree ("workspace_id","platform");--> statement-breakpoint +CREATE INDEX "publishing_webhook_events_delivery_idx" ON "publishing_webhook_events" USING btree ("delivery_id","provider_occurred_at");--> statement-breakpoint +CREATE INDEX "publishing_webhook_events_platform_idx" ON "publishing_webhook_events" USING btree ("platform","processed_at");--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_channel_account_id_publishing_channel_accounts_id_fk" FOREIGN KEY ("channel_account_id") REFERENCES "public"."publishing_channel_accounts"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "deliveries_channel_account_idx" ON "deliveries" USING btree ("channel_account_id"); \ No newline at end of file diff --git a/server/drizzle/0013_lethal_giant_man.sql b/server/drizzle/0013_lethal_giant_man.sql new file mode 100644 index 0000000..133b584 --- /dev/null +++ b/server/drizzle/0013_lethal_giant_man.sql @@ -0,0 +1,3 @@ +ALTER TABLE "publishing_webhook_events" ADD COLUMN "workspace_id" uuid NOT NULL;--> statement-breakpoint +ALTER TABLE "publishing_webhook_events" ADD CONSTRAINT "publishing_webhook_events_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "publishing_webhook_events_workspace_idx" ON "publishing_webhook_events" USING btree ("workspace_id","processed_at"); \ No newline at end of file diff --git a/server/drizzle/0014_heavy_retro_girl.sql b/server/drizzle/0014_heavy_retro_girl.sql new file mode 100644 index 0000000..5e26acf --- /dev/null +++ b/server/drizzle/0014_heavy_retro_girl.sql @@ -0,0 +1,3 @@ +ALTER TABLE "deliveries" DROP CONSTRAINT "deliveries_channel_account_id_publishing_channel_accounts_id_fk"; +--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_channel_account_id_publishing_channel_accounts_id_fk" FOREIGN KEY ("channel_account_id") REFERENCES "public"."publishing_channel_accounts"("id") ON DELETE set null ON UPDATE no action; \ No newline at end of file diff --git a/server/drizzle/0015_reflective_true_believers.sql b/server/drizzle/0015_reflective_true_believers.sql new file mode 100644 index 0000000..e195b41 --- /dev/null +++ b/server/drizzle/0015_reflective_true_believers.sql @@ -0,0 +1,3 @@ +ALTER TABLE "deliveries" DROP CONSTRAINT "deliveries_channel_account_id_publishing_channel_accounts_id_fk"; +--> statement-breakpoint +ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_channel_account_id_publishing_channel_accounts_id_fk" FOREIGN KEY ("channel_account_id") REFERENCES "public"."publishing_channel_accounts"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/server/drizzle/0016_amused_longshot.sql b/server/drizzle/0016_amused_longshot.sql new file mode 100644 index 0000000..04879a5 --- /dev/null +++ b/server/drizzle/0016_amused_longshot.sql @@ -0,0 +1,20 @@ +CREATE TABLE "provider_verifications" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "workspace_id" uuid NOT NULL, + "provider" varchar(32) NOT NULL, + "status" varchar(32) NOT NULL, + "configuration_fingerprint" varchar(64) NOT NULL, + "checked_at" timestamp with time zone DEFAULT now() NOT NULL, + "latency_ms" integer, + "error_code" varchar(80), + "message" text, + "details" jsonb DEFAULT '{}'::jsonb NOT NULL, + "checked_by_id" uuid NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +ALTER TABLE "provider_verifications" ADD CONSTRAINT "provider_verifications_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "provider_verifications" ADD CONSTRAINT "provider_verifications_checked_by_id_users_id_fk" FOREIGN KEY ("checked_by_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "provider_verifications_workspace_provider_unique" ON "provider_verifications" USING btree ("workspace_id","provider");--> statement-breakpoint +CREATE INDEX "provider_verifications_workspace_status_idx" ON "provider_verifications" USING btree ("workspace_id","status"); \ No newline at end of file diff --git a/server/drizzle/meta/0000_snapshot.json b/server/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..3e677bb --- /dev/null +++ b/server/drizzle/meta/0000_snapshot.json @@ -0,0 +1,2980 @@ +{ + "id": "34864dff-ea51-4989-8dc8-3c2e81bd63d5", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "SCRIPT_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0001_snapshot.json b/server/drizzle/meta/0001_snapshot.json new file mode 100644 index 0000000..6fc0280 --- /dev/null +++ b/server/drizzle/meta/0001_snapshot.json @@ -0,0 +1,2981 @@ +{ + "id": "38b0fb89-3922-45b7-83ba-81248aff9685", + "prevId": "34864dff-ea51-4989-8dc8-3c2e81bd63d5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0002_snapshot.json b/server/drizzle/meta/0002_snapshot.json new file mode 100644 index 0000000..6121a21 --- /dev/null +++ b/server/drizzle/meta/0002_snapshot.json @@ -0,0 +1,2982 @@ +{ + "id": "acdb9359-8b09-489e-a027-f62abffe093b", + "prevId": "38b0fb89-3922-45b7-83ba-81248aff9685", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0003_snapshot.json b/server/drizzle/meta/0003_snapshot.json new file mode 100644 index 0000000..5a90cae --- /dev/null +++ b/server/drizzle/meta/0003_snapshot.json @@ -0,0 +1,2983 @@ +{ + "id": "d6396dbf-e5cd-4ca9-a622-8f47ad9a2ce6", + "prevId": "acdb9359-8b09-489e-a027-f62abffe093b", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0004_snapshot.json b/server/drizzle/meta/0004_snapshot.json new file mode 100644 index 0000000..7f06e80 --- /dev/null +++ b/server/drizzle/meta/0004_snapshot.json @@ -0,0 +1,2990 @@ +{ + "id": "8bf065f5-954e-4821-8a01-82be442dc65d", + "prevId": "d6396dbf-e5cd-4ca9-a622-8f47ad9a2ce6", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0005_snapshot.json b/server/drizzle/meta/0005_snapshot.json new file mode 100644 index 0000000..aa700da --- /dev/null +++ b/server/drizzle/meta/0005_snapshot.json @@ -0,0 +1,3178 @@ +{ + "id": "05cc30f0-a2df-411d-8baf-b0243d5f748f", + "prevId": "8bf065f5-954e-4821-8a01-82be442dc65d", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0006_snapshot.json b/server/drizzle/meta/0006_snapshot.json new file mode 100644 index 0000000..cc2e216 --- /dev/null +++ b/server/drizzle/meta/0006_snapshot.json @@ -0,0 +1,3406 @@ +{ + "id": "166980e0-15f9-4539-bbcc-0769218de091", + "prevId": "05cc30f0-a2df-411d-8baf-b0243d5f748f", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0007_snapshot.json b/server/drizzle/meta/0007_snapshot.json new file mode 100644 index 0000000..f05a050 --- /dev/null +++ b/server/drizzle/meta/0007_snapshot.json @@ -0,0 +1,3538 @@ +{ + "id": "8265f41f-cc78-4cad-82c9-82721ba18ccc", + "prevId": "166980e0-15f9-4539-bbcc-0769218de091", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0008_snapshot.json b/server/drizzle/meta/0008_snapshot.json new file mode 100644 index 0000000..7baeb28 --- /dev/null +++ b/server/drizzle/meta/0008_snapshot.json @@ -0,0 +1,3573 @@ +{ + "id": "21f5a9cd-de25-45d1-8620-3d133d3d161d", + "prevId": "8265f41f-cc78-4cad-82c9-82721ba18ccc", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0009_snapshot.json b/server/drizzle/meta/0009_snapshot.json new file mode 100644 index 0000000..0819759 --- /dev/null +++ b/server/drizzle/meta/0009_snapshot.json @@ -0,0 +1,3854 @@ +{ + "id": "afc084f4-1d7f-4c41-b31c-d6a3d738ef18", + "prevId": "21f5a9cd-de25-45d1-8620-3d133d3d161d", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0010_snapshot.json b/server/drizzle/meta/0010_snapshot.json new file mode 100644 index 0000000..66bc5cb --- /dev/null +++ b/server/drizzle/meta/0010_snapshot.json @@ -0,0 +1,3872 @@ +{ + "id": "b059ffe6-7413-4008-ac83-b763457d5aa1", + "prevId": "afc084f4-1d7f-4c41-b31c-d6a3d738ef18", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0011_snapshot.json b/server/drizzle/meta/0011_snapshot.json new file mode 100644 index 0000000..ca72894 --- /dev/null +++ b/server/drizzle/meta/0011_snapshot.json @@ -0,0 +1,4110 @@ +{ + "id": "72ba7485-1bb1-4a18-b819-e7099b57544c", + "prevId": "b059ffe6-7413-4008-ac83-b763457d5aa1", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0012_snapshot.json b/server/drizzle/meta/0012_snapshot.json new file mode 100644 index 0000000..01c4a48 --- /dev/null +++ b/server/drizzle/meta/0012_snapshot.json @@ -0,0 +1,4646 @@ +{ + "id": "3232a581-0f8c-466e-b51e-c808930a54b2", + "prevId": "72ba7485-1bb1-4a18-b819-e7099b57544c", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "channel_account_id": { + "name": "channel_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_provider_event_at": { + "name": "last_provider_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_channel_account_idx": { + "name": "deliveries_channel_account_idx", + "columns": [ + { + "expression": "channel_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_channel_account_id_publishing_channel_accounts_id_fk": { + "name": "deliveries_channel_account_id_publishing_channel_accounts_id_fk", + "tableFrom": "deliveries", + "tableTo": "publishing_channel_accounts", + "columnsFrom": [ + "channel_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_channel_accounts": { + "name": "publishing_channel_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "external_account_id": { + "name": "external_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "publishing_channel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'CONNECTED'" + }, + "access_token_ciphertext": { + "name": "access_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ciphertext": { + "name": "refresh_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "connected_by_id": { + "name": "connected_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "last_verified_at": { + "name": "last_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_channel_accounts_external_unique": { + "name": "publishing_channel_accounts_external_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "external_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_workspace_idx": { + "name": "publishing_channel_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_status_idx": { + "name": "publishing_channel_accounts_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_channel_accounts_workspace_id_workspaces_id_fk": { + "name": "publishing_channel_accounts_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_channel_accounts_connected_by_id_users_id_fk": { + "name": "publishing_channel_accounts_connected_by_id_users_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "users", + "columnsFrom": [ + "connected_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_oauth_states": { + "name": "publishing_oauth_states", + "schema": "", + "columns": { + "state_hash": { + "name": "state_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "code_verifier_ciphertext": { + "name": "code_verifier_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_path": { + "name": "return_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/?publishing=connected'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_oauth_states_expiry_idx": { + "name": "publishing_oauth_states_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_oauth_states_workspace_idx": { + "name": "publishing_oauth_states_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_oauth_states_workspace_id_workspaces_id_fk": { + "name": "publishing_oauth_states_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_oauth_states_created_by_id_users_id_fk": { + "name": "publishing_oauth_states_created_by_id_users_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_webhook_events": { + "name": "publishing_webhook_events", + "schema": "", + "columns": { + "event_key": { + "name": "event_key", + "type": "varchar(320)", + "primaryKey": true, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_occurred_at": { + "name": "provider_occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_webhook_events_delivery_idx": { + "name": "publishing_webhook_events_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_platform_idx": { + "name": "publishing_webhook_events_platform_idx", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_webhook_events_delivery_id_deliveries_id_fk": { + "name": "publishing_webhook_events_delivery_id_deliveries_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "deliveries", + "columnsFrom": [ + "delivery_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.publishing_channel_status": { + "name": "publishing_channel_status", + "schema": "public", + "values": [ + "CONNECTED", + "EXPIRED", + "REVOKED", + "ERROR" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0013_snapshot.json b/server/drizzle/meta/0013_snapshot.json new file mode 100644 index 0000000..120c747 --- /dev/null +++ b/server/drizzle/meta/0013_snapshot.json @@ -0,0 +1,4686 @@ +{ + "id": "9556a6ed-469f-4031-9275-7fb836907b5d", + "prevId": "3232a581-0f8c-466e-b51e-c808930a54b2", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "channel_account_id": { + "name": "channel_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_provider_event_at": { + "name": "last_provider_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_channel_account_idx": { + "name": "deliveries_channel_account_idx", + "columns": [ + { + "expression": "channel_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_channel_account_id_publishing_channel_accounts_id_fk": { + "name": "deliveries_channel_account_id_publishing_channel_accounts_id_fk", + "tableFrom": "deliveries", + "tableTo": "publishing_channel_accounts", + "columnsFrom": [ + "channel_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_channel_accounts": { + "name": "publishing_channel_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "external_account_id": { + "name": "external_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "publishing_channel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'CONNECTED'" + }, + "access_token_ciphertext": { + "name": "access_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ciphertext": { + "name": "refresh_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "connected_by_id": { + "name": "connected_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "last_verified_at": { + "name": "last_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_channel_accounts_external_unique": { + "name": "publishing_channel_accounts_external_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "external_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_workspace_idx": { + "name": "publishing_channel_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_status_idx": { + "name": "publishing_channel_accounts_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_channel_accounts_workspace_id_workspaces_id_fk": { + "name": "publishing_channel_accounts_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_channel_accounts_connected_by_id_users_id_fk": { + "name": "publishing_channel_accounts_connected_by_id_users_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "users", + "columnsFrom": [ + "connected_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_oauth_states": { + "name": "publishing_oauth_states", + "schema": "", + "columns": { + "state_hash": { + "name": "state_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "code_verifier_ciphertext": { + "name": "code_verifier_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_path": { + "name": "return_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/?publishing=connected'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_oauth_states_expiry_idx": { + "name": "publishing_oauth_states_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_oauth_states_workspace_idx": { + "name": "publishing_oauth_states_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_oauth_states_workspace_id_workspaces_id_fk": { + "name": "publishing_oauth_states_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_oauth_states_created_by_id_users_id_fk": { + "name": "publishing_oauth_states_created_by_id_users_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_webhook_events": { + "name": "publishing_webhook_events", + "schema": "", + "columns": { + "event_key": { + "name": "event_key", + "type": "varchar(320)", + "primaryKey": true, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_occurred_at": { + "name": "provider_occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_webhook_events_delivery_idx": { + "name": "publishing_webhook_events_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_workspace_idx": { + "name": "publishing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_platform_idx": { + "name": "publishing_webhook_events_platform_idx", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "publishing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_webhook_events_delivery_id_deliveries_id_fk": { + "name": "publishing_webhook_events_delivery_id_deliveries_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "deliveries", + "columnsFrom": [ + "delivery_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.publishing_channel_status": { + "name": "publishing_channel_status", + "schema": "public", + "values": [ + "CONNECTED", + "EXPIRED", + "REVOKED", + "ERROR" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0014_snapshot.json b/server/drizzle/meta/0014_snapshot.json new file mode 100644 index 0000000..a9a5bf8 --- /dev/null +++ b/server/drizzle/meta/0014_snapshot.json @@ -0,0 +1,4686 @@ +{ + "id": "6af179a4-1050-424f-b129-91a2300b9544", + "prevId": "9556a6ed-469f-4031-9275-7fb836907b5d", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "channel_account_id": { + "name": "channel_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_provider_event_at": { + "name": "last_provider_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_channel_account_idx": { + "name": "deliveries_channel_account_idx", + "columns": [ + { + "expression": "channel_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_channel_account_id_publishing_channel_accounts_id_fk": { + "name": "deliveries_channel_account_id_publishing_channel_accounts_id_fk", + "tableFrom": "deliveries", + "tableTo": "publishing_channel_accounts", + "columnsFrom": [ + "channel_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_channel_accounts": { + "name": "publishing_channel_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "external_account_id": { + "name": "external_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "publishing_channel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'CONNECTED'" + }, + "access_token_ciphertext": { + "name": "access_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ciphertext": { + "name": "refresh_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "connected_by_id": { + "name": "connected_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "last_verified_at": { + "name": "last_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_channel_accounts_external_unique": { + "name": "publishing_channel_accounts_external_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "external_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_workspace_idx": { + "name": "publishing_channel_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_status_idx": { + "name": "publishing_channel_accounts_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_channel_accounts_workspace_id_workspaces_id_fk": { + "name": "publishing_channel_accounts_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_channel_accounts_connected_by_id_users_id_fk": { + "name": "publishing_channel_accounts_connected_by_id_users_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "users", + "columnsFrom": [ + "connected_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_oauth_states": { + "name": "publishing_oauth_states", + "schema": "", + "columns": { + "state_hash": { + "name": "state_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "code_verifier_ciphertext": { + "name": "code_verifier_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_path": { + "name": "return_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/?publishing=connected'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_oauth_states_expiry_idx": { + "name": "publishing_oauth_states_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_oauth_states_workspace_idx": { + "name": "publishing_oauth_states_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_oauth_states_workspace_id_workspaces_id_fk": { + "name": "publishing_oauth_states_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_oauth_states_created_by_id_users_id_fk": { + "name": "publishing_oauth_states_created_by_id_users_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_webhook_events": { + "name": "publishing_webhook_events", + "schema": "", + "columns": { + "event_key": { + "name": "event_key", + "type": "varchar(320)", + "primaryKey": true, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_occurred_at": { + "name": "provider_occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_webhook_events_delivery_idx": { + "name": "publishing_webhook_events_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_workspace_idx": { + "name": "publishing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_platform_idx": { + "name": "publishing_webhook_events_platform_idx", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "publishing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_webhook_events_delivery_id_deliveries_id_fk": { + "name": "publishing_webhook_events_delivery_id_deliveries_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "deliveries", + "columnsFrom": [ + "delivery_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.publishing_channel_status": { + "name": "publishing_channel_status", + "schema": "public", + "values": [ + "CONNECTED", + "EXPIRED", + "REVOKED", + "ERROR" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0015_snapshot.json b/server/drizzle/meta/0015_snapshot.json new file mode 100644 index 0000000..08815cf --- /dev/null +++ b/server/drizzle/meta/0015_snapshot.json @@ -0,0 +1,4686 @@ +{ + "id": "69e62589-0f6f-4604-830b-0cd44e776e43", + "prevId": "6af179a4-1050-424f-b129-91a2300b9544", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "channel_account_id": { + "name": "channel_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_provider_event_at": { + "name": "last_provider_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_channel_account_idx": { + "name": "deliveries_channel_account_idx", + "columns": [ + { + "expression": "channel_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_channel_account_id_publishing_channel_accounts_id_fk": { + "name": "deliveries_channel_account_id_publishing_channel_accounts_id_fk", + "tableFrom": "deliveries", + "tableTo": "publishing_channel_accounts", + "columnsFrom": [ + "channel_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_channel_accounts": { + "name": "publishing_channel_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "external_account_id": { + "name": "external_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "publishing_channel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'CONNECTED'" + }, + "access_token_ciphertext": { + "name": "access_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ciphertext": { + "name": "refresh_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "connected_by_id": { + "name": "connected_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "last_verified_at": { + "name": "last_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_channel_accounts_external_unique": { + "name": "publishing_channel_accounts_external_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "external_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_workspace_idx": { + "name": "publishing_channel_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_status_idx": { + "name": "publishing_channel_accounts_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_channel_accounts_workspace_id_workspaces_id_fk": { + "name": "publishing_channel_accounts_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_channel_accounts_connected_by_id_users_id_fk": { + "name": "publishing_channel_accounts_connected_by_id_users_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "users", + "columnsFrom": [ + "connected_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_oauth_states": { + "name": "publishing_oauth_states", + "schema": "", + "columns": { + "state_hash": { + "name": "state_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "code_verifier_ciphertext": { + "name": "code_verifier_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_path": { + "name": "return_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/?publishing=connected'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_oauth_states_expiry_idx": { + "name": "publishing_oauth_states_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_oauth_states_workspace_idx": { + "name": "publishing_oauth_states_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_oauth_states_workspace_id_workspaces_id_fk": { + "name": "publishing_oauth_states_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_oauth_states_created_by_id_users_id_fk": { + "name": "publishing_oauth_states_created_by_id_users_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_webhook_events": { + "name": "publishing_webhook_events", + "schema": "", + "columns": { + "event_key": { + "name": "event_key", + "type": "varchar(320)", + "primaryKey": true, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_occurred_at": { + "name": "provider_occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_webhook_events_delivery_idx": { + "name": "publishing_webhook_events_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_workspace_idx": { + "name": "publishing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_platform_idx": { + "name": "publishing_webhook_events_platform_idx", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "publishing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_webhook_events_delivery_id_deliveries_id_fk": { + "name": "publishing_webhook_events_delivery_id_deliveries_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "deliveries", + "columnsFrom": [ + "delivery_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.publishing_channel_status": { + "name": "publishing_channel_status", + "schema": "public", + "values": [ + "CONNECTED", + "EXPIRED", + "REVOKED", + "ERROR" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/0016_snapshot.json b/server/drizzle/meta/0016_snapshot.json new file mode 100644 index 0000000..e014a55 --- /dev/null +++ b/server/drizzle/meta/0016_snapshot.json @@ -0,0 +1,4852 @@ +{ + "id": "991595be-497b-4ac6-ae8d-c93f4508b9fb", + "prevId": "69e62589-0f6f-4604-830b-0cd44e776e43", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account_action_tokens": { + "name": "account_action_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "account_token_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "account_action_tokens_hash_unique": { + "name": "account_action_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_user_type_idx": { + "name": "account_action_tokens_user_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "account_action_tokens_expiry_idx": { + "name": "account_action_tokens_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_action_tokens_user_id_users_id_fk": { + "name": "account_action_tokens_user_id_users_id_fk", + "tableFrom": "account_action_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.asset_versions": { + "name": "asset_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "asset_id": { + "name": "asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": false + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "negative_prompt": { + "name": "negative_prompt", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "seed": { + "name": "seed", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "asset_versions_asset_version_unique": { + "name": "asset_versions_asset_version_unique", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "asset_versions_current_idx": { + "name": "asset_versions_current_idx", + "columns": [ + { + "expression": "asset_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "asset_versions_asset_id_assets_id_fk": { + "name": "asset_versions_asset_id_assets_id_fk", + "tableFrom": "asset_versions", + "tableTo": "assets", + "columnsFrom": [ + "asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "asset_versions_created_by_id_users_id_fk": { + "name": "asset_versions_created_by_id_users_id_fk", + "tableFrom": "asset_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.assets": { + "name": "assets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "asset_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "status": { + "name": "status", + "type": "asset_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "assets_project_type_idx": { + "name": "assets_project_type_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "assets_project_status_idx": { + "name": "assets_project_status_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "assets_project_id_projects_id_fk": { + "name": "assets_project_id_projects_id_fk", + "tableFrom": "assets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "assets_created_by_id_users_id_fk": { + "name": "assets_created_by_id_users_id_fk", + "tableFrom": "assets", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after": { + "name": "after", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_logs_workspace_time_idx": { + "name": "audit_logs_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "audit_logs_actor_idx": { + "name": "audit_logs_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_workspace_id_workspaces_id_fk": { + "name": "audit_logs_workspace_id_workspaces_id_fk", + "tableFrom": "audit_logs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audit_logs_actor_id_users_id_fk": { + "name": "audit_logs_actor_id_users_id_fk", + "tableFrom": "audit_logs", + "tableTo": "users", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_subscriptions": { + "name": "billing_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "price_id": { + "name": "price_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true, + "default": "'no_subscription'" + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_event_created_at": { + "name": "last_event_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_subscriptions_workspace_unique": { + "name": "billing_subscriptions_workspace_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_customer_unique": { + "name": "billing_subscriptions_customer_unique", + "columns": [ + { + "expression": "customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_subscription_unique": { + "name": "billing_subscriptions_subscription_unique", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_subscriptions_status_idx": { + "name": "billing_subscriptions_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_subscriptions_workspace_id_workspaces_id_fk": { + "name": "billing_subscriptions_workspace_id_workspaces_id_fk", + "tableFrom": "billing_subscriptions", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_webhook_events": { + "name": "billing_webhook_events", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "event_type": { + "name": "event_type", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "livemode": { + "name": "livemode", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_created_at": { + "name": "provider_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_webhook_events_workspace_idx": { + "name": "billing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_webhook_events_type_idx": { + "name": "billing_webhook_events_type_idx", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "billing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "billing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deliveries": { + "name": "deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "channel_account_id": { + "name": "channel_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "destination": { + "name": "destination", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "published_url": { + "name": "published_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_provider_event_at": { + "name": "last_provider_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "deliveries_render_idx": { + "name": "deliveries_render_idx", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_job_idx": { + "name": "deliveries_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_channel_account_idx": { + "name": "deliveries_channel_account_idx", + "columns": [ + { + "expression": "channel_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "deliveries_status_idx": { + "name": "deliveries_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deliveries_render_id_renders_id_fk": { + "name": "deliveries_render_id_renders_id_fk", + "tableFrom": "deliveries", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_job_id_generation_jobs_id_fk": { + "name": "deliveries_job_id_generation_jobs_id_fk", + "tableFrom": "deliveries", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "deliveries_channel_account_id_publishing_channel_accounts_id_fk": { + "name": "deliveries_channel_account_id_publishing_channel_accounts_id_fk", + "tableFrom": "deliveries", + "tableTo": "publishing_channel_accounts", + "columnsFrom": [ + "channel_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deliveries_created_by_id_users_id_fk": { + "name": "deliveries_created_by_id_users_id_fk", + "tableFrom": "deliveries", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.episodes": { + "name": "episodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "episode_number": { + "name": "episode_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "synopsis": { + "name": "synopsis", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "target_duration_seconds": { + "name": "target_duration_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 180 + }, + "status": { + "name": "status", + "type": "episode_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OUTLINE'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "episodes_project_number_unique": { + "name": "episodes_project_number_unique", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "episode_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "episodes_project_idx": { + "name": "episodes_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "episodes_project_id_projects_id_fk": { + "name": "episodes_project_id_projects_id_fk", + "tableFrom": "episodes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "episodes_created_by_id_users_id_fk": { + "name": "episodes_created_by_id_users_id_fk", + "tableFrom": "episodes", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generation_jobs": { + "name": "generation_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "production_run_id": { + "name": "production_run_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "job_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider": { + "name": "provider", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "provider_model": { + "name": "provider_model", + "type": "varchar(160)", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + }, + "estimated_credits": { + "name": "estimated_credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "generation_jobs_idempotency_unique": { + "name": "generation_jobs_idempotency_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_workspace_status_idx": { + "name": "generation_jobs_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_project_idx": { + "name": "generation_jobs_project_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "generation_jobs_production_run_idx": { + "name": "generation_jobs_production_run_idx", + "columns": [ + { + "expression": "production_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generation_jobs_workspace_id_workspaces_id_fk": { + "name": "generation_jobs_workspace_id_workspaces_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_project_id_projects_id_fk": { + "name": "generation_jobs_project_id_projects_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_episode_id_episodes_id_fk": { + "name": "generation_jobs_episode_id_episodes_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generation_jobs_production_run_id_production_runs_id_fk": { + "name": "generation_jobs_production_run_id_production_runs_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "production_runs", + "columnsFrom": [ + "production_run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "generation_jobs_created_by_id_users_id_fk": { + "name": "generation_jobs_created_by_id_users_id_fk", + "tableFrom": "generation_jobs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "memberships_workspace_id_workspaces_id_fk": { + "name": "memberships_workspace_id_workspaces_id_fk", + "tableFrom": "memberships", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_user_id_users_id_fk": { + "name": "memberships_user_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "memberships_invited_by_id_users_id_fk": { + "name": "memberships_invited_by_id_users_id_fk", + "tableFrom": "memberships", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "memberships_workspace_id_user_id_pk": { + "name": "memberships_workspace_id_user_id_pk", + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "tone": { + "name": "tone", + "type": "notification_tone", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'INFO'" + }, + "title": { + "name": "title", + "type": "varchar(240)", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "page": { + "name": "page", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notifications_user_dedupe_unique": { + "name": "notifications_user_dedupe_unique", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_created_idx": { + "name": "notifications_user_created_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_user_unread_idx": { + "name": "notifications_user_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_workspace_created_idx": { + "name": "notifications_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_workspace_id_workspaces_id_fk": { + "name": "notifications_workspace_id_workspaces_id_fk", + "tableFrom": "notifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.production_runs": { + "name": "production_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "render_id": { + "name": "render_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "production_run_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "total_jobs": { + "name": "total_jobs", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "production_runs_render_unique": { + "name": "production_runs_render_unique", + "columns": [ + { + "expression": "render_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_status_idx": { + "name": "production_runs_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "production_runs_episode_created_idx": { + "name": "production_runs_episode_created_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "production_runs_episode_id_episodes_id_fk": { + "name": "production_runs_episode_id_episodes_id_fk", + "tableFrom": "production_runs", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_render_id_renders_id_fk": { + "name": "production_runs_render_id_renders_id_fk", + "tableFrom": "production_runs", + "tableTo": "renders", + "columnsFrom": [ + "render_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "production_runs_created_by_id_users_id_fk": { + "name": "production_runs_created_by_id_users_id_fk", + "tableFrom": "production_runs", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "logline": { + "name": "logline", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "genre": { + "name": "genre", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true, + "default": "'都市悬疑'" + }, + "visual_bible": { + "name": "visual_bible", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "project_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "projects_workspace_slug_unique": { + "name": "projects_workspace_slug_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "projects_workspace_idx": { + "name": "projects_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_workspaces_id_fk": { + "name": "projects_workspace_id_workspaces_id_fk", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "projects_created_by_id_users_id_fk": { + "name": "projects_created_by_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.provider_verifications": { + "name": "provider_verifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "configuration_fingerprint": { + "name": "configuration_fingerprint", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "checked_by_id": { + "name": "checked_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "provider_verifications_workspace_provider_unique": { + "name": "provider_verifications_workspace_provider_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "provider_verifications_workspace_status_idx": { + "name": "provider_verifications_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "provider_verifications_workspace_id_workspaces_id_fk": { + "name": "provider_verifications_workspace_id_workspaces_id_fk", + "tableFrom": "provider_verifications", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "provider_verifications_checked_by_id_users_id_fk": { + "name": "provider_verifications_checked_by_id_users_id_fk", + "tableFrom": "provider_verifications", + "tableTo": "users", + "columnsFrom": [ + "checked_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_channel_accounts": { + "name": "publishing_channel_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "external_account_id": { + "name": "external_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "publishing_channel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'CONNECTED'" + }, + "access_token_ciphertext": { + "name": "access_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ciphertext": { + "name": "refresh_token_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "connected_by_id": { + "name": "connected_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "last_verified_at": { + "name": "last_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "error_code": { + "name": "error_code", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_channel_accounts_external_unique": { + "name": "publishing_channel_accounts_external_unique", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "external_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_workspace_idx": { + "name": "publishing_channel_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_channel_accounts_status_idx": { + "name": "publishing_channel_accounts_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_channel_accounts_workspace_id_workspaces_id_fk": { + "name": "publishing_channel_accounts_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_channel_accounts_connected_by_id_users_id_fk": { + "name": "publishing_channel_accounts_connected_by_id_users_id_fk", + "tableFrom": "publishing_channel_accounts", + "tableTo": "users", + "columnsFrom": [ + "connected_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_oauth_states": { + "name": "publishing_oauth_states", + "schema": "", + "columns": { + "state_hash": { + "name": "state_hash", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "code_verifier_ciphertext": { + "name": "code_verifier_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_path": { + "name": "return_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'/?publishing=connected'" + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_oauth_states_expiry_idx": { + "name": "publishing_oauth_states_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_oauth_states_workspace_idx": { + "name": "publishing_oauth_states_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_oauth_states_workspace_id_workspaces_id_fk": { + "name": "publishing_oauth_states_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_oauth_states_created_by_id_users_id_fk": { + "name": "publishing_oauth_states_created_by_id_users_id_fk", + "tableFrom": "publishing_oauth_states", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.publishing_webhook_events": { + "name": "publishing_webhook_events", + "schema": "", + "columns": { + "event_key": { + "name": "event_key", + "type": "varchar(320)", + "primaryKey": true, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "provider_occurred_at": { + "name": "provider_occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "publishing_webhook_events_delivery_idx": { + "name": "publishing_webhook_events_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_workspace_idx": { + "name": "publishing_webhook_events_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "publishing_webhook_events_platform_idx": { + "name": "publishing_webhook_events_platform_idx", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "processed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "publishing_webhook_events_workspace_id_workspaces_id_fk": { + "name": "publishing_webhook_events_workspace_id_workspaces_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "publishing_webhook_events_delivery_id_deliveries_id_fk": { + "name": "publishing_webhook_events_delivery_id_deliveries_id_fk", + "tableFrom": "publishing_webhook_events", + "tableTo": "deliveries", + "columnsFrom": [ + "delivery_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.refresh_tokens": { + "name": "refresh_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "replaced_by_id": { + "name": "replaced_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "refresh_tokens_hash_unique": { + "name": "refresh_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "refresh_tokens_user_idx": { + "name": "refresh_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "refresh_tokens_user_id_users_id_fk": { + "name": "refresh_tokens_user_id_users_id_fk", + "tableFrom": "refresh_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.renders": { + "name": "renders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "render_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'QUEUED'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_srt_key": { + "name": "subtitle_srt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_vtt_key": { + "name": "subtitle_vtt_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true, + "default": "'video/mp4'" + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fps": { + "name": "fps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source_manifest": { + "name": "source_manifest", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "quality_report": { + "name": "quality_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "renders_episode_version_unique": { + "name": "renders_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "renders_episode_status_idx": { + "name": "renders_episode_status_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "renders_episode_id_episodes_id_fk": { + "name": "renders_episode_id_episodes_id_fk", + "tableFrom": "renders", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "renders_created_by_id_users_id_fk": { + "name": "renders_created_by_id_users_id_fk", + "tableFrom": "renders", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_comments": { + "name": "review_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "review_request_id": { + "name": "review_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timecode_ms": { + "name": "timecode_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_comments_request_idx": { + "name": "review_comments_request_idx", + "columns": [ + { + "expression": "review_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_comments_review_request_id_review_requests_id_fk": { + "name": "review_comments_review_request_id_review_requests_id_fk", + "tableFrom": "review_comments", + "tableTo": "review_requests", + "columnsFrom": [ + "review_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_comments_author_id_users_id_fk": { + "name": "review_comments_author_id_users_id_fk", + "tableFrom": "review_comments", + "tableTo": "users", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.review_requests": { + "name": "review_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "review_target_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'OPEN'" + }, + "requested_by_id": { + "name": "requested_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "assigned_to_id": { + "name": "assigned_to_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "review_requests_workspace_status_idx": { + "name": "review_requests_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "review_requests_target_idx": { + "name": "review_requests_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "review_requests_workspace_id_workspaces_id_fk": { + "name": "review_requests_workspace_id_workspaces_id_fk", + "tableFrom": "review_requests", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "review_requests_requested_by_id_users_id_fk": { + "name": "review_requests_requested_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "requested_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "review_requests_assigned_to_id_users_id_fk": { + "name": "review_requests_assigned_to_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "assigned_to_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "review_requests_resolved_by_id_users_id_fk": { + "name": "review_requests_resolved_by_id_users_id_fk", + "tableFrom": "review_requests", + "tableTo": "users", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.script_versions": { + "name": "script_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(200)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "plain_text": { + "name": "plain_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "change_summary": { + "name": "change_summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "script_versions_episode_version_unique": { + "name": "script_versions_episode_version_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "script_versions_episode_current_idx": { + "name": "script_versions_episode_current_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "script_versions_episode_id_episodes_id_fk": { + "name": "script_versions_episode_id_episodes_id_fk", + "tableFrom": "script_versions", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "script_versions_created_by_id_users_id_fk": { + "name": "script_versions_created_by_id_users_id_fk", + "tableFrom": "script_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shot_versions": { + "name": "shot_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "shot_id": { + "name": "shot_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_asset_version_id": { + "name": "image_asset_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "video_storage_key": { + "name": "video_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "audio_storage_key": { + "name": "audio_storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subtitle_text": { + "name": "subtitle_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "generation_params": { + "name": "generation_params", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_current": { + "name": "is_current", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shot_versions_shot_version_unique": { + "name": "shot_versions_shot_version_unique", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shot_versions_current_idx": { + "name": "shot_versions_current_idx", + "columns": [ + { + "expression": "shot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_current", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shot_versions_shot_id_shots_id_fk": { + "name": "shot_versions_shot_id_shots_id_fk", + "tableFrom": "shot_versions", + "tableTo": "shots", + "columnsFrom": [ + "shot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shot_versions_image_asset_version_id_asset_versions_id_fk": { + "name": "shot_versions_image_asset_version_id_asset_versions_id_fk", + "tableFrom": "shot_versions", + "tableTo": "asset_versions", + "columnsFrom": [ + "image_asset_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shot_versions_created_by_id_users_id_fk": { + "name": "shot_versions_created_by_id_users_id_fk", + "tableFrom": "shot_versions", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shots": { + "name": "shots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "episode_id": { + "name": "episode_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shot_number": { + "name": "shot_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scene_number": { + "name": "scene_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(180)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shot_type": { + "name": "shot_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'中景'" + }, + "camera_motion": { + "name": "camera_motion", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'静止'" + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3000 + }, + "status": { + "name": "status", + "type": "shot_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DRAFT'" + }, + "character_asset_ids": { + "name": "character_asset_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "scene_asset_id": { + "name": "scene_asset_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by_id": { + "name": "created_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shots_episode_number_unique": { + "name": "shots_episode_number_unique", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shot_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shots_episode_sort_idx": { + "name": "shots_episode_sort_idx", + "columns": [ + { + "expression": "episode_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shots_episode_id_episodes_id_fk": { + "name": "shots_episode_id_episodes_id_fk", + "tableFrom": "shots", + "tableTo": "episodes", + "columnsFrom": [ + "episode_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "shots_scene_asset_id_assets_id_fk": { + "name": "shots_scene_asset_id_assets_id_fk", + "tableFrom": "shots", + "tableTo": "assets", + "columnsFrom": [ + "scene_asset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shots_created_by_id_users_id_fk": { + "name": "shots_created_by_id_users_id_fk", + "tableFrom": "shots", + "tableTo": "users", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usage_ledger": { + "name": "usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "usage_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "credits": { + "name": "credits", + "type": "numeric(20, 4)", + "primaryKey": false, + "notNull": true + }, + "provider_cost_usd": { + "name": "provider_cost_usd", + "type": "numeric(20, 6)", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "usage_ledger_workspace_time_idx": { + "name": "usage_ledger_workspace_time_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usage_ledger_job_idx": { + "name": "usage_ledger_job_idx", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "usage_ledger_workspace_id_workspaces_id_fk": { + "name": "usage_ledger_workspace_id_workspaces_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "usage_ledger_user_id_users_id_fk": { + "name": "usage_ledger_user_id_users_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "usage_ledger_job_id_generation_jobs_id_fk": { + "name": "usage_ledger_job_id_generation_jobs_id_fk", + "tableFrom": "usage_ledger", + "tableTo": "generation_jobs", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(120)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "users_email_unique": { + "name": "users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invitations": { + "name": "workspace_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "membership_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'VIEWER'" + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_by_id": { + "name": "accepted_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by_id": { + "name": "invited_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invitations_token_hash_unique": { + "name": "workspace_invitations_token_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_email_idx": { + "name": "workspace_invitations_workspace_email_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invitations_workspace_created_idx": { + "name": "workspace_invitations_workspace_created_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invitations_workspace_id_workspaces_id_fk": { + "name": "workspace_invitations_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invitations_accepted_by_id_users_id_fk": { + "name": "workspace_invitations_accepted_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "accepted_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invitations_invited_by_id_users_id_fk": { + "name": "workspace_invitations_invited_by_id_users_id_fk", + "tableFrom": "workspace_invitations", + "tableTo": "users", + "columnsFrom": [ + "invited_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(160)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(80)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'PRO'" + }, + "monthly_credit_limit": { + "name": "monthly_credit_limit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10000 + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspaces_slug_unique": { + "name": "workspaces_slug_unique", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_owner_idx": { + "name": "workspaces_owner_idx", + "columns": [ + { + "expression": "owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_owner_id_users_id_fk": { + "name": "workspaces_owner_id_users_id_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.account_token_type": { + "name": "account_token_type", + "schema": "public", + "values": [ + "EMAIL_VERIFICATION", + "PASSWORD_RESET" + ] + }, + "public.asset_status": { + "name": "asset_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "ARCHIVED" + ] + }, + "public.asset_type": { + "name": "asset_type", + "schema": "public", + "values": [ + "CHARACTER", + "SCENE", + "PROP", + "VOICE", + "MUSIC", + "SHOT" + ] + }, + "public.delivery_status": { + "name": "delivery_status", + "schema": "public", + "values": [ + "DRAFT", + "QUEUED", + "PUBLISHING", + "PUBLISHED", + "FAILED", + "CANCELLED" + ] + }, + "public.episode_status": { + "name": "episode_status", + "schema": "public", + "values": [ + "OUTLINE", + "SCRIPTING", + "STORYBOARDING", + "PRODUCTION", + "REVIEW", + "PUBLISHED" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.job_type": { + "name": "job_type", + "schema": "public", + "values": [ + "PIPELINE_HEALTHCHECK", + "SCRIPT_GENERATE", + "STORYBOARD_GENERATE", + "ASSET_GENERATE", + "TTS_GENERATE", + "VIDEO_GENERATE", + "LIPSYNC_GENERATE", + "EPISODE_RENDER", + "DELIVERY_PUBLISH" + ] + }, + "public.membership_role": { + "name": "membership_role", + "schema": "public", + "values": [ + "OWNER", + "ADMIN", + "EDITOR", + "REVIEWER", + "VIEWER" + ] + }, + "public.notification_tone": { + "name": "notification_tone", + "schema": "public", + "values": [ + "INFO", + "SUCCESS", + "WARNING", + "ERROR" + ] + }, + "public.production_run_status": { + "name": "production_run_status", + "schema": "public", + "values": [ + "QUEUED", + "RUNNING", + "SUCCEEDED", + "FAILED", + "CANCELLED" + ] + }, + "public.project_status": { + "name": "project_status", + "schema": "public", + "values": [ + "DRAFT", + "ACTIVE", + "ARCHIVED" + ] + }, + "public.publishing_channel_status": { + "name": "publishing_channel_status", + "schema": "public", + "values": [ + "CONNECTED", + "EXPIRED", + "REVOKED", + "ERROR" + ] + }, + "public.render_status": { + "name": "render_status", + "schema": "public", + "values": [ + "QUEUED", + "RENDERING", + "REVIEW", + "APPROVED", + "FAILED" + ] + }, + "public.review_status": { + "name": "review_status", + "schema": "public", + "values": [ + "OPEN", + "APPROVED", + "CHANGES_REQUESTED", + "CANCELLED" + ] + }, + "public.review_target_type": { + "name": "review_target_type", + "schema": "public", + "values": [ + "SCRIPT_VERSION", + "ASSET_VERSION", + "SHOT_VERSION", + "RENDER" + ] + }, + "public.shot_status": { + "name": "shot_status", + "schema": "public", + "values": [ + "DRAFT", + "GENERATING", + "REVIEW", + "APPROVED", + "RENDERED" + ] + }, + "public.usage_kind": { + "name": "usage_kind", + "schema": "public", + "values": [ + "TEXT_INPUT_TOKEN", + "TEXT_OUTPUT_TOKEN", + "IMAGE", + "AUDIO_SECOND", + "VIDEO_SECOND", + "RENDER_SECOND", + "STORAGE_BYTE_MONTH" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/server/drizzle/meta/_journal.json b/server/drizzle/meta/_journal.json new file mode 100644 index 0000000..762fd09 --- /dev/null +++ b/server/drizzle/meta/_journal.json @@ -0,0 +1,125 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1785398872080, + "tag": "0000_last_spectrum", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1785400342760, + "tag": "0001_perfect_gravity", + "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1785401841259, + "tag": "0002_yielding_spencer_smythe", + "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1785404103710, + "tag": "0003_hard_norrin_radd", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1785405889215, + "tag": "0004_goofy_karnak", + "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1785431751467, + "tag": "0005_brave_betty_ross", + "breakpoints": true + }, + { + "idx": 6, + "version": "7", + "when": 1785432812502, + "tag": "0006_wooden_texas_twister", + "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1785434191972, + "tag": "0007_sudden_roland_deschain", + "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1785435268450, + "tag": "0008_red_trish_tilby", + "breakpoints": true + }, + { + "idx": 9, + "version": "7", + "when": 1785437272781, + "tag": "0009_chilly_mockingbird", + "breakpoints": true + }, + { + "idx": 10, + "version": "7", + "when": 1785439338694, + "tag": "0010_sharp_odin", + "breakpoints": true + }, + { + "idx": 11, + "version": "7", + "when": 1785446641562, + "tag": "0011_futuristic_stature", + "breakpoints": true + }, + { + "idx": 12, + "version": "7", + "when": 1785450378611, + "tag": "0012_warm_old_lace", + "breakpoints": true + }, + { + "idx": 13, + "version": "7", + "when": 1785450438724, + "tag": "0013_lethal_giant_man", + "breakpoints": true + }, + { + "idx": 14, + "version": "7", + "when": 1785450621103, + "tag": "0014_heavy_retro_girl", + "breakpoints": true + }, + { + "idx": 15, + "version": "7", + "when": 1785450684178, + "tag": "0015_reflective_true_believers", + "breakpoints": true + }, + { + "idx": 16, + "version": "7", + "when": 1785456376158, + "tag": "0016_amused_longshot", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..7873659 --- /dev/null +++ b/server/package.json @@ -0,0 +1,52 @@ +{ + "name": "@frameflow/server", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "tsx watch src/index.ts", + "worker": "tsx watch src/worker.ts", + "start": "node dist/index.js", + "start:worker": "node dist/worker.js", + "config:check": "tsx src/config-check.ts", + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit", + "db:generate": "drizzle-kit generate", + "db:migrate": "tsx src/db/migrate.ts", + "db:seed": "tsx src/db/seed.ts", + "test": "vitest run", + "test:watch": "vitest" + }, + "dependencies": { + "@aws-sdk/client-s3": "^3.850.0", + "@aws-sdk/s3-request-presigner": "^3.850.0", + "@fastify/cookie": "^11.0.2", + "@fastify/cors": "^11.1.0", + "@fastify/helmet": "^13.0.1", + "@fastify/jwt": "^10.0.0", + "@fastify/multipart": "^9.2.1", + "@fastify/rate-limit": "^10.3.0", + "@fastify/sensible": "^6.0.3", + "argon2": "^0.44.0", + "bullmq": "^5.58.0", + "dotenv": "^17.2.1", + "drizzle-orm": "^0.45.2", + "fastify": "^5.5.0", + "fastify-raw-body": "^5.0.0", + "ioredis": "^5.7.0", + "ipaddr.js": "^2.4.0", + "openai": "^7.2.0", + "pino": "^10.3.1", + "postgres": "^3.4.7", + "prom-client": "^15.1.3", + "stripe": "^22.4.0", + "zod": "^4.0.17" + }, + "devDependencies": { + "@types/node": "^24.2.0", + "drizzle-kit": "^0.31.5", + "tsx": "^4.20.4", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + } +} diff --git a/server/src/app.ts b/server/src/app.ts new file mode 100644 index 0000000..1d9e796 --- /dev/null +++ b/server/src/app.ts @@ -0,0 +1,168 @@ +import cookie from '@fastify/cookie' +import cors from '@fastify/cors' +import helmet from '@fastify/helmet' +import jwt from '@fastify/jwt' +import multipart from '@fastify/multipart' +import rateLimit from '@fastify/rate-limit' +import sensible from '@fastify/sensible' +import rawBody from 'fastify-raw-body' +import Fastify from 'fastify' +import { sql } from 'drizzle-orm' +import { ZodError } from 'zod' +import { config } from './config.js' +import { db } from './db/client.js' +import { AppError } from './lib/errors.js' +import { apiRequestDurationSeconds, apiRequestsTotal, applicationDependencyAvailable, metricsRegistry } from './lib/metrics.js' +import { authRoutes } from './routes/auth.js' +import { assetRoutes } from './routes/assets.js' +import { episodeRoutes } from './routes/episodes.js' +import { projectRoutes } from './routes/projects.js' +import { shotRoutes } from './routes/shots.js' +import { workspaceRoutes } from './routes/workspaces.js' +import { jobRoutes } from './routes/jobs.js' +import { uploadRoutes } from './routes/uploads.js' +import { productionRoutes } from './routes/production.js' +import { reviewRoutes } from './routes/reviews.js' +import { billingRoutes } from './routes/billing.js' +import { readinessRoutes } from './routes/readiness.js' +import { auditRoutes } from './routes/audit.js' +import { notificationRoutes } from './routes/notifications.js' +import { publishingRoutes } from './routes/publishing.js' +import type { StripeBillingProvider } from './lib/stripe-billing.js' +import type { PublishingAdapterRegistry } from './publishing/types.js' +import type { InvitationMailer } from './lib/mailer.js' +import type { ProviderConfiguration } from './providers/readiness.js' +import { checkRedis, redis } from './queue/connection.js' +import { closeQueue } from './queue/client.js' +import { checkWorkerHeartbeat } from './queue/heartbeat.js' +import { checkStorage, closeStorage } from './storage/client.js' + +export interface BuildAppOptions { + billingProvider?: StripeBillingProvider + invitationMailer?: InvitationMailer + publishingAdapters?: PublishingAdapterRegistry + publishingWebhookSecret?: string + providerVerificationFetch?: typeof fetch + providerVerificationConfiguration?: ProviderConfiguration +} + +export async function buildApp(options: BuildAppOptions = {}) { + const app = Fastify({ + logger: { level: config.LOG_LEVEL }, + requestIdHeader: 'x-request-id', + trustProxy: config.NODE_ENV === 'production', + bodyLimit: config.MAX_UPLOAD_BYTES, + }) + + await app.register(helmet, { contentSecurityPolicy: config.NODE_ENV === 'production' }) + await app.register(cors, { + origin: config.WEB_ORIGIN.split(',').map((origin) => origin.trim()), + credentials: true, + methods: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], + }) + await app.register(cookie) + await app.register(sensible) + await app.register(rawBody, { global: false, encoding: false, runFirst: true }) + await app.register(rateLimit, { max: 120, timeWindow: '1 minute' }) + await app.register(multipart, { + limits: { fileSize: config.MAX_UPLOAD_BYTES, files: 8 }, + }) + await app.register(jwt, { secret: config.JWT_ACCESS_SECRET }) + + app.get('/health/live', async () => ({ status: 'ok', service: 'frameflow-api' })) + app.get('/health/ready', async (_request, reply) => { + const checks = await Promise.allSettled([ + db.execute(sql`select 1`), + checkRedis(), + checkStorage(), + checkWorkerHeartbeat(), + ]) + const names = ['postgres', 'redis', 'objectStorage', 'worker'] as const + const dependencies = Object.fromEntries(names.map((name, index) => [name, checks[index]?.status === 'fulfilled' ? 'ok' : 'unavailable'])) + names.forEach((name, index) => applicationDependencyAvailable.set({ dependency: name }, checks[index]?.status === 'fulfilled' ? 1 : 0)) + const ready = checks.every((check) => check.status === 'fulfilled') + return reply.code(ready ? 200 : 503).send({ status: ready ? 'ready' : 'not_ready', dependencies }) + }) + app.get('/metrics', async (request, reply) => { + if (config.METRICS_TOKEN && request.headers.authorization !== `Bearer ${config.METRICS_TOKEN}`) { + return reply.code(401).send({ error: { code: 'UNAUTHORIZED', message: 'Metrics token is missing or invalid' } }) + } + return reply.header('content-type', metricsRegistry.contentType).send(await metricsRegistry.metrics()) + }) + + app.addHook('onResponse', async (request, reply) => { + const labels = { + method: request.method, + route: request.routeOptions.url ?? 'unmatched', + status: String(reply.statusCode), + } + apiRequestsTotal.inc(labels) + apiRequestDurationSeconds.observe(labels, reply.elapsedTime / 1000) + }) + + app.addHook('onClose', async () => { + await Promise.allSettled([closeQueue(), redis.quit()]) + closeStorage() + }) + + app.setNotFoundHandler((request, reply) => { + reply.code(404).send({ error: { code: 'NOT_FOUND', message: `Route ${request.method} ${request.url} not found` } }) + }) + + app.setErrorHandler((error, request, reply) => { + const appError = error as AppError + const businessCodes = new Set(['BAD_REQUEST', 'UNAUTHORIZED', 'EMAIL_VERIFICATION_REQUIRED', 'FORBIDDEN', 'NOT_FOUND', 'CONFLICT', 'CREDIT_LIMIT_EXCEEDED', 'SERVICE_UNAVAILABLE']) + if (error instanceof AppError || appError.name === 'AppError' || businessCodes.has(appError.code)) { + return reply.code(appError.statusCode).send({ + error: { code: appError.code, message: appError.message, details: appError.details }, + requestId: request.id, + }) + } + if (error instanceof ZodError) { + return reply.code(400).send({ + error: { code: 'BAD_REQUEST', message: 'Request validation failed', details: error.issues }, + requestId: request.id, + }) + } + if (typeof error === 'object' && error !== null && 'code' in error && error.code === '23505') { + return reply.code(409).send({ error: { code: 'CONFLICT', message: 'A unique value already exists' }, requestId: request.id }) + } + request.log.error({ err: error }, 'Unhandled request error') + return reply.code(500).send({ error: { code: 'INTERNAL_ERROR', message: 'Unexpected server error' }, requestId: request.id }) + }) + + await app.register(authRoutes, { prefix: '/api/v1/auth' }) + await app.register(workspaceRoutes, { + prefix: '/api/v1/workspaces', + ...(options.invitationMailer ? { invitationMailer: options.invitationMailer } : {}), + }) + await app.register(projectRoutes, { prefix: '/api/v1' }) + await app.register(episodeRoutes, { prefix: '/api/v1' }) + await app.register(assetRoutes, { prefix: '/api/v1' }) + await app.register(shotRoutes, { prefix: '/api/v1' }) + await app.register(uploadRoutes, { prefix: '/api/v1' }) + await app.register(jobRoutes, { prefix: '/api/v1' }) + await app.register(productionRoutes, { + prefix: '/api/v1', + ...(options.publishingAdapters ? { publishingAdapters: options.publishingAdapters } : {}), + }) + await app.register(reviewRoutes, { prefix: '/api/v1' }) + await app.register(billingRoutes, { + prefix: '/api/v1', + ...(options.billingProvider ? { billingProvider: options.billingProvider } : {}), + }) + await app.register(readinessRoutes, { + prefix: '/api/v1', + ...(options.providerVerificationFetch ? { providerVerificationFetch: options.providerVerificationFetch } : {}), + ...(options.providerVerificationConfiguration ? { providerVerificationConfiguration: options.providerVerificationConfiguration } : {}), + }) + await app.register(auditRoutes, { prefix: '/api/v1' }) + await app.register(notificationRoutes, { prefix: '/api/v1' }) + await app.register(publishingRoutes, { + prefix: '/api/v1', + ...(options.publishingAdapters ? { publishingAdapters: options.publishingAdapters } : {}), + ...(options.publishingWebhookSecret ? { publishingWebhookSecret: options.publishingWebhookSecret } : {}), + }) + + return app +} diff --git a/server/src/config-check.ts b/server/src/config-check.ts new file mode 100644 index 0000000..204f75e --- /dev/null +++ b/server/src/config-check.ts @@ -0,0 +1,22 @@ +import { config } from './config.js' + +const replicateCapabilities = [ + config.REPLICATE_IMAGE_VERSION && 'image', + config.REPLICATE_VIDEO_VERSION && 'video', + config.REPLICATE_LIPSYNC_VERSION && 'lipsync', +].filter(Boolean) + +console.log(JSON.stringify({ + status: 'valid', + environment: config.NODE_ENV, + emailDelivery: config.RESEND_API_KEY ? 'configured' : 'disabled', + openai: config.OPENAI_API_KEY ? 'configured' : 'disabled', + agnes: config.AGNES_API_KEY ? ['text', 'image', 'video'] : [], + generic: [ + config.GENERIC_TEXT_API_KEY && config.GENERIC_TEXT_BASE_URL && config.GENERIC_TEXT_MODEL && 'text', + config.GENERIC_IMAGE_API_KEY && config.GENERIC_IMAGE_BASE_URL && config.GENERIC_IMAGE_MODEL && 'image', + config.GENERIC_VIDEO_API_KEY && config.GENERIC_VIDEO_BASE_URL && config.GENERIC_VIDEO_MODEL && 'video', + ].filter(Boolean), + replicate: config.REPLICATE_API_TOKEN ? replicateCapabilities : [], + stripe: config.STRIPE_SECRET_KEY ? 'configured' : 'disabled', +})) diff --git a/server/src/config.test.ts b/server/src/config.test.ts new file mode 100644 index 0000000..a910188 --- /dev/null +++ b/server/src/config.test.ts @@ -0,0 +1,113 @@ +import { describe, expect, it } from 'vitest' +import { parseConfig } from './config.js' + +function productionEnvironment(overrides: NodeJS.ProcessEnv = {}): NodeJS.ProcessEnv { + return { + NODE_ENV: 'production', + WEB_ORIGIN: 'https://studio.frameflow.cn', + API_PUBLIC_ORIGIN: 'https://studio.frameflow.cn', + DATABASE_URL: 'postgresql://frameflow:postgres-password-32-characters@postgres:5432/frameflow', + REDIS_URL: 'redis://default:redis-password-32-characters@redis:6379', + JWT_ACCESS_SECRET: 'access-secret-with-at-least-32-characters', + JWT_REFRESH_SECRET: 'refresh-secret-with-at-least-32-characters', + CREDENTIAL_ENCRYPTION_KEY: 'credential-encryption-secret-with-32-characters', + EMAIL_VERIFICATION_REQUIRED: 'true', + RESEND_API_KEY: 're_live_frameflow_configuration', + EMAIL_FROM: 'FrameFlow ', + S3_ENDPOINT: 'http://minio:9000', + S3_PUBLIC_ENDPOINT: 'https://media.frameflow.cn', + S3_ACCESS_KEY: 'frameflow-production-access', + S3_SECRET_KEY: 'storage-secret-with-at-least-32-characters', + ...overrides, + } +} + +describe('production environment validation', () => { + it('accepts a complete production configuration with optional providers disabled', () => { + const result = parseConfig(productionEnvironment()) + expect(result.NODE_ENV).toBe('production') + expect(result.EMAIL_VERIFICATION_REQUIRED).toBe(true) + expect(result.S3_PUBLIC_ENDPOINT).toBe('https://media.frameflow.cn') + }) + + it('rejects placeholder secrets without exposing their values', () => { + expect(() => parseConfig(productionEnvironment({ + JWT_ACCESS_SECRET: 'replace_with_at_least_32_random_characters_access', + }))).toThrow('JWT_ACCESS_SECRET contains a placeholder value') + }) + + it('requires real HTTPS public origins', () => { + expect(() => parseConfig(productionEnvironment({ + WEB_ORIGIN: 'http://studio.example.com', + S3_PUBLIC_ENDPOINT: 'http://127.0.0.1:9000', + }))).toThrow(/WEB_ORIGIN\[0\] must use HTTPS in production/) + }) + + it('requires the public storage endpoint to be a bare origin', () => { + expect(() => parseConfig(productionEnvironment({ + S3_PUBLIC_ENDPOINT: 'https://media.frameflow.cn/private-path', + }))).toThrow('S3_PUBLIC_ENDPOINT must be an origin') + }) + + it('requires distinct signing secrets', () => { + const sharedSecret = 'shared-signing-secret-with-32-characters' + expect(() => parseConfig(productionEnvironment({ + JWT_ACCESS_SECRET: sharedSecret, + JWT_REFRESH_SECRET: sharedSecret, + }))).toThrow('JWT_ACCESS_SECRET and JWT_REFRESH_SECRET must be different') + }) + + it('rejects Replicate versions without an API token', () => { + expect(() => parseConfig(productionEnvironment({ + REPLICATE_VIDEO_VERSION: 'video-model-version', + }))).toThrow('REPLICATE_API_TOKEN is required') + }) + + it('bounds the Replicate prediction deadline to the provider-supported range', () => { + expect(() => parseConfig(productionEnvironment({ + REPLICATE_PREDICTION_DEADLINE_SECONDS: '4', + }))).toThrow('REPLICATE_PREDICTION_DEADLINE_SECONDS') + expect(() => parseConfig(productionEnvironment({ + REPLICATE_PREDICTION_DEADLINE_SECONDS: '86401', + }))).toThrow('REPLICATE_PREDICTION_DEADLINE_SECONDS') + }) + + it('requires each generic provider capability to be configured as a complete triple', () => { + expect(() => parseConfig(productionEnvironment({ + GENERIC_IMAGE_API_KEY: 'generic-image-secret', + GENERIC_IMAGE_MODEL: 'vendor-image-model', + }))).toThrow('GENERIC_IMAGE requires API_KEY, BASE_URL, and MODEL together') + + const result = parseConfig(productionEnvironment({ + GENERIC_TEXT_API_KEY: 'generic-text-secret', + GENERIC_TEXT_BASE_URL: 'https://text.vendor.cn/v1', + GENERIC_TEXT_MODEL: 'vendor-text-model', + })) + expect(result.GENERIC_TEXT_BASE_URL).toBe('https://text.vendor.cn/v1') + + expect(() => parseConfig(productionEnvironment({ + GENERIC_VIDEO_API_KEY: 'generic-video-secret', + GENERIC_VIDEO_BASE_URL: 'https://video.vendor.cn/v1?route=private', + GENERIC_VIDEO_MODEL: 'vendor-video-model', + }))).toThrow('GENERIC_VIDEO_BASE_URL must not contain credentials, query parameters, or a fragment') + }) + + it('rejects a partially configured Stripe integration', () => { + expect(() => parseConfig(productionEnvironment({ + STRIPE_SECRET_KEY: 'sk_live_frameflow', + STRIPE_WEBHOOK_SECRET: 'whsec_frameflow', + }))).toThrow('Stripe production billing must configure') + }) + + it('requires independent credential encryption and complete publishing connector configuration', () => { + const accessSecret = 'access-secret-with-at-least-32-characters' + expect(() => parseConfig(productionEnvironment({ + JWT_ACCESS_SECRET: accessSecret, + CREDENTIAL_ENCRYPTION_KEY: accessSecret, + }))).toThrow('CREDENTIAL_ENCRYPTION_KEY must be distinct') + + expect(() => parseConfig(productionEnvironment({ + PUBLISHING_CONNECTOR_URL: 'https://publisher.frameflow.cn', + }))).toThrow('Publishing connector must configure') + }) +}) diff --git a/server/src/config.ts b/server/src/config.ts new file mode 100644 index 0000000..ba256e7 --- /dev/null +++ b/server/src/config.ts @@ -0,0 +1,279 @@ +import 'dotenv/config' +import { z } from 'zod' + +const booleanFromEnv = z.preprocess((value) => { + if (typeof value === 'string') return value.toLowerCase() === 'true' + return value +}, z.boolean()) + +const optionalSecret = (minimumLength = 1) => z.preprocess( + (value) => typeof value === 'string' && value.trim() === '' ? undefined : value, + z.string().min(minimumLength).optional(), +) + +const optionalUrl = z.preprocess( + (value) => typeof value === 'string' && value.trim() === '' ? undefined : value, + z.string().url().optional(), +) + +const schema = z.object({ + NODE_ENV: z.enum(['development', 'test', 'production']).default('development'), + API_HOST: z.string().default('127.0.0.1'), + API_PORT: z.coerce.number().int().positive().default(8787), + API_PUBLIC_ORIGIN: z.string().url().default('http://127.0.0.1:8787'), + WEB_ORIGIN: z.string().default('http://127.0.0.1:4173'), + LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent']).default('info'), + METRICS_HOST: z.string().default('127.0.0.1'), + WORKER_METRICS_PORT: z.coerce.number().int().positive().default(9092), + WORKER_HEARTBEAT_KEY: z.string().min(1).default('frameflow:worker:heartbeat'), + WORKER_HEARTBEAT_INTERVAL_MS: z.coerce.number().int().min(1000).default(5000), + WORKER_HEARTBEAT_TTL_SECONDS: z.coerce.number().int().min(5).default(20), + METRICS_TOKEN: optionalSecret(20), + DATABASE_URL: z.string().url().default('postgresql://frameflow:frameflow@127.0.0.1:54329/frameflow'), + REDIS_URL: z.string().url().default('redis://127.0.0.1:63799'), + JWT_ACCESS_SECRET: z.string().min(32).default('local-access-secret-replace-before-prod'), + JWT_REFRESH_SECRET: z.string().min(32).default('local-refresh-secret-replace-before-prod'), + CREDENTIAL_ENCRYPTION_KEY: z.string().min(32).default('local-credential-encryption-key-replace-before-prod'), + ACCESS_TOKEN_TTL: z.string().default('15m'), + REFRESH_TOKEN_TTL_DAYS: z.coerce.number().int().positive().default(30), + EMAIL_VERIFICATION_REQUIRED: booleanFromEnv.optional(), + EMAIL_VERIFICATION_TTL_HOURS: z.coerce.number().int().min(1).max(168).default(24), + PASSWORD_RESET_TTL_MINUTES: z.coerce.number().int().min(5).max(1440).default(30), + RESEND_API_KEY: optionalSecret(), + EMAIL_FROM: z.string().trim().min(3).default('FrameFlow '), + S3_ENDPOINT: z.string().url().default('http://127.0.0.1:9000'), + S3_PUBLIC_ENDPOINT: z.string().url().optional(), + S3_REGION: z.string().default('us-east-1'), + S3_BUCKET: z.string().default('frameflow'), + S3_ACCESS_KEY: z.string().default('frameflow'), + S3_SECRET_KEY: z.string().default('frameflow-local-secret'), + S3_FORCE_PATH_STYLE: booleanFromEnv.default(true), + OPENAI_API_KEY: optionalSecret(), + OPENAI_TEXT_MODEL: z.string().default('gpt-5.6-sol'), + OPENAI_IMAGE_MODEL: z.string().default('gpt-image-2'), + OPENAI_TTS_MODEL: z.string().default('gpt-4o-mini-tts'), + OPENAI_TTS_VOICE: z.string().default('alloy'), + AGNES_API_KEY: optionalSecret(), + AGNES_TEXT_MODEL: z.string().default('agnes-2.5-flash'), + AGNES_IMAGE_MODEL: z.string().default('agnes-image-2.1-flash'), + AGNES_VIDEO_MODEL: z.string().default('agnes-video-v2.0'), + AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS: z.coerce.number().int().min(30).max(86_400).default(900), + AGNES_VIDEO_POLL_INTERVAL_MS: z.coerce.number().int().min(1000).max(60_000).default(4000), + GENERIC_TEXT_API_KEY: optionalSecret(), + GENERIC_TEXT_BASE_URL: optionalUrl, + GENERIC_TEXT_MODEL: optionalSecret(), + GENERIC_IMAGE_API_KEY: optionalSecret(), + GENERIC_IMAGE_BASE_URL: optionalUrl, + GENERIC_IMAGE_MODEL: optionalSecret(), + GENERIC_VIDEO_API_KEY: optionalSecret(), + GENERIC_VIDEO_BASE_URL: optionalUrl, + GENERIC_VIDEO_MODEL: optionalSecret(), + GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS: z.coerce.number().int().min(5).max(86_400).default(900), + GENERIC_VIDEO_POLL_INTERVAL_MS: z.coerce.number().int().min(250).max(60_000).default(4000), + REPLICATE_API_TOKEN: optionalSecret(), + REPLICATE_IMAGE_VERSION: optionalSecret(), + REPLICATE_VIDEO_VERSION: optionalSecret(), + REPLICATE_LIPSYNC_VERSION: optionalSecret(), + REPLICATE_PREDICTION_DEADLINE_SECONDS: z.coerce.number().int().min(5).max(86_400).default(900), + STRIPE_SECRET_KEY: optionalSecret(), + STRIPE_WEBHOOK_SECRET: optionalSecret(), + STRIPE_PRO_PRICE_ID: optionalSecret(), + STRIPE_STUDIO_PRICE_ID: optionalSecret(), + STRIPE_PORTAL_CONFIGURATION_ID: optionalSecret(), + BILLING_SUCCESS_URL: optionalUrl, + BILLING_CANCEL_URL: optionalUrl, + PUBLISHING_CONNECTOR_URL: optionalUrl, + PUBLISHING_CONNECTOR_SECRET: optionalSecret(24), + PUBLISHING_CONNECTOR_TIMEOUT_MS: z.coerce.number().int().min(1000).max(120_000).default(30_000), + FFMPEG_PATH: z.string().default('ffmpeg'), + FFPROBE_PATH: z.string().default('ffprobe'), + WORKER_CONCURRENCY: z.coerce.number().int().positive().max(20).default(2), + MAX_UPLOAD_BYTES: z.coerce.number().int().positive().default(100 * 1024 * 1024), + PROVIDER_DOWNLOAD_TIMEOUT_MS: z.coerce.number().int().min(1000).max(600_000).default(180_000), + PROVIDER_DOWNLOAD_MAX_REDIRECTS: z.coerce.number().int().min(0).max(10).default(3), +}) + +type ParsedConfig = z.infer + +function parseUrl(name: string, value: string, issues: string[]) { + try { + return new URL(value) + } catch { + issues.push(`${name} must be a valid URL`) + return null + } +} + +function isLocalHostname(hostname: string) { + const normalized = hostname.toLowerCase() + return normalized === 'localhost' + || normalized === '127.0.0.1' + || normalized === '0.0.0.0' + || normalized === '::1' +} + +function isDocumentationHostname(hostname: string) { + const normalized = hostname.toLowerCase() + return normalized === 'example.com' || normalized.endsWith('.example.com') +} + +function looksLikePlaceholder(value: string) { + const normalized = value.trim().toLowerCase() + return normalized.startsWith('replace_') + || normalized.startsWith('replace-') + || normalized.includes('replace-before-prod') + || normalized.includes('change-me') + || normalized.includes('changeme') + || normalized === 'frameflow-local-secret' +} + +function validateOrigin(name: string, value: string, issues: string[]) { + const url = parseUrl(name, value, issues) + if (!url) return + if (url.protocol !== 'https:') issues.push(`${name} must use HTTPS in production`) + if (isLocalHostname(url.hostname) || isDocumentationHostname(url.hostname)) { + issues.push(`${name} must use a real public hostname in production`) + } + if (url.username || url.password || url.pathname !== '/' || url.search || url.hash) { + issues.push(`${name} must be an origin without credentials, path, query, or fragment`) + } +} + +function validatePublicUrl(name: string, value: string | undefined, issues: string[], required = false) { + if (!value) { + if (required) issues.push(`${name} is required in production`) + return + } + const url = parseUrl(name, value, issues) + if (!url) return + if (url.protocol !== 'https:') issues.push(`${name} must use HTTPS in production`) + if (isLocalHostname(url.hostname) || isDocumentationHostname(url.hostname)) { + issues.push(`${name} must use a real public hostname in production`) + } +} + +function validateProviderBaseUrl(name: string, value: string, issues: string[]) { + validatePublicUrl(name, value, issues, true) + const url = parseUrl(name, value, issues) + if (!url) return + if (url.username || url.password || url.search || url.hash) { + issues.push(`${name} must not contain credentials, query parameters, or a fragment`) + } +} + +function validateServiceUrl(name: string, value: string, protocols: string[], issues: string[]) { + const url = parseUrl(name, value, issues) + if (!url) return + if (!protocols.includes(url.protocol)) issues.push(`${name} must use ${protocols.join(' or ')}`) + if (isLocalHostname(url.hostname)) issues.push(`${name} must not target localhost in production`) + if (!url.username) issues.push(`${name} must include a username in production`) + if (!url.password) issues.push(`${name} must include authentication credentials in production`) + if (looksLikePlaceholder(url.password)) issues.push(`${name} contains a placeholder password`) +} + +function validateProductionConfiguration(data: ParsedConfig) { + const issues: string[] = [] + const origins = data.WEB_ORIGIN.split(',').map((origin) => origin.trim()).filter(Boolean) + if (origins.length === 0) issues.push('WEB_ORIGIN must include at least one origin') + origins.forEach((origin, index) => validateOrigin(`WEB_ORIGIN[${index}]`, origin, issues)) + validateOrigin('API_PUBLIC_ORIGIN', data.API_PUBLIC_ORIGIN, issues) + + validateServiceUrl('DATABASE_URL', data.DATABASE_URL, ['postgres:', 'postgresql:'], issues) + validateServiceUrl('REDIS_URL', data.REDIS_URL, ['redis:', 'rediss:'], issues) + if (data.S3_PUBLIC_ENDPOINT) validateOrigin('S3_PUBLIC_ENDPOINT', data.S3_PUBLIC_ENDPOINT, issues) + else issues.push('S3_PUBLIC_ENDPOINT is required in production') + validatePublicUrl('BILLING_SUCCESS_URL', data.BILLING_SUCCESS_URL, issues) + validatePublicUrl('BILLING_CANCEL_URL', data.BILLING_CANCEL_URL, issues) + + const storageEndpoint = parseUrl('S3_ENDPOINT', data.S3_ENDPOINT, issues) + if (storageEndpoint) { + if (!['http:', 'https:'].includes(storageEndpoint.protocol)) issues.push('S3_ENDPOINT must use http: or https:') + if (isLocalHostname(storageEndpoint.hostname)) issues.push('S3_ENDPOINT must not target localhost in production') + } + + const secretValues: Array<[string, string | undefined]> = [ + ['JWT_ACCESS_SECRET', data.JWT_ACCESS_SECRET], + ['JWT_REFRESH_SECRET', data.JWT_REFRESH_SECRET], + ['CREDENTIAL_ENCRYPTION_KEY', data.CREDENTIAL_ENCRYPTION_KEY], + ['S3_ACCESS_KEY', data.S3_ACCESS_KEY], + ['S3_SECRET_KEY', data.S3_SECRET_KEY], + ['RESEND_API_KEY', data.RESEND_API_KEY], + ['OPENAI_API_KEY', data.OPENAI_API_KEY], + ['AGNES_API_KEY', data.AGNES_API_KEY], + ['GENERIC_TEXT_API_KEY', data.GENERIC_TEXT_API_KEY], + ['GENERIC_IMAGE_API_KEY', data.GENERIC_IMAGE_API_KEY], + ['GENERIC_VIDEO_API_KEY', data.GENERIC_VIDEO_API_KEY], + ['REPLICATE_API_TOKEN', data.REPLICATE_API_TOKEN], + ['STRIPE_SECRET_KEY', data.STRIPE_SECRET_KEY], + ['STRIPE_WEBHOOK_SECRET', data.STRIPE_WEBHOOK_SECRET], + ['STRIPE_PRO_PRICE_ID', data.STRIPE_PRO_PRICE_ID], + ['STRIPE_STUDIO_PRICE_ID', data.STRIPE_STUDIO_PRICE_ID], + ['PUBLISHING_CONNECTOR_SECRET', data.PUBLISHING_CONNECTOR_SECRET], + ] + secretValues.forEach(([name, value]) => { + if (value && looksLikePlaceholder(value)) issues.push(`${name} contains a placeholder value`) + }) + if (data.JWT_ACCESS_SECRET === data.JWT_REFRESH_SECRET) { + issues.push('JWT_ACCESS_SECRET and JWT_REFRESH_SECRET must be different') + } + if (data.CREDENTIAL_ENCRYPTION_KEY === data.JWT_ACCESS_SECRET || data.CREDENTIAL_ENCRYPTION_KEY === data.JWT_REFRESH_SECRET) { + issues.push('CREDENTIAL_ENCRYPTION_KEY must be distinct from JWT signing secrets') + } + if (data.S3_SECRET_KEY.length < 16) issues.push('S3_SECRET_KEY must contain at least 16 characters in production') + + const emailVerificationRequired = data.EMAIL_VERIFICATION_REQUIRED ?? true + if (emailVerificationRequired && !data.RESEND_API_KEY) { + issues.push('RESEND_API_KEY is required when production email verification is enabled') + } + if (data.RESEND_API_KEY && (/frameflow\.local/i.test(data.EMAIL_FROM) || /@example\.com/i.test(data.EMAIL_FROM))) { + issues.push('EMAIL_FROM must use a verified non-placeholder sender in production') + } + + const replicateVersions = [data.REPLICATE_IMAGE_VERSION, data.REPLICATE_VIDEO_VERSION, data.REPLICATE_LIPSYNC_VERSION] + if (replicateVersions.some(Boolean) && !data.REPLICATE_API_TOKEN) { + issues.push('REPLICATE_API_TOKEN is required when a Replicate model version is configured') + } + + const genericCapabilities = [ + ['GENERIC_TEXT', data.GENERIC_TEXT_API_KEY, data.GENERIC_TEXT_BASE_URL, data.GENERIC_TEXT_MODEL], + ['GENERIC_IMAGE', data.GENERIC_IMAGE_API_KEY, data.GENERIC_IMAGE_BASE_URL, data.GENERIC_IMAGE_MODEL], + ['GENERIC_VIDEO', data.GENERIC_VIDEO_API_KEY, data.GENERIC_VIDEO_BASE_URL, data.GENERIC_VIDEO_MODEL], + ] as const + for (const [name, apiKey, baseUrl, model] of genericCapabilities) { + const values = [apiKey, baseUrl, model] + if (values.some(Boolean) && values.some((value) => !value)) { + issues.push(`${name} requires API_KEY, BASE_URL, and MODEL together`) + } + if (baseUrl) validateProviderBaseUrl(`${name}_BASE_URL`, baseUrl, issues) + } + + const stripeValues = [data.STRIPE_SECRET_KEY, data.STRIPE_WEBHOOK_SECRET, data.STRIPE_PRO_PRICE_ID, data.STRIPE_STUDIO_PRICE_ID] + if (stripeValues.some(Boolean) && stripeValues.some((value) => !value)) { + issues.push('Stripe production billing must configure STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRO_PRICE_ID, and STRIPE_STUDIO_PRICE_ID together') + } + + const publishingConnectorValues = [data.PUBLISHING_CONNECTOR_URL, data.PUBLISHING_CONNECTOR_SECRET] + if (publishingConnectorValues.some(Boolean) && publishingConnectorValues.some((value) => !value)) { + issues.push('Publishing connector must configure PUBLISHING_CONNECTOR_URL and PUBLISHING_CONNECTOR_SECRET together') + } + if (data.PUBLISHING_CONNECTOR_URL) { + validatePublicUrl('PUBLISHING_CONNECTOR_URL', data.PUBLISHING_CONNECTOR_URL, issues, true) + } + + if (issues.length > 0) throw new Error(`Unsafe production environment configuration:\n${issues.join('\n')}`) +} + +export function parseConfig(environment: NodeJS.ProcessEnv) { + const parsed = schema.safeParse(environment) + if (!parsed.success) { + const details = parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('\n') + throw new Error(`Invalid environment configuration:\n${details}`) + } + + if (parsed.data.NODE_ENV === 'production') validateProductionConfiguration(parsed.data) + const emailVerificationRequired = parsed.data.EMAIL_VERIFICATION_REQUIRED ?? parsed.data.NODE_ENV === 'production' + return { ...parsed.data, EMAIL_VERIFICATION_REQUIRED: emailVerificationRequired } +} + +export const config = parseConfig(process.env) +export type Config = typeof config diff --git a/server/src/db/client.ts b/server/src/db/client.ts new file mode 100644 index 0000000..57a93a4 --- /dev/null +++ b/server/src/db/client.ts @@ -0,0 +1,17 @@ +import { drizzle } from 'drizzle-orm/postgres-js' +import postgres from 'postgres' +import { config } from '../config.js' +import * as schema from './schema.js' + +export const sqlClient = postgres(config.DATABASE_URL, { + max: config.NODE_ENV === 'test' ? 2 : 10, + idle_timeout: 20, + connect_timeout: 10, + prepare: false, +}) + +export const db = drizzle(sqlClient, { schema }) + +export async function closeDatabase() { + await sqlClient.end({ timeout: 5 }) +} diff --git a/server/src/db/migrate.ts b/server/src/db/migrate.ts new file mode 100644 index 0000000..a93c3b9 --- /dev/null +++ b/server/src/db/migrate.ts @@ -0,0 +1,9 @@ +import { migrate } from 'drizzle-orm/postgres-js/migrator' +import { closeDatabase, db } from './client.js' + +try { + await migrate(db, { migrationsFolder: new URL('../../drizzle', import.meta.url).pathname }) + console.info('Database migrations applied') +} finally { + await closeDatabase() +} diff --git a/server/src/db/schema.ts b/server/src/db/schema.ts new file mode 100644 index 0000000..2a2b5ce --- /dev/null +++ b/server/src/db/schema.ts @@ -0,0 +1,566 @@ +import { + boolean, + index, + integer, + jsonb, + numeric, + pgEnum, + pgTable, + primaryKey, + text, + timestamp, + uniqueIndex, + uuid, + varchar, +} from 'drizzle-orm/pg-core' + +const timestamps = { + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(), +} + +export const membershipRole = pgEnum('membership_role', [ + 'OWNER', + 'ADMIN', + 'EDITOR', + 'REVIEWER', + 'VIEWER', +]) +export const projectStatus = pgEnum('project_status', ['DRAFT', 'ACTIVE', 'ARCHIVED']) +export const episodeStatus = pgEnum('episode_status', [ + 'OUTLINE', + 'SCRIPTING', + 'STORYBOARDING', + 'PRODUCTION', + 'REVIEW', + 'PUBLISHED', +]) +export const assetType = pgEnum('asset_type', ['CHARACTER', 'SCENE', 'PROP', 'VOICE', 'MUSIC', 'SHOT']) +export const assetStatus = pgEnum('asset_status', ['DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'ARCHIVED']) +export const shotStatus = pgEnum('shot_status', ['DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'RENDERED']) +export const jobType = pgEnum('job_type', [ + 'PIPELINE_HEALTHCHECK', + 'SCRIPT_GENERATE', + 'STORYBOARD_GENERATE', + 'ASSET_GENERATE', + 'TTS_GENERATE', + 'VIDEO_GENERATE', + 'LIPSYNC_GENERATE', + 'EPISODE_RENDER', + 'DELIVERY_PUBLISH', +]) +export const jobStatus = pgEnum('job_status', ['QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED']) +export const productionRunStatus = pgEnum('production_run_status', ['QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED']) +export const reviewStatus = pgEnum('review_status', ['OPEN', 'APPROVED', 'CHANGES_REQUESTED', 'CANCELLED']) +export const reviewTargetType = pgEnum('review_target_type', ['SCRIPT_VERSION', 'ASSET_VERSION', 'SHOT_VERSION', 'RENDER']) +export const renderStatus = pgEnum('render_status', ['QUEUED', 'RENDERING', 'REVIEW', 'APPROVED', 'FAILED']) +export const deliveryStatus = pgEnum('delivery_status', ['DRAFT', 'QUEUED', 'PUBLISHING', 'PUBLISHED', 'FAILED', 'CANCELLED']) +export const accountTokenType = pgEnum('account_token_type', ['EMAIL_VERIFICATION', 'PASSWORD_RESET']) +export const usageKind = pgEnum('usage_kind', [ + 'TEXT_INPUT_TOKEN', + 'TEXT_OUTPUT_TOKEN', + 'IMAGE', + 'AUDIO_SECOND', + 'VIDEO_SECOND', + 'RENDER_SECOND', + 'STORAGE_BYTE_MONTH', +]) +export const notificationTone = pgEnum('notification_tone', ['INFO', 'SUCCESS', 'WARNING', 'ERROR']) +export const publishingChannelStatus = pgEnum('publishing_channel_status', ['CONNECTED', 'EXPIRED', 'REVOKED', 'ERROR']) + +export const users = pgTable('users', { + id: uuid('id').defaultRandom().primaryKey(), + email: varchar('email', { length: 320 }).notNull(), + displayName: varchar('display_name', { length: 120 }).notNull(), + passwordHash: text('password_hash').notNull(), + avatarKey: text('avatar_key'), + emailVerifiedAt: timestamp('email_verified_at', { withTimezone: true }), + disabledAt: timestamp('disabled_at', { withTimezone: true }), + ...timestamps, +}, (table) => [uniqueIndex('users_email_unique').on(table.email)]) + +export const workspaces = pgTable('workspaces', { + id: uuid('id').defaultRandom().primaryKey(), + name: varchar('name', { length: 160 }).notNull(), + slug: varchar('slug', { length: 80 }).notNull(), + ownerId: uuid('owner_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + plan: varchar('plan', { length: 32 }).default('PRO').notNull(), + monthlyCreditLimit: integer('monthly_credit_limit').default(10000).notNull(), + settings: jsonb('settings').$type>().default({}).notNull(), + ...timestamps, +}, (table) => [uniqueIndex('workspaces_slug_unique').on(table.slug), index('workspaces_owner_idx').on(table.ownerId)]) + +export const billingSubscriptions = pgTable('billing_subscriptions', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + provider: varchar('provider', { length: 32 }).default('stripe').notNull(), + customerId: varchar('customer_id', { length: 255 }).notNull(), + subscriptionId: varchar('subscription_id', { length: 255 }), + priceId: varchar('price_id', { length: 255 }), + plan: varchar('plan', { length: 32 }), + status: varchar('status', { length: 48 }).default('no_subscription').notNull(), + currentPeriodEnd: timestamp('current_period_end', { withTimezone: true }), + cancelAtPeriodEnd: boolean('cancel_at_period_end').default(false).notNull(), + lastEventCreatedAt: timestamp('last_event_created_at', { withTimezone: true }), + ...timestamps, +}, (table) => [ + uniqueIndex('billing_subscriptions_workspace_unique').on(table.workspaceId), + uniqueIndex('billing_subscriptions_customer_unique').on(table.customerId), + uniqueIndex('billing_subscriptions_subscription_unique').on(table.subscriptionId), + index('billing_subscriptions_status_idx').on(table.status), +]) + +export const billingWebhookEvents = pgTable('billing_webhook_events', { + eventId: varchar('event_id', { length: 255 }).primaryKey(), + provider: varchar('provider', { length: 32 }).default('stripe').notNull(), + eventType: varchar('event_type', { length: 160 }).notNull(), + livemode: boolean('livemode').default(false).notNull(), + workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'set null' }), + providerCreatedAt: timestamp('provider_created_at', { withTimezone: true }).notNull(), + processedAt: timestamp('processed_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + index('billing_webhook_events_workspace_idx').on(table.workspaceId, table.processedAt), + index('billing_webhook_events_type_idx').on(table.eventType), +]) + +export const memberships = pgTable('memberships', { + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + role: membershipRole('role').default('VIEWER').notNull(), + invitedById: uuid('invited_by_id').references(() => users.id, { onDelete: 'set null' }), + joinedAt: timestamp('joined_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + primaryKey({ columns: [table.workspaceId, table.userId] }), + index('memberships_user_idx').on(table.userId), +]) + +export const providerVerifications = pgTable('provider_verifications', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + provider: varchar('provider', { length: 32 }).$type<'openai' | 'replicate' | 'agnes' | 'generic'>().notNull(), + status: varchar('status', { length: 32 }).$type<'VERIFIED' | 'FAILED'>().notNull(), + configurationFingerprint: varchar('configuration_fingerprint', { length: 64 }).notNull(), + checkedAt: timestamp('checked_at', { withTimezone: true }).defaultNow().notNull(), + latencyMs: integer('latency_ms'), + errorCode: varchar('error_code', { length: 80 }), + message: text('message'), + details: jsonb('details').$type>().default({}).notNull(), + checkedById: uuid('checked_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [ + uniqueIndex('provider_verifications_workspace_provider_unique').on(table.workspaceId, table.provider), + index('provider_verifications_workspace_status_idx').on(table.workspaceId, table.status), +]) + +export const workspaceInvitations = pgTable('workspace_invitations', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + email: varchar('email', { length: 320 }).notNull(), + role: membershipRole('role').default('VIEWER').notNull(), + tokenHash: text('token_hash').notNull(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + acceptedAt: timestamp('accepted_at', { withTimezone: true }), + acceptedById: uuid('accepted_by_id').references(() => users.id, { onDelete: 'set null' }), + revokedAt: timestamp('revoked_at', { withTimezone: true }), + invitedById: uuid('invited_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [ + uniqueIndex('workspace_invitations_token_hash_unique').on(table.tokenHash), + index('workspace_invitations_workspace_email_idx').on(table.workspaceId, table.email), + index('workspace_invitations_workspace_created_idx').on(table.workspaceId, table.createdAt), +]) + +export const refreshTokens = pgTable('refresh_tokens', { + id: uuid('id').defaultRandom().primaryKey(), + userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + tokenHash: text('token_hash').notNull(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + revokedAt: timestamp('revoked_at', { withTimezone: true }), + replacedById: uuid('replaced_by_id'), + userAgent: text('user_agent'), + ipAddress: varchar('ip_address', { length: 64 }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [uniqueIndex('refresh_tokens_hash_unique').on(table.tokenHash), index('refresh_tokens_user_idx').on(table.userId)]) + +export const accountActionTokens = pgTable('account_action_tokens', { + id: uuid('id').defaultRandom().primaryKey(), + userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + type: accountTokenType('type').notNull(), + tokenHash: text('token_hash').notNull(), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + consumedAt: timestamp('consumed_at', { withTimezone: true }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + uniqueIndex('account_action_tokens_hash_unique').on(table.tokenHash), + index('account_action_tokens_user_type_idx').on(table.userId, table.type), + index('account_action_tokens_expiry_idx').on(table.expiresAt), +]) + +export const projects = pgTable('projects', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + name: varchar('name', { length: 180 }).notNull(), + slug: varchar('slug', { length: 100 }).notNull(), + logline: text('logline').default('').notNull(), + genre: varchar('genre', { length: 80 }).default('都市悬疑').notNull(), + visualBible: jsonb('visual_bible').$type>().default({}).notNull(), + status: projectStatus('status').default('DRAFT').notNull(), + ...timestamps, +}, (table) => [ + uniqueIndex('projects_workspace_slug_unique').on(table.workspaceId, table.slug), + index('projects_workspace_idx').on(table.workspaceId), +]) + +export const episodes = pgTable('episodes', { + id: uuid('id').defaultRandom().primaryKey(), + projectId: uuid('project_id').notNull().references(() => projects.id, { onDelete: 'cascade' }), + episodeNumber: integer('episode_number').notNull(), + title: varchar('title', { length: 200 }).notNull(), + synopsis: text('synopsis').default('').notNull(), + targetDurationSeconds: integer('target_duration_seconds').default(180).notNull(), + status: episodeStatus('status').default('OUTLINE').notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [ + uniqueIndex('episodes_project_number_unique').on(table.projectId, table.episodeNumber), + index('episodes_project_idx').on(table.projectId), +]) + +export const scriptVersions = pgTable('script_versions', { + id: uuid('id').defaultRandom().primaryKey(), + episodeId: uuid('episode_id').notNull().references(() => episodes.id, { onDelete: 'cascade' }), + version: integer('version').notNull(), + title: varchar('title', { length: 200 }).notNull(), + content: jsonb('content').$type>().notNull(), + plainText: text('plain_text').default('').notNull(), + changeSummary: text('change_summary').default('').notNull(), + isCurrent: boolean('is_current').default(false).notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + uniqueIndex('script_versions_episode_version_unique').on(table.episodeId, table.version), + index('script_versions_episode_current_idx').on(table.episodeId, table.isCurrent), +]) + +export const assets = pgTable('assets', { + id: uuid('id').defaultRandom().primaryKey(), + projectId: uuid('project_id').notNull().references(() => projects.id, { onDelete: 'cascade' }), + type: assetType('type').notNull(), + name: varchar('name', { length: 180 }).notNull(), + description: text('description').default('').notNull(), + status: assetStatus('status').default('DRAFT').notNull(), + tags: jsonb('tags').$type().default([]).notNull(), + metadata: jsonb('metadata').$type>().default({}).notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [index('assets_project_type_idx').on(table.projectId, table.type), index('assets_project_status_idx').on(table.projectId, table.status)]) + +export const assetVersions = pgTable('asset_versions', { + id: uuid('id').defaultRandom().primaryKey(), + assetId: uuid('asset_id').notNull().references(() => assets.id, { onDelete: 'cascade' }), + version: integer('version').notNull(), + storageKey: text('storage_key'), + thumbnailKey: text('thumbnail_key'), + mimeType: varchar('mime_type', { length: 120 }), + byteSize: integer('byte_size'), + width: integer('width'), + height: integer('height'), + durationMs: integer('duration_ms'), + prompt: text('prompt').default('').notNull(), + negativePrompt: text('negative_prompt').default('').notNull(), + provider: varchar('provider', { length: 80 }), + providerModel: varchar('provider_model', { length: 160 }), + seed: varchar('seed', { length: 80 }), + generationParams: jsonb('generation_params').$type>().default({}).notNull(), + isCurrent: boolean('is_current').default(false).notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + uniqueIndex('asset_versions_asset_version_unique').on(table.assetId, table.version), + index('asset_versions_current_idx').on(table.assetId, table.isCurrent), +]) + +export const shots = pgTable('shots', { + id: uuid('id').defaultRandom().primaryKey(), + episodeId: uuid('episode_id').notNull().references(() => episodes.id, { onDelete: 'cascade' }), + shotNumber: integer('shot_number').notNull(), + sceneNumber: integer('scene_number').notNull(), + title: varchar('title', { length: 180 }).notNull(), + description: text('description').default('').notNull(), + shotType: varchar('shot_type', { length: 50 }).default('中景').notNull(), + cameraMotion: varchar('camera_motion', { length: 50 }).default('静止').notNull(), + durationMs: integer('duration_ms').default(3000).notNull(), + status: shotStatus('status').default('DRAFT').notNull(), + characterAssetIds: jsonb('character_asset_ids').$type().default([]).notNull(), + sceneAssetId: uuid('scene_asset_id').references(() => assets.id, { onDelete: 'set null' }), + sortOrder: integer('sort_order').notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [ + uniqueIndex('shots_episode_number_unique').on(table.episodeId, table.shotNumber), + index('shots_episode_sort_idx').on(table.episodeId, table.sortOrder), +]) + +export const shotVersions = pgTable('shot_versions', { + id: uuid('id').defaultRandom().primaryKey(), + shotId: uuid('shot_id').notNull().references(() => shots.id, { onDelete: 'cascade' }), + version: integer('version').notNull(), + imageAssetVersionId: uuid('image_asset_version_id').references(() => assetVersions.id, { onDelete: 'set null' }), + videoStorageKey: text('video_storage_key'), + audioStorageKey: text('audio_storage_key'), + subtitleText: text('subtitle_text').default('').notNull(), + generationParams: jsonb('generation_params').$type>().default({}).notNull(), + isCurrent: boolean('is_current').default(false).notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [uniqueIndex('shot_versions_shot_version_unique').on(table.shotId, table.version), index('shot_versions_current_idx').on(table.shotId, table.isCurrent)]) + +export interface RenderSourceManifest { + schemaVersion: 1 + capturedAt: string + shots: Array<{ + shotId: string + shotVersionId: string + shotNumber: number + shotVersion: number + sortOrder: number + durationMs: number + subtitleText: string + imageAssetVersionId: string | null + }> +} + +export const renders = pgTable('renders', { + id: uuid('id').defaultRandom().primaryKey(), + episodeId: uuid('episode_id').notNull().references(() => episodes.id, { onDelete: 'cascade' }), + version: integer('version').notNull(), + status: renderStatus('status').default('QUEUED').notNull(), + storageKey: text('storage_key'), + thumbnailKey: text('thumbnail_key'), + subtitleSrtKey: text('subtitle_srt_key'), + subtitleVttKey: text('subtitle_vtt_key'), + mimeType: varchar('mime_type', { length: 120 }).default('video/mp4').notNull(), + byteSize: integer('byte_size'), + durationMs: integer('duration_ms'), + width: integer('width').notNull(), + height: integer('height').notNull(), + fps: integer('fps').default(24).notNull(), + settings: jsonb('settings').$type>().default({}).notNull(), + sourceManifest: jsonb('source_manifest').$type(), + qualityReport: jsonb('quality_report').$type>(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + ...timestamps, +}, (table) => [uniqueIndex('renders_episode_version_unique').on(table.episodeId, table.version), index('renders_episode_status_idx').on(table.episodeId, table.status)]) + +export const publishingChannelAccounts = pgTable('publishing_channel_accounts', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + platform: varchar('platform', { length: 32 }).notNull(), + externalAccountId: varchar('external_account_id', { length: 255 }).notNull(), + displayName: varchar('display_name', { length: 180 }).notNull(), + avatarUrl: text('avatar_url'), + status: publishingChannelStatus('status').default('CONNECTED').notNull(), + accessTokenCiphertext: text('access_token_ciphertext'), + refreshTokenCiphertext: text('refresh_token_ciphertext'), + tokenExpiresAt: timestamp('token_expires_at', { withTimezone: true }), + scopes: jsonb('scopes').$type().default([]).notNull(), + metadata: jsonb('metadata').$type>().default({}).notNull(), + connectedById: uuid('connected_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + lastVerifiedAt: timestamp('last_verified_at', { withTimezone: true }).defaultNow().notNull(), + errorCode: varchar('error_code', { length: 100 }), + errorMessage: text('error_message'), + ...timestamps, +}, (table) => [ + uniqueIndex('publishing_channel_accounts_external_unique').on(table.workspaceId, table.platform, table.externalAccountId), + index('publishing_channel_accounts_workspace_idx').on(table.workspaceId, table.platform), + index('publishing_channel_accounts_status_idx').on(table.workspaceId, table.status), +]) + +export const publishingOauthStates = pgTable('publishing_oauth_states', { + stateHash: varchar('state_hash', { length: 64 }).primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + platform: varchar('platform', { length: 32 }).notNull(), + codeVerifierCiphertext: text('code_verifier_ciphertext'), + returnPath: text('return_path').default('/?publishing=connected').notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(), + consumedAt: timestamp('consumed_at', { withTimezone: true }), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + index('publishing_oauth_states_expiry_idx').on(table.expiresAt), + index('publishing_oauth_states_workspace_idx').on(table.workspaceId, table.platform), +]) + +export const productionRuns = pgTable('production_runs', { + id: uuid('id').defaultRandom().primaryKey(), + episodeId: uuid('episode_id').notNull().references(() => episodes.id, { onDelete: 'cascade' }), + renderId: uuid('render_id').notNull().references(() => renders.id, { onDelete: 'cascade' }), + status: productionRunStatus('status').default('QUEUED').notNull(), + settings: jsonb('settings').$type>().default({}).notNull(), + totalJobs: integer('total_jobs').notNull(), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + startedAt: timestamp('started_at', { withTimezone: true }), + completedAt: timestamp('completed_at', { withTimezone: true }), + ...timestamps, +}, (table) => [ + uniqueIndex('production_runs_render_unique').on(table.renderId), + index('production_runs_episode_status_idx').on(table.episodeId, table.status), + index('production_runs_episode_created_idx').on(table.episodeId, table.createdAt), +]) + +export const generationJobs = pgTable('generation_jobs', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + projectId: uuid('project_id').references(() => projects.id, { onDelete: 'cascade' }), + episodeId: uuid('episode_id').references(() => episodes.id, { onDelete: 'cascade' }), + productionRunId: uuid('production_run_id').references(() => productionRuns.id, { onDelete: 'set null' }), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + type: jobType('type').notNull(), + status: jobStatus('status').default('QUEUED').notNull(), + progress: integer('progress').default(0).notNull(), + provider: varchar('provider', { length: 80 }), + providerModel: varchar('provider_model', { length: 160 }), + externalId: varchar('external_id', { length: 255 }), + idempotencyKey: varchar('idempotency_key', { length: 180 }).notNull(), + input: jsonb('input').$type>().notNull(), + output: jsonb('output').$type>(), + errorCode: varchar('error_code', { length: 100 }), + errorMessage: text('error_message'), + attempts: integer('attempts').default(0).notNull(), + maxAttempts: integer('max_attempts').default(3).notNull(), + estimatedCredits: numeric('estimated_credits', { precision: 20, scale: 4 }).default('0').notNull(), + startedAt: timestamp('started_at', { withTimezone: true }), + completedAt: timestamp('completed_at', { withTimezone: true }), + ...timestamps, +}, (table) => [ + uniqueIndex('generation_jobs_idempotency_unique').on(table.workspaceId, table.idempotencyKey), + index('generation_jobs_workspace_status_idx').on(table.workspaceId, table.status), + index('generation_jobs_project_idx').on(table.projectId), + index('generation_jobs_production_run_idx').on(table.productionRunId), +]) + +export const reviewRequests = pgTable('review_requests', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + targetType: reviewTargetType('target_type').notNull(), + targetId: uuid('target_id').notNull(), + status: reviewStatus('status').default('OPEN').notNull(), + requestedById: uuid('requested_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + assignedToId: uuid('assigned_to_id').references(() => users.id, { onDelete: 'set null' }), + resolvedById: uuid('resolved_by_id').references(() => users.id, { onDelete: 'set null' }), + summary: text('summary').default('').notNull(), + resolvedAt: timestamp('resolved_at', { withTimezone: true }), + ...timestamps, +}, (table) => [index('review_requests_workspace_status_idx').on(table.workspaceId, table.status), index('review_requests_target_idx').on(table.targetType, table.targetId)]) + +export const reviewComments = pgTable('review_comments', { + id: uuid('id').defaultRandom().primaryKey(), + reviewRequestId: uuid('review_request_id').notNull().references(() => reviewRequests.id, { onDelete: 'cascade' }), + authorId: uuid('author_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + body: text('body').notNull(), + timecodeMs: integer('timecode_ms'), + metadata: jsonb('metadata').$type>().default({}).notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [index('review_comments_request_idx').on(table.reviewRequestId)]) + +export const deliveries = pgTable('deliveries', { + id: uuid('id').defaultRandom().primaryKey(), + renderId: uuid('render_id').notNull().references(() => renders.id, { onDelete: 'cascade' }), + jobId: uuid('job_id').references(() => generationJobs.id, { onDelete: 'set null' }), + channelAccountId: uuid('channel_account_id').references(() => publishingChannelAccounts.id, { onDelete: 'cascade' }), + platform: varchar('platform', { length: 80 }).notNull(), + status: deliveryStatus('status').default('DRAFT').notNull(), + destination: jsonb('destination').$type>().default({}).notNull(), + externalId: varchar('external_id', { length: 255 }), + publishedUrl: text('published_url'), + scheduledAt: timestamp('scheduled_at', { withTimezone: true }), + publishedAt: timestamp('published_at', { withTimezone: true }), + lastProviderEventAt: timestamp('last_provider_event_at', { withTimezone: true }), + createdById: uuid('created_by_id').notNull().references(() => users.id, { onDelete: 'restrict' }), + errorMessage: text('error_message'), + ...timestamps, +}, (table) => [ + index('deliveries_render_idx').on(table.renderId), + index('deliveries_job_idx').on(table.jobId), + index('deliveries_channel_account_idx').on(table.channelAccountId), + index('deliveries_status_idx').on(table.status), +]) + +export const publishingWebhookEvents = pgTable('publishing_webhook_events', { + eventKey: varchar('event_key', { length: 320 }).primaryKey(), + eventId: varchar('event_id', { length: 255 }).notNull(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + platform: varchar('platform', { length: 32 }).notNull(), + deliveryId: uuid('delivery_id').references(() => deliveries.id, { onDelete: 'set null' }), + status: varchar('status', { length: 32 }).notNull(), + providerOccurredAt: timestamp('provider_occurred_at', { withTimezone: true }).notNull(), + payload: jsonb('payload').$type>().default({}).notNull(), + applied: boolean('applied').default(false).notNull(), + processedAt: timestamp('processed_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [ + index('publishing_webhook_events_delivery_idx').on(table.deliveryId, table.providerOccurredAt), + index('publishing_webhook_events_workspace_idx').on(table.workspaceId, table.processedAt), + index('publishing_webhook_events_platform_idx').on(table.platform, table.processedAt), +]) + +export const usageLedger = pgTable('usage_ledger', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + userId: uuid('user_id').references(() => users.id, { onDelete: 'set null' }), + jobId: uuid('job_id').references(() => generationJobs.id, { onDelete: 'set null' }), + kind: usageKind('kind').notNull(), + quantity: numeric('quantity', { precision: 20, scale: 4 }).notNull(), + credits: numeric('credits', { precision: 20, scale: 4 }).notNull(), + providerCostUsd: numeric('provider_cost_usd', { precision: 20, scale: 6 }), + metadata: jsonb('metadata').$type>().default({}).notNull(), + occurredAt: timestamp('occurred_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [index('usage_ledger_workspace_time_idx').on(table.workspaceId, table.occurredAt), index('usage_ledger_job_idx').on(table.jobId)]) + +export const notifications = pgTable('notifications', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }), + userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), + kind: varchar('kind', { length: 80 }).notNull(), + tone: notificationTone('tone').default('INFO').notNull(), + title: varchar('title', { length: 240 }).notNull(), + body: text('body').default('').notNull(), + page: varchar('page', { length: 48 }).notNull(), + resourceType: varchar('resource_type', { length: 80 }), + resourceId: uuid('resource_id'), + dedupeKey: varchar('dedupe_key', { length: 255 }).notNull(), + metadata: jsonb('metadata').$type>().default({}).notNull(), + readAt: timestamp('read_at', { withTimezone: true }), + ...timestamps, +}, (table) => [ + uniqueIndex('notifications_user_dedupe_unique').on(table.userId, table.dedupeKey), + index('notifications_user_created_idx').on(table.userId, table.createdAt), + index('notifications_user_unread_idx').on(table.userId, table.readAt, table.createdAt), + index('notifications_workspace_created_idx').on(table.workspaceId, table.createdAt), +]) + +export const auditLogs = pgTable('audit_logs', { + id: uuid('id').defaultRandom().primaryKey(), + workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'cascade' }), + actorId: uuid('actor_id').references(() => users.id, { onDelete: 'set null' }), + action: varchar('action', { length: 120 }).notNull(), + resourceType: varchar('resource_type', { length: 80 }).notNull(), + resourceId: uuid('resource_id'), + ipAddress: varchar('ip_address', { length: 64 }), + userAgent: text('user_agent'), + before: jsonb('before').$type>(), + after: jsonb('after').$type>(), + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), +}, (table) => [index('audit_logs_workspace_time_idx').on(table.workspaceId, table.createdAt), index('audit_logs_actor_idx').on(table.actorId)]) + +export type User = typeof users.$inferSelect +export type Workspace = typeof workspaces.$inferSelect +export type Project = typeof projects.$inferSelect +export type Episode = typeof episodes.$inferSelect +export type Asset = typeof assets.$inferSelect +export type GenerationJob = typeof generationJobs.$inferSelect +export type ProductionRun = typeof productionRuns.$inferSelect +export type Notification = typeof notifications.$inferSelect +export type ProviderVerification = typeof providerVerifications.$inferSelect diff --git a/server/src/db/seed.ts b/server/src/db/seed.ts new file mode 100644 index 0000000..351b529 --- /dev/null +++ b/server/src/db/seed.ts @@ -0,0 +1,269 @@ +import argon2 from 'argon2' +import { readFile } from 'node:fs/promises' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { and, desc, eq, sql } from 'drizzle-orm' +import { closeDatabase, db } from './client.js' +import { createCharacterConsistencyProfile, readCharacterConsistencyProfile } from '../lib/character-consistency.js' +import { closeStorage, projectSeedObjectKey, putObject } from '../storage/client.js' +import { + assetVersions, + assets, + episodes, + memberships, + projects, + scriptVersions, + shotVersions, + shots, + users, + workspaces, +} from './schema.js' + +const seedEmail = 'studio@frameflow.local' + +async function seed() { + const workspaceRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../..') + const passwordHash = await argon2.hash('FrameFlow2026!', { type: argon2.argon2id }) + + const [user] = await db.insert(users).values({ + email: seedEmail, + displayName: '雾灯工作室', + passwordHash, + emailVerifiedAt: new Date(), + }).onConflictDoUpdate({ + target: users.email, + set: { displayName: '雾灯工作室', passwordHash, updatedAt: new Date() }, + }).returning() + + if (!user) throw new Error('Failed to create seed user') + + let [workspace] = await db.select().from(workspaces).where(eq(workspaces.slug, 'mistlight-studio')).limit(1) + if (!workspace) { + ;[workspace] = await db.insert(workspaces).values({ + name: '雾灯工作室', + slug: 'mistlight-studio', + ownerId: user.id, + }).returning() + } + if (!workspace) throw new Error('Failed to create seed workspace') + + await db.insert(memberships).values({ + workspaceId: workspace.id, + userId: user.id, + role: 'OWNER', + }).onConflictDoUpdate({ + target: [memberships.workspaceId, memberships.userId], + set: { role: 'OWNER', updatedAt: new Date() }, + }) + + let [project] = await db.select().from(projects).where(and(eq(projects.workspaceId, workspace.id), eq(projects.slug, 'mist-letters'))).limit(1) + if (!project) { + ;[project] = await db.insert(projects).values({ + workspaceId: workspace.id, + createdById: user.id, + name: '雾城来信', + slug: 'mist-letters', + logline: '调查记者循着匿名录音,揭开十年前失踪案与整座雾城的秘密。', + genre: '都市悬疑', + status: 'ACTIVE', + visualBible: { + style: '写实电影感漫画', + palette: ['冷灰', '雾蓝', '信号红'], + lighting: '潮湿雨夜、硬侧光、克制霓虹', + }, + }).returning() + } + if (!project) throw new Error('Failed to create seed project') + + let [episode] = await db.select().from(episodes).where(and(eq(episodes.projectId, project.id), eq(episodes.episodeNumber, 4))).limit(1) + if (!episode) { + ;[episode] = await db.insert(episodes).values({ + projectId: project.id, + episodeNumber: 4, + title: '暗房里的第二封信', + synopsis: '林遥循着录音中的钟声来到旧城天台,与陆澄第一次正面谈起十年前的失踪案。', + status: 'STORYBOARDING', + targetDurationSeconds: 190, + createdById: user.id, + }).returning() + } + if (!episode) throw new Error('Failed to create seed episode') + + const [existingScript] = await db.select().from(scriptVersions).where(and(eq(scriptVersions.episodeId, episode.id), eq(scriptVersions.version, 1))).limit(1) + if (!existingScript) { + await db.insert(scriptVersions).values({ + episodeId: episode.id, + version: 1, + title: episode.title, + isCurrent: true, + createdById: user.id, + changeSummary: '初始剧本', + plainText: '场 12 · 外 · 旧城天台 · 夜\n林遥:你知道我会来。\n陆澄:有些答案只能在下雨的时候被听见。', + content: { + scenes: [ + { + number: 12, + location: '旧城天台', + time: '夜', + beats: [ + { type: 'action', text: '雨落得很急,铁门在风里撞向墙面。' }, + { type: 'dialogue', character: '林遥', text: '你知道我会来。' }, + { type: 'dialogue', character: '陆澄', text: '有些答案只能在下雨的时候被听见。' }, + ], + }, + ], + }, + }) + } + + const assetSeeds = [ + { + name: '林遥 · 侦探记者', + type: 'CHARACTER' as const, + description: '二十七岁调查记者,短发,克制而敏锐。', + filename: 'character-linyao.jpg', + identityPrompt: '二十七岁东亚女性调查记者,利落短发,克制敏锐的眼神,清晰稳定的面部轮廓。', + costumePrompt: '深色短款记者外套,简洁内搭,不佩戴夸张饰品。', + }, + { + name: '陆澄 · 法医顾问', + type: 'CHARACTER' as const, + description: '三十二岁法医顾问,冷静,带有难以辨认的疲惫。', + filename: 'character-lucheng.jpg', + identityPrompt: '三十二岁东亚男性法医顾问,短发,冷静疲惫的眼神,清晰稳定的面部轮廓。', + costumePrompt: '深色衬衫与克制的职业外套,无醒目标识。', + }, + { + name: '旧城天台 · 雨夜', + type: 'SCENE' as const, + description: '暴雨中的旧城高楼天台,雾与霓虹交叠。', + filename: 'scene-rooftop.jpg', + }, + ] + + const seededAssets = new Map() + for (const seedAsset of assetSeeds) { + const body = await readFile(resolve(workspaceRoot, 'public/assets', seedAsset.filename)) + const key = projectSeedObjectKey(workspace.id, project.id, seedAsset.filename) + await putObject({ + key, + body, + contentType: 'image/jpeg', + metadata: { source: 'seed', projectId: project.id }, + }) + let [asset] = await db.select().from(assets).where(and(eq(assets.projectId, project.id), eq(assets.name, seedAsset.name))).limit(1) + if (!asset) { + ;[asset] = await db.insert(assets).values({ + projectId: project.id, + type: seedAsset.type, + name: seedAsset.name, + description: seedAsset.description, + status: 'APPROVED', + tags: seedAsset.type === 'CHARACTER' ? ['主角'] : ['外景', '夜'], + createdById: user.id, + }).returning() + } + if (!asset) continue + let [version] = await db.select().from(assetVersions).where(and(eq(assetVersions.assetId, asset.id), eq(assetVersions.version, 1))).limit(1) + if (!version) { + ;[version] = await db.insert(assetVersions).values({ + assetId: asset.id, + version: 1, + storageKey: key, + mimeType: 'image/jpeg', + byteSize: body.length, + prompt: seedAsset.description, + provider: 'local-seed', + providerModel: 'bundled-example-v1', + generationParams: { source: 'seed', filename: seedAsset.filename }, + isCurrent: true, + createdById: user.id, + }).returning() + } else if (version.storageKey === `seed/${seedAsset.filename}` || version.storageKey === key) { + ;[version] = await db.update(assetVersions).set({ + storageKey: key, + mimeType: 'image/jpeg', + byteSize: body.length, + provider: 'local-seed', + providerModel: 'bundled-example-v1', + generationParams: { ...(version.generationParams ?? {}), source: 'seed', filename: seedAsset.filename }, + }).where(eq(assetVersions.id, version.id)).returning() + } + if (!version) throw new Error(`Failed to create seed version for ${seedAsset.name}`) + + if (seedAsset.type === 'CHARACTER' && !readCharacterConsistencyProfile(asset.metadata)) { + const consistencyProfile = createCharacterConsistencyProfile({ + referenceAssetVersionIds: [version.id], + identityPrompt: seedAsset.identityPrompt, + costumePrompt: seedAsset.costumePrompt, + stylePrompt: '写实电影感漫画,冷灰雾蓝色调,潮湿雨夜硬侧光。', + negativePrompt: '身份漂移,年龄变化,发型变化,畸形五官,文字,水印', + consistencyStrength: 90, + identityLocked: true, + }, user.id) + ;[asset] = await db.update(assets).set({ + metadata: { ...(asset.metadata ?? {}), consistencyProfile }, + updatedAt: new Date(), + }).where(eq(assets.id, asset.id)).returning() + if (!asset) throw new Error(`Failed to create seed consistency profile for ${seedAsset.name}`) + } + seededAssets.set(seedAsset.name, { asset, version }) + } + + const linyao = seededAssets.get('林遥 · 侦探记者') + const lucheng = seededAssets.get('陆澄 · 法医顾问') + const rooftop = seededAssets.get('旧城天台 · 雨夜') + if (!linyao || !lucheng || !rooftop) throw new Error('Seed asset references are incomplete') + + let [existingShot] = await db.select().from(shots).where(and(eq(shots.episodeId, episode.id), eq(shots.shotNumber, 1))).limit(1) + if (!existingShot) { + ;[existingShot] = await db.insert(shots).values({ + episodeId: episode.id, + shotNumber: 1, + sceneNumber: 12, + sortOrder: 100, + title: '雨夜旧城天台', + description: '暴雨掠过旧城天台,霓虹在积水中摇晃。', + shotType: '全景', + durationMs: 3200, + status: 'APPROVED', + characterAssetIds: [linyao.asset.id, lucheng.asset.id], + sceneAssetId: rooftop.asset.id, + createdById: user.id, + }).returning() + } else if (existingShot.characterAssetIds.length === 0 && !existingShot.sceneAssetId) { + ;[existingShot] = await db.update(shots).set({ + characterAssetIds: [linyao.asset.id, lucheng.asset.id], + sceneAssetId: rooftop.asset.id, + updatedAt: new Date(), + }).where(eq(shots.id, existingShot.id)).returning() + } + if (!existingShot) throw new Error('Failed to create seed shot') + + const existingShotVersions = await db.select().from(shotVersions).where(eq(shotVersions.shotId, existingShot.id)).orderBy(desc(shotVersions.version)) + if (!existingShotVersions.some((version) => version.generationParams?.source === 'seed')) { + await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`shot:${existingShot.id}`}))`) + const [latest] = await tx.select({ version: shotVersions.version }).from(shotVersions).where(eq(shotVersions.shotId, existingShot.id)).orderBy(desc(shotVersions.version)).limit(1) + await tx.update(shotVersions).set({ isCurrent: false }).where(eq(shotVersions.shotId, existingShot.id)) + await tx.insert(shotVersions).values({ + shotId: existingShot.id, + version: (latest?.version ?? 0) + 1, + imageAssetVersionId: rooftop.version.id, + subtitleText: '林遥:你知道我会来。\n陆澄:有些答案只能在下雨的时候被听见。', + generationParams: { source: 'seed', operation: 'example-storyboard' }, + isCurrent: true, + createdById: user.id, + }) + }) + } + + console.info(`Seed complete. Login: ${seedEmail} / FrameFlow2026!`) +} + +try { + await seed() +} finally { + await closeDatabase() + closeStorage() +} diff --git a/server/src/index.ts b/server/src/index.ts new file mode 100644 index 0000000..489943c --- /dev/null +++ b/server/src/index.ts @@ -0,0 +1,23 @@ +import { buildApp } from './app.js' +import { config } from './config.js' +import { closeDatabase } from './db/client.js' + +const app = await buildApp() + +async function shutdown(signal: string) { + app.log.info({ signal }, 'Shutting down') + await app.close() + await closeDatabase() + process.exit(0) +} + +process.on('SIGINT', () => void shutdown('SIGINT')) +process.on('SIGTERM', () => void shutdown('SIGTERM')) + +try { + await app.listen({ host: config.API_HOST, port: config.API_PORT }) +} catch (error) { + app.log.error(error) + await closeDatabase() + process.exit(1) +} diff --git a/server/src/lib/account-tokens.ts b/server/src/lib/account-tokens.ts new file mode 100644 index 0000000..a3ee759 --- /dev/null +++ b/server/src/lib/account-tokens.ts @@ -0,0 +1,40 @@ +import { randomBytes } from 'node:crypto' +import { and, eq, isNull, sql } from 'drizzle-orm' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { accountActionTokens } from '../db/schema.js' +import { hashToken } from './auth.js' + +export type AccountTokenType = 'EMAIL_VERIFICATION' | 'PASSWORD_RESET' + +function tokenTtlMs(type: AccountTokenType) { + return type === 'EMAIL_VERIFICATION' + ? config.EMAIL_VERIFICATION_TTL_HOURS * 60 * 60 * 1000 + : config.PASSWORD_RESET_TTL_MINUTES * 60 * 1000 +} + +export async function issueAccountToken(userId: string, type: AccountTokenType) { + const token = randomBytes(32).toString('base64url') + const tokenHash = hashToken(token) + const now = new Date() + const expiresAt = new Date(now.getTime() + tokenTtlMs(type)) + + const record = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`account-token:${userId}:${type}`}))`) + await tx.update(accountActionTokens).set({ consumedAt: now }).where(and( + eq(accountActionTokens.userId, userId), + eq(accountActionTokens.type, type), + isNull(accountActionTokens.consumedAt), + )) + const [created] = await tx.insert(accountActionTokens).values({ + userId, + type, + tokenHash, + expiresAt, + }).returning() + if (!created) throw new Error('Failed to create account action token') + return created + }) + + return { token, record } +} diff --git a/server/src/lib/audit.ts b/server/src/lib/audit.ts new file mode 100644 index 0000000..2791e27 --- /dev/null +++ b/server/src/lib/audit.ts @@ -0,0 +1,27 @@ +import type { FastifyRequest } from 'fastify' +import { db } from '../db/client.js' +import { auditLogs } from '../db/schema.js' +import { requestMeta } from './http.js' + +export async function audit(input: { + request: FastifyRequest + workspaceId?: string + action: string + resourceType: string + resourceId?: string + before?: Record + after?: Record +}) { + const meta = requestMeta(input.request) + await db.insert(auditLogs).values({ + workspaceId: input.workspaceId, + actorId: input.request.user?.sub, + action: input.action, + resourceType: input.resourceType, + resourceId: input.resourceId, + before: input.before, + after: input.after, + ipAddress: meta.ipAddress, + userAgent: meta.userAgent, + }) +} diff --git a/server/src/lib/auth.ts b/server/src/lib/auth.ts new file mode 100644 index 0000000..b0e84c0 --- /dev/null +++ b/server/src/lib/auth.ts @@ -0,0 +1,100 @@ +import { createHash, randomBytes } from 'node:crypto' +import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' +import { and, eq, gt, isNull } from 'drizzle-orm' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { refreshTokens, users } from '../db/schema.js' +import { errors } from './errors.js' + +export const REFRESH_COOKIE = 'ff_refresh' + +export function hashToken(value: string) { + return createHash('sha256').update(value).digest('hex') +} + +export function generateRefreshToken() { + return randomBytes(48).toString('base64url') +} + +export function refreshCookieOptions() { + return { + httpOnly: true, + secure: config.NODE_ENV === 'production', + sameSite: 'lax' as const, + path: '/api/v1/auth', + maxAge: config.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60, + } +} + +export function signAccessToken(app: FastifyInstance, user: { id: string; email: string; displayName: string }) { + return app.jwt.sign({ + sub: user.id, + email: user.email, + displayName: user.displayName, + tokenType: 'access' as const, + }, { expiresIn: config.ACCESS_TOKEN_TTL }) +} + +export async function createRefreshSession(input: { + userId: string + userAgent?: string + ipAddress?: string +}) { + const token = generateRefreshToken() + const expiresAt = new Date(Date.now() + config.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000) + const [session] = await db.insert(refreshTokens).values({ + userId: input.userId, + tokenHash: hashToken(token), + expiresAt, + userAgent: input.userAgent, + ipAddress: input.ipAddress, + }).returning() + if (!session) throw new Error('Failed to create refresh session') + return { token, session } +} + +export async function rotateRefreshSession(token: string, meta: { userAgent?: string; ipAddress?: string }) { + const [current] = await db.select().from(refreshTokens).where(and( + eq(refreshTokens.tokenHash, hashToken(token)), + isNull(refreshTokens.revokedAt), + gt(refreshTokens.expiresAt, new Date()), + )).limit(1) + + if (!current) throw errors.unauthorized('Refresh session is invalid or expired') + + const [user] = await db.select({ + id: users.id, + email: users.email, + displayName: users.displayName, + emailVerifiedAt: users.emailVerifiedAt, + disabledAt: users.disabledAt, + }).from(users).where(eq(users.id, current.userId)).limit(1) + + if (!user || user.disabledAt) throw errors.unauthorized('Account is unavailable') + if (config.EMAIL_VERIFICATION_REQUIRED && !user.emailVerifiedAt) throw errors.emailVerificationRequired() + + const next = await createRefreshSession({ userId: user.id, ...meta }) + await db.update(refreshTokens).set({ + revokedAt: new Date(), + replacedById: next.session.id, + }).where(eq(refreshTokens.id, current.id)) + + return { user, token: next.token } +} + +export async function revokeRefreshSession(token?: string) { + if (!token) return + await db.update(refreshTokens).set({ revokedAt: new Date() }).where(and( + eq(refreshTokens.tokenHash, hashToken(token)), + isNull(refreshTokens.revokedAt), + )) +} + +export async function requireAuth(request: FastifyRequest, _reply: FastifyReply) { + try { + await request.jwtVerify() + } catch { + throw errors.unauthorized() + } + if (request.user.tokenType !== 'access') throw errors.unauthorized() +} diff --git a/server/src/lib/billing-plans.ts b/server/src/lib/billing-plans.ts new file mode 100644 index 0000000..43c376b --- /dev/null +++ b/server/src/lib/billing-plans.ts @@ -0,0 +1,18 @@ +export const BILLING_PLAN_CATALOG = [ + { id: 'PRO', monthlyCreditLimit: 10_000, purchasable: true }, + { id: 'STUDIO', monthlyCreditLimit: 50_000, purchasable: true }, + { id: 'ENTERPRISE', monthlyCreditLimit: null, purchasable: false }, +] as const + +export type BillingPlanId = typeof BILLING_PLAN_CATALOG[number]['id'] +export type PurchasableBillingPlan = Extract + +export const DEFAULT_BILLING_PLAN: BillingPlanId = 'PRO' + +export function billingPlan(plan: string | null | undefined) { + return BILLING_PLAN_CATALOG.find((item) => item.id === plan) ?? null +} + +export function planCreditLimit(plan: BillingPlanId) { + return billingPlan(plan)?.monthlyCreditLimit ?? 10_000 +} diff --git a/server/src/lib/billing.ts b/server/src/lib/billing.ts new file mode 100644 index 0000000..60f194b --- /dev/null +++ b/server/src/lib/billing.ts @@ -0,0 +1,131 @@ +import { and, desc, eq, gte, inArray, lt, sql } from 'drizzle-orm' +import { db } from '../db/client.js' +import { billingSubscriptions, episodes, generationJobs, renders, shots, usageLedger, workspaces } from '../db/schema.js' +import type { JobKind } from '../queue/types.js' +import { BILLING_PLAN_CATALOG } from './billing-plans.js' +import type { BillingProviderReadiness } from './stripe-billing.js' + +export function billingPeriod(now = new Date()) { + const start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)) + const end = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)) + return { start, end } +} + +function numberValue(value: string | number | null | undefined) { + const parsed = Number(value ?? 0) + return Number.isFinite(parsed) ? parsed : 0 +} + +export async function estimateJobCredits(type: JobKind, input: Record) { + if (type === 'PIPELINE_HEALTHCHECK' || type === 'DELIVERY_PUBLISH') return 0 + if (type === 'SCRIPT_GENERATE') return 30 + if (type === 'STORYBOARD_GENERATE') return 40 + if (type === 'ASSET_GENERATE') return 120 + if (type === 'TTS_GENERATE') { + const text = typeof input.text === 'string' ? input.text : '' + return Math.max(1, Math.ceil(text.length / 5) * 0.6) + } + if (type === 'VIDEO_GENERATE') { + const duration = numberValue(typeof input.durationSeconds === 'number' || typeof input.durationSeconds === 'string' ? input.durationSeconds : 0) || 5 + return Math.max(1, duration) * 35 + } + if (type === 'LIPSYNC_GENERATE') return 60 + if (type === 'EPISODE_RENDER' && typeof input.renderId === 'string') { + const [row] = await db.select({ episodeId: renders.episodeId, targetDurationSeconds: episodes.targetDurationSeconds }).from(renders) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .where(eq(renders.id, input.renderId)).limit(1) + if (row) { + const durations = await db.select({ durationMs: shots.durationMs }).from(shots).where(eq(shots.episodeId, row.episodeId)) + const seconds = durations.length ? durations.reduce((total, shot) => total + shot.durationMs, 0) / 1000 : row.targetDurationSeconds + return Math.max(1, seconds) * 0.8 + } + } + return 100 +} + +export async function workspaceBillingSummary(workspaceId: string, options: { + now?: Date + providerReadiness: BillingProviderReadiness + canManage: boolean +}) { + const now = options.now ?? new Date() + const { start, end } = billingPeriod(now) + const [[workspace], [subscription]] = await Promise.all([ + db.select({ + id: workspaces.id, + plan: workspaces.plan, + monthlyCreditLimit: workspaces.monthlyCreditLimit, + }).from(workspaces).where(eq(workspaces.id, workspaceId)).limit(1), + db.select().from(billingSubscriptions).where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1), + ]) + if (!workspace) return null + + const [[usage], [reservation], breakdown, recent] = await Promise.all([ + db.select({ credits: sql`coalesce(sum(${usageLedger.credits}), 0)` }).from(usageLedger).where(and( + eq(usageLedger.workspaceId, workspaceId), + gte(usageLedger.occurredAt, start), + lt(usageLedger.occurredAt, end), + )), + db.select({ credits: sql`coalesce(sum(${generationJobs.estimatedCredits}), 0)` }).from(generationJobs).where(and( + eq(generationJobs.workspaceId, workspaceId), + inArray(generationJobs.status, ['QUEUED', 'RUNNING']), + )), + db.select({ + kind: usageLedger.kind, + quantity: sql`coalesce(sum(${usageLedger.quantity}), 0)`, + credits: sql`coalesce(sum(${usageLedger.credits}), 0)`, + }).from(usageLedger).where(and( + eq(usageLedger.workspaceId, workspaceId), + gte(usageLedger.occurredAt, start), + lt(usageLedger.occurredAt, end), + )).groupBy(usageLedger.kind).orderBy(desc(sql`sum(${usageLedger.credits})`)), + db.select().from(usageLedger).where(and( + eq(usageLedger.workspaceId, workspaceId), + gte(usageLedger.occurredAt, start), + lt(usageLedger.occurredAt, end), + )).orderBy(desc(usageLedger.occurredAt)).limit(50), + ]) + + const usedCredits = numberValue(usage?.credits) + const reservedCredits = numberValue(reservation?.credits) + const remainingCredits = Math.max(0, workspace.monthlyCreditLimit - usedCredits - reservedCredits) + return { + plan: workspace.plan, + monthlyCreditLimit: workspace.monthlyCreditLimit, + usedCredits, + reservedCredits, + remainingCredits, + utilizationPercent: workspace.monthlyCreditLimit > 0 ? Math.min(100, (usedCredits + reservedCredits) / workspace.monthlyCreditLimit * 100) : 100, + canManage: options.canManage, + provider: { + name: options.providerReadiness.provider, + status: options.providerReadiness.status, + configured: Object.values(options.providerReadiness.plans).some((plan) => plan.checkoutAvailable), + missingRequirements: options.providerReadiness.missingRequirements, + portalAvailable: options.providerReadiness.portalConfigured && Boolean(subscription), + webhookConfigured: options.providerReadiness.webhookConfigured, + }, + plans: BILLING_PLAN_CATALOG.map((plan) => ({ + id: plan.id, + monthlyCreditLimit: plan.monthlyCreditLimit, + purchasable: plan.purchasable, + checkoutAvailable: plan.purchasable + ? options.providerReadiness.plans[plan.id].checkoutAvailable + : false, + missingRequirements: plan.purchasable + ? options.providerReadiness.plans[plan.id].missingRequirements + : [], + })), + subscription: subscription ? { + provider: subscription.provider, + status: subscription.status, + plan: subscription.plan, + hasSubscription: Boolean(subscription.subscriptionId), + currentPeriodEnd: subscription.currentPeriodEnd?.toISOString() ?? null, + cancelAtPeriodEnd: subscription.cancelAtPeriodEnd, + } : null, + period: { start: start.toISOString(), end: end.toISOString() }, + breakdown: breakdown.map((row) => ({ kind: row.kind, quantity: numberValue(row.quantity), credits: numberValue(row.credits) })), + recent: recent.map((row) => ({ ...row, quantity: numberValue(row.quantity), credits: numberValue(row.credits), providerCostUsd: row.providerCostUsd === null ? null : numberValue(row.providerCostUsd) })), + } +} diff --git a/server/src/lib/character-consistency.test.ts b/server/src/lib/character-consistency.test.ts new file mode 100644 index 0000000..417cb91 --- /dev/null +++ b/server/src/lib/character-consistency.test.ts @@ -0,0 +1,68 @@ +import { describe, expect, it } from 'vitest' +import { applyCharacterConsistency, type AppliedCharacterProfile } from './character-consistency.js' + +function profile(overrides: Partial = {}): AppliedCharacterProfile { + return { + schemaVersion: 1, + assetId: crypto.randomUUID(), + assetName: '林遥', + referenceAssetVersionIds: [crypto.randomUUID()], + identityPrompt: '短发,琥珀色眼睛,面部轮廓保持一致', + costumePrompt: '深色风衣与银色胸针', + stylePrompt: '写实漫剧,冷色雨夜光线', + negativePrompt: '脸型漂移,服装变色', + consistencyStrength: 88, + identityLocked: true, + updatedAt: '2026-07-30T12:00:00.000Z', + updatedById: crypto.randomUUID(), + ...overrides, + } +} + +describe('character consistency application', () => { + it('prioritizes locked identity references and records an applied snapshot', () => { + const locked = profile() + const automaticReference = crypto.randomUUID() + const manualReference = crypto.randomUUID() + const result = applyCharacterConsistency({ + prompt: '人物推开天台铁门', + negativePrompt: '多余手指', + params: { consistencyStrength: 55, seedMode: 'random' }, + manualReferenceAssetVersionIds: [manualReference, locked.referenceAssetVersionIds[0]], + otherAutomaticReferenceAssetVersionIds: [automaticReference], + profiles: [locked], + }) + + expect(result.referenceAssetVersionIds).toEqual([ + locked.referenceAssetVersionIds[0], + automaticReference, + manualReference, + ]) + expect(result.params).toMatchObject({ consistencyStrength: 88, seedMode: 'random' }) + expect(result.prompt).toContain('角色「林遥」') + expect(result.prompt).toContain(locked.identityPrompt) + expect(result.prompt).toContain(locked.costumePrompt) + expect(result.negativePrompt).toBe('多余手指;脸型漂移,服装变色') + expect(result.profileSnapshots).toEqual([expect.objectContaining({ + assetId: locked.assetId, + referenceAssetVersionIds: locked.referenceAssetVersionIds, + identityLocked: true, + })]) + }) + + it('does not enforce an unlocked draft profile', () => { + const draft = profile({ identityLocked: false }) + const result = applyCharacterConsistency({ + prompt: '原始提示词', + negativePrompt: '', + params: { consistencyStrength: 64 }, + manualReferenceAssetVersionIds: [], + profiles: [draft], + }) + + expect(result.prompt).toBe('原始提示词') + expect(result.params.consistencyStrength).toBe(64) + expect(result.referenceAssetVersionIds).toEqual([]) + expect(result.profileSnapshots).toEqual([]) + }) +}) diff --git a/server/src/lib/character-consistency.ts b/server/src/lib/character-consistency.ts new file mode 100644 index 0000000..cb9baa4 --- /dev/null +++ b/server/src/lib/character-consistency.ts @@ -0,0 +1,116 @@ +import { z } from 'zod' + +export const characterConsistencyProfileInputSchema = z.object({ + referenceAssetVersionIds: z.array(z.uuid()).max(16).default([]), + identityPrompt: z.string().trim().max(4000).default(''), + costumePrompt: z.string().trim().max(4000).default(''), + stylePrompt: z.string().trim().max(4000).default(''), + negativePrompt: z.string().trim().max(4000).default(''), + consistencyStrength: z.number().int().min(50).max(100).default(82), + identityLocked: z.boolean().default(false), +}).superRefine((profile, context) => { + if (new Set(profile.referenceAssetVersionIds).size !== profile.referenceAssetVersionIds.length) { + context.addIssue({ code: 'custom', path: ['referenceAssetVersionIds'], message: 'Reference versions must be unique' }) + } + if (profile.identityLocked && profile.referenceAssetVersionIds.length === 0) { + context.addIssue({ code: 'custom', path: ['referenceAssetVersionIds'], message: 'A locked identity requires at least one reference version' }) + } +}) + +export type CharacterConsistencyProfileInput = z.infer + +export const characterConsistencyProfileSchema = characterConsistencyProfileInputSchema.and(z.object({ + schemaVersion: z.literal(1), + updatedAt: z.iso.datetime({ offset: true }), + updatedById: z.uuid(), +})) + +export type CharacterConsistencyProfile = z.infer + +export interface AppliedCharacterProfile extends CharacterConsistencyProfile { + assetId: string + assetName: string +} + +export function readCharacterConsistencyProfile(metadata: Record | null | undefined) { + const parsed = characterConsistencyProfileSchema.safeParse(metadata?.consistencyProfile) + return parsed.success ? parsed.data : null +} + +export function createCharacterConsistencyProfile( + input: CharacterConsistencyProfileInput, + updatedById: string, + updatedAt = new Date(), +): CharacterConsistencyProfile { + return { + ...input, + schemaVersion: 1, + updatedAt: updatedAt.toISOString(), + updatedById, + } +} + +function appendPrompt(base: string, profiles: AppliedCharacterProfile[]) { + const blocks = profiles.map((profile) => { + const fields = [ + profile.identityPrompt ? `身份特征:${profile.identityPrompt}` : '', + profile.costumePrompt ? `服装约束:${profile.costumePrompt}` : '', + profile.stylePrompt ? `视觉风格:${profile.stylePrompt}` : '', + ].filter(Boolean) + return fields.length > 0 ? `角色「${profile.assetName}」\n${fields.join('\n')}` : '' + }).filter(Boolean) + return blocks.length > 0 ? [base, '角色一致性约束:', ...blocks].join('\n') : base +} + +function mergeNegativePrompt(base: string, profiles: AppliedCharacterProfile[]) { + return [...new Set([base.trim(), ...profiles.map((profile) => profile.negativePrompt.trim())].filter(Boolean))].join(';') +} + +export function applyCharacterConsistency(input: { + prompt: string + negativePrompt: string + params: Record + manualReferenceAssetVersionIds: string[] + profiles: AppliedCharacterProfile[] + otherAutomaticReferenceAssetVersionIds?: string[] +}) { + const lockedProfiles = input.profiles.filter((profile) => profile.identityLocked) + const lockedReferenceIds = [...new Set(lockedProfiles.flatMap((profile) => profile.referenceAssetVersionIds))] + if (lockedReferenceIds.length > 16) { + throw new Error('Locked character profiles contain more than 16 unique identity references') + } + const referenceAssetVersionIds = [...new Set([ + ...lockedReferenceIds, + ...(input.otherAutomaticReferenceAssetVersionIds ?? []), + ...input.manualReferenceAssetVersionIds, + ])].slice(0, 16) + const consistencyStrength = lockedProfiles.length > 0 + ? Math.max(...lockedProfiles.map((profile) => profile.consistencyStrength)) + : undefined + const params = { + ...input.params, + ...(consistencyStrength === undefined ? {} : { consistencyStrength }), + } + const profileSnapshots = lockedProfiles.map((profile) => ({ + schemaVersion: profile.schemaVersion, + assetId: profile.assetId, + assetName: profile.assetName, + referenceAssetVersionIds: [...profile.referenceAssetVersionIds], + identityPrompt: profile.identityPrompt, + costumePrompt: profile.costumePrompt, + stylePrompt: profile.stylePrompt, + negativePrompt: profile.negativePrompt, + consistencyStrength: profile.consistencyStrength, + identityLocked: true as const, + updatedAt: profile.updatedAt, + updatedById: profile.updatedById, + })) + + return { + prompt: appendPrompt(input.prompt, lockedProfiles), + negativePrompt: mergeNegativePrompt(input.negativePrompt, lockedProfiles), + params, + referenceAssetVersionIds, + profileSnapshots, + } +} diff --git a/server/src/lib/credential-vault.test.ts b/server/src/lib/credential-vault.test.ts new file mode 100644 index 0000000..b3ff151 --- /dev/null +++ b/server/src/lib/credential-vault.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from 'vitest' +import { decryptCredential, encryptCredential } from './credential-vault.js' + +const secret = 'vault-test-secret-with-at-least-32-characters' + +describe('credential vault', () => { + it('encrypts credentials with randomized authenticated ciphertext', () => { + const first = encryptCredential('provider-access-token', secret) + const second = encryptCredential('provider-access-token', secret) + expect(first).not.toBe(second) + expect(first).not.toContain('provider-access-token') + expect(decryptCredential(first, secret)).toBe('provider-access-token') + expect(decryptCredential(second, secret)).toBe('provider-access-token') + }) + + it('rejects tampering, wrong keys, and unsupported formats', () => { + const encrypted = encryptCredential('refresh-token', secret) + const parts = encrypted.split('.') + const ciphertext = Buffer.from(parts[3]!, 'base64url') + ciphertext[0] ^= 1 + parts[3] = ciphertext.toString('base64url') + expect(() => decryptCredential(parts.join('.'), secret)).toThrow('could not be decrypted') + expect(() => decryptCredential(encrypted, 'different-secret-with-at-least-32-characters')).toThrow('could not be decrypted') + expect(() => decryptCredential('plaintext-token', secret)).toThrow('unsupported format') + }) + + it('rejects non-canonical base64url components even when they decode to the same bytes', () => { + const encrypted = encryptCredential('refresh-token', secret) + const parts = encrypted.split('.') + const encoded = parts[3]! + const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' + const lastIndex = alphabet.indexOf(encoded.at(-1)!) + const alternateIndex = (lastIndex & 0b110000) | ((lastIndex + 1) & 0b001111) + const nonCanonical = `${encoded.slice(0, -1)}${alphabet[alternateIndex]}` + expect(Buffer.from(nonCanonical, 'base64url')).toEqual(Buffer.from(encoded, 'base64url')) + parts[3] = nonCanonical + expect(() => decryptCredential(parts.join('.'), secret)).toThrow('could not be decrypted') + }) +}) diff --git a/server/src/lib/credential-vault.ts b/server/src/lib/credential-vault.ts new file mode 100644 index 0000000..61d821b --- /dev/null +++ b/server/src/lib/credential-vault.ts @@ -0,0 +1,51 @@ +import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto' +import { config } from '../config.js' + +const VERSION = 'v1' +const ALGORITHM = 'aes-256-gcm' + +function encryptionKey(secret: string) { + return createHash('sha256').update(secret, 'utf8').digest() +} + +function decodeBase64Url(value: string, expectedLength?: number) { + if (!/^[a-zA-Z0-9_-]+$/.test(value)) throw new Error('invalid base64url') + const decoded = Buffer.from(value, 'base64url') + if ( + decoded.length === 0 + || decoded.toString('base64url') !== value + || (expectedLength !== undefined && decoded.length !== expectedLength) + ) { + throw new Error('invalid base64url') + } + return decoded +} + +export function encryptCredential(value: string, secret = config.CREDENTIAL_ENCRYPTION_KEY) { + if (!value) throw new Error('Credential value cannot be empty') + const iv = randomBytes(12) + const cipher = createCipheriv(ALGORITHM, encryptionKey(secret), iv) + const encrypted = Buffer.concat([cipher.update(value, 'utf8'), cipher.final()]) + const tag = cipher.getAuthTag() + return [VERSION, iv.toString('base64url'), tag.toString('base64url'), encrypted.toString('base64url')].join('.') +} + +export function decryptCredential(value: string, secret = config.CREDENTIAL_ENCRYPTION_KEY) { + const [version, ivValue, tagValue, encryptedValue, extra] = value.split('.') + if (version !== VERSION || !ivValue || !tagValue || !encryptedValue || extra) { + throw new Error('Stored credential has an unsupported format') + } + try { + const iv = decodeBase64Url(ivValue, 12) + const tag = decodeBase64Url(tagValue, 16) + const encrypted = decodeBase64Url(encryptedValue) + const decipher = createDecipheriv(ALGORITHM, encryptionKey(secret), iv) + decipher.setAuthTag(tag) + return Buffer.concat([ + decipher.update(encrypted), + decipher.final(), + ]).toString('utf8') + } catch { + throw new Error('Stored credential could not be decrypted') + } +} diff --git a/server/src/lib/errors.ts b/server/src/lib/errors.ts new file mode 100644 index 0000000..41ba3bf --- /dev/null +++ b/server/src/lib/errors.ts @@ -0,0 +1,24 @@ +export class AppError extends Error { + readonly statusCode: number + readonly code: string + readonly details?: unknown + + constructor(statusCode: number, code: string, message: string, details?: unknown) { + super(message) + this.name = 'AppError' + this.statusCode = statusCode + this.code = code + this.details = details + } +} + +export const errors = { + badRequest: (message: string, details?: unknown) => new AppError(400, 'BAD_REQUEST', message, details), + unauthorized: (message = 'Authentication required') => new AppError(401, 'UNAUTHORIZED', message), + emailVerificationRequired: () => new AppError(403, 'EMAIL_VERIFICATION_REQUIRED', '请先完成邮箱验证'), + forbidden: (message = 'Insufficient permissions') => new AppError(403, 'FORBIDDEN', message), + notFound: (resource = 'Resource') => new AppError(404, 'NOT_FOUND', `${resource} not found`), + conflict: (message: string) => new AppError(409, 'CONFLICT', message), + serviceUnavailable: (message: string, details?: unknown) => new AppError(503, 'SERVICE_UNAVAILABLE', message, details), + creditLimitExceeded: (details?: unknown) => new AppError(402, 'CREDIT_LIMIT_EXCEEDED', 'Workspace credit limit would be exceeded', details), +} diff --git a/server/src/lib/http.ts b/server/src/lib/http.ts new file mode 100644 index 0000000..1292451 --- /dev/null +++ b/server/src/lib/http.ts @@ -0,0 +1,20 @@ +import type { FastifyRequest } from 'fastify' +import { type ZodType, ZodError } from 'zod' +import { errors } from './errors.js' + +export function parseWith(schema: ZodType, value: unknown): T { + try { + return schema.parse(value) + } catch (error) { + if (error instanceof ZodError) { + throw errors.badRequest('Request validation failed', error.issues) + } + throw error + } +} +export function requestMeta(request: FastifyRequest) { + return { + ipAddress: request.ip, + userAgent: request.headers['user-agent'] ?? null, + } +} diff --git a/server/src/lib/mailer.test.ts b/server/src/lib/mailer.test.ts new file mode 100644 index 0000000..49c2371 --- /dev/null +++ b/server/src/lib/mailer.test.ts @@ -0,0 +1,63 @@ +import { describe, expect, it, vi } from 'vitest' +import { sendWorkspaceInvitationEmail, workspaceInvitationUrl } from './mailer.js' + +describe('workspace invitation email', () => { + it('builds an invitation URL on the configured public origin', () => { + const url = new URL(workspaceInvitationUrl('invitation-token')) + expect(url.searchParams.get('invite')).toBe('invitation-token') + expect([...url.searchParams.keys()]).toEqual(['invite']) + expect(url.hash).toBe('') + }) + + it('sends escaped HTML and a complete plain-text fallback through Resend', async () => { + let requestBody: Record = {} + const fetchMock = vi.fn(async (_input, init) => { + requestBody = JSON.parse(String(init?.body)) as Record + return new Response(JSON.stringify({ id: 'email_123' }), { + status: 200, + headers: { 'content-type': 'application/json' }, + }) + }) + + const delivery = await sendWorkspaceInvitationEmail({ + to: 'invitee@example.com', + inviterName: '<导演>', + workspaceName: '北岸 & 工作室', + roleLabel: '编辑', + expiresAt: new Date('2026-08-08T12:00:00.000Z'), + url: 'https://studio.example.com/?invite=token&source=email', + }, { + apiKey: 're_test_key', + from: 'FrameFlow ', + fetchImpl: fetchMock, + }) + + expect(delivery).toEqual({ sent: true, provider: 'resend', id: 'email_123' }) + expect(fetchMock).toHaveBeenCalledOnce() + expect(requestBody).toMatchObject({ + from: 'FrameFlow ', + to: ['invitee@example.com'], + subject: '<导演> 邀请你加入 北岸 & 工作室', + }) + expect(String(requestBody.text)).toContain('https://studio.example.com/?invite=token&source=email') + expect(String(requestBody.html)).toContain('<导演>') + expect(String(requestBody.html)).toContain('北岸 & 工作室') + expect(String(requestBody.html)).toContain('invite=token&source=email') + expect(String(requestBody.html)).not.toContain('<导演>') + }) + + it('reports a development fallback without making a network call', async () => { + const fetchMock = vi.fn() + const delivery = await sendWorkspaceInvitationEmail({ + to: 'invitee@example.com', + inviterName: '导演', + workspaceName: '北岸工作室', + roleLabel: '编辑', + expiresAt: new Date('2026-08-08T12:00:00.000Z'), + url: 'http://127.0.0.1:4173/?invite=token', + }, { apiKey: '', fetchImpl: fetchMock }) + + expect(delivery).toEqual({ sent: false, provider: 'development' }) + expect(fetchMock).not.toHaveBeenCalled() + }) +}) diff --git a/server/src/lib/mailer.ts b/server/src/lib/mailer.ts new file mode 100644 index 0000000..20eb22c --- /dev/null +++ b/server/src/lib/mailer.ts @@ -0,0 +1,128 @@ +import { config } from '../config.js' +import type { AccountTokenType } from './account-tokens.js' + +export interface EmailTransportOptions { + apiKey?: string + from?: string + fetchImpl?: typeof fetch +} + +export interface WorkspaceInvitationEmailInput { + to: string + inviterName: string + workspaceName: string + roleLabel: string + expiresAt: Date + url: string +} + +export interface InvitationMailer { + send(input: WorkspaceInvitationEmailInput): Promise +} + +export type EmailDeliveryResult = + | { sent: false; provider: 'development' } + | { sent: true; provider: 'resend'; id: string | null } + +function escapeHtml(value: string) { + return value.replace(/[&<>"']/g, (character) => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + })[character]!) +} + +export function accountActionUrl(type: AccountTokenType, token: string) { + const origin = config.WEB_ORIGIN.split(',')[0]?.trim() || 'http://127.0.0.1:4173' + const url = new URL(origin) + url.search = '' + url.hash = '' + url.searchParams.set(type === 'EMAIL_VERIFICATION' ? 'verify_email' : 'reset_password', token) + return url.toString() +} + +export function workspaceInvitationUrl(token: string) { + const origin = config.WEB_ORIGIN.split(',')[0]?.trim() || 'http://127.0.0.1:4173' + const url = new URL(origin) + url.search = '' + url.hash = '' + url.searchParams.set('invite', token) + return url.toString() +} + +async function sendEmail(input: { + to: string + subject: string + text: string + html: string +}, options: EmailTransportOptions = {}): Promise { + const apiKey = options.apiKey ?? config.RESEND_API_KEY + if (!apiKey) return { sent: false, provider: 'development' } + + const response = await (options.fetchImpl ?? fetch)('https://api.resend.com/emails', { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + from: options.from ?? config.EMAIL_FROM, + to: [input.to], + subject: input.subject, + text: input.text, + html: input.html, + }), + signal: AbortSignal.timeout(15_000), + }) + if (!response.ok) throw new Error(`Email provider returned ${response.status}: ${(await response.text()).slice(0, 500)}`) + const body = await response.json() as { id?: string } + return { sent: true, provider: 'resend', id: body.id ?? null } +} + +export async function sendAccountActionEmail(input: { + type: AccountTokenType + to: string + displayName: string + url: string +}, options: EmailTransportOptions = {}) { + const verification = input.type === 'EMAIL_VERIFICATION' + const title = verification ? '验证你的 FrameFlow 邮箱' : '重置你的 FrameFlow 密码' + const action = verification ? '验证邮箱' : '重置密码' + const lifetime = verification + ? `${config.EMAIL_VERIFICATION_TTL_HOURS} 小时` + : `${config.PASSWORD_RESET_TTL_MINUTES} 分钟` + const safeName = escapeHtml(input.displayName) + const safeUrl = escapeHtml(input.url) + return sendEmail({ + to: input.to, + subject: title, + text: `${input.displayName},请在 ${lifetime}内打开以下链接完成${action}:\n\n${input.url}\n\n如果不是你发起的操作,请忽略此邮件。`, + html: `

      ${safeName},你好。

      请在 ${lifetime}内完成${action}。

      如果不是你发起的操作,请忽略此邮件。

      `, + }, options) +} + +export async function sendWorkspaceInvitationEmail( + input: WorkspaceInvitationEmailInput, + options: EmailTransportOptions = {}, +) { + const expiresAt = new Intl.DateTimeFormat('zh-CN', { + dateStyle: 'long', + timeStyle: 'short', + }).format(input.expiresAt) + const safeInviterName = escapeHtml(input.inviterName) + const safeWorkspaceName = escapeHtml(input.workspaceName) + const safeRoleLabel = escapeHtml(input.roleLabel) + const safeUrl = escapeHtml(input.url) + return sendEmail({ + to: input.to, + subject: `${input.inviterName} 邀请你加入 ${input.workspaceName}`, + text: `${input.inviterName} 邀请你加入 FrameFlow 工作室「${input.workspaceName}」,初始角色为${input.roleLabel}。\n\n请在 ${expiresAt} 前打开以下链接接受邀请:\n\n${input.url}\n\n该链接只能由收到邀请的邮箱账号使用。如果你不认识邀请人,请忽略此邮件。`, + html: `

      ${safeInviterName} 邀请你加入 FrameFlow 工作室「${safeWorkspaceName}」。

      初始角色:${safeRoleLabel}

      请在 ${escapeHtml(expiresAt)} 前接受邀请。

      加入工作室

      该链接只能由收到邀请的邮箱账号使用。如果你不认识邀请人,请忽略此邮件。

      `, + }, options) +} + +export const resendInvitationMailer: InvitationMailer = { + send: sendWorkspaceInvitationEmail, +} diff --git a/server/src/lib/metrics.ts b/server/src/lib/metrics.ts new file mode 100644 index 0000000..95eed5d --- /dev/null +++ b/server/src/lib/metrics.ts @@ -0,0 +1,62 @@ +import { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from 'prom-client' + +export const metricsRegistry = new Registry() + +collectDefaultMetrics({ register: metricsRegistry, prefix: 'frameflow_' }) + +export const apiRequestsTotal = new Counter({ + name: 'frameflow_api_requests_total', + help: 'Total API requests', + labelNames: ['method', 'route', 'status'] as const, + registers: [metricsRegistry], +}) + +export const apiRequestDurationSeconds = new Histogram({ + name: 'frameflow_api_request_duration_seconds', + help: 'API request duration in seconds', + labelNames: ['method', 'route', 'status'] as const, + buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10], + registers: [metricsRegistry], +}) + +export const applicationDependencyAvailable = new Gauge({ + name: 'frameflow_application_dependency_available', + help: 'Whether an API readiness dependency is currently available (1 or 0)', + labelNames: ['dependency'] as const, + registers: [metricsRegistry], +}) + +export const generationJobsProcessedTotal = new Counter({ + name: 'frameflow_generation_jobs_processed_total', + help: 'Generation job attempts by result', + labelNames: ['type', 'result'] as const, + registers: [metricsRegistry], +}) + +export const generationJobDurationSeconds = new Histogram({ + name: 'frameflow_generation_job_duration_seconds', + help: 'Generation job attempt duration in seconds', + labelNames: ['type'] as const, + buckets: [0.1, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600], + registers: [metricsRegistry], +}) + +export const generationWorkerActiveJobs = new Gauge({ + name: 'frameflow_generation_worker_active_jobs', + help: 'Generation jobs currently handled by this worker', + registers: [metricsRegistry], +}) + +export const generationWorkerHeartbeatTimestampSeconds = new Gauge({ + name: 'frameflow_generation_worker_heartbeat_timestamp_seconds', + help: 'Unix timestamp of the last successful worker heartbeat write', + registers: [metricsRegistry], +}) + +export const generationJobQueueDelaySeconds = new Histogram({ + name: 'frameflow_generation_job_queue_delay_seconds', + help: 'Time from queue submission until a worker starts the job', + labelNames: ['type'] as const, + buckets: [0.1, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600, 1800], + registers: [metricsRegistry], +}) diff --git a/server/src/lib/notifications.test.ts b/server/src/lib/notifications.test.ts new file mode 100644 index 0000000..c634f33 --- /dev/null +++ b/server/src/lib/notifications.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from 'vitest' +import { buildJobTerminalMessage } from './notifications.js' + +describe('job terminal notification copy', () => { + it('describes an asynchronous platform delivery as submitted', () => { + expect(buildJobTerminalMessage({ + jobType: 'DELIVERY_PUBLISH', + status: 'SUCCEEDED', + output: { status: 'PUBLISHING' }, + })).toEqual({ + title: '平台发布已提交', + body: '平台已接收发布任务,正在处理中。最终结果会在发布管理中更新。', + }) + }) + + it('describes a terminal delivery as completed', () => { + expect(buildJobTerminalMessage({ + jobType: 'DELIVERY_PUBLISH', + status: 'SUCCEEDED', + output: { status: 'PUBLISHED' }, + })).toEqual({ + title: '成片交付已完成', + body: '成片已完成交付,可前往发布管理查看详情。', + }) + }) + + it('keeps ordinary job and failure messages unchanged', () => { + expect(buildJobTerminalMessage({ jobType: 'SCRIPT_GENERATE', status: 'SUCCEEDED' }).title).toBe('剧本生成已完成') + expect(buildJobTerminalMessage({ + jobType: 'VIDEO_GENERATE', + status: 'FAILED', + errorMessage: '服务商超时', + })).toEqual({ title: '视频生成失败', body: '服务商超时' }) + }) +}) diff --git a/server/src/lib/notifications.ts b/server/src/lib/notifications.ts new file mode 100644 index 0000000..8abebd6 --- /dev/null +++ b/server/src/lib/notifications.ts @@ -0,0 +1,240 @@ +import { and, eq, inArray } from 'drizzle-orm' +import { db } from '../db/client.js' +import { memberships, notifications } from '../db/schema.js' +import type { Notification } from '../db/schema.js' +import { publishRealtimeEvent } from './realtime.js' + +type NotificationTone = Notification['tone'] + +export interface CreateNotificationInput { + workspaceId: string + userId: string + kind: string + tone: NotificationTone + title: string + body?: string + page: string + resourceType?: string + resourceId?: string + dedupeKey: string + metadata?: Record +} + +export async function createNotifications(inputs: CreateNotificationInput[]) { + if (inputs.length === 0) return [] + const created = await db.insert(notifications).values(inputs.map((input) => ({ + workspaceId: input.workspaceId, + userId: input.userId, + kind: input.kind, + tone: input.tone, + title: input.title.slice(0, 240), + body: (input.body ?? '').slice(0, 10_000), + page: input.page, + resourceType: input.resourceType, + resourceId: input.resourceId, + dedupeKey: input.dedupeKey, + metadata: input.metadata ?? {}, + }))).onConflictDoNothing().returning() + + await Promise.all(created.map((notification) => publishRealtimeEvent({ + workspaceId: notification.workspaceId, + userId: notification.userId, + type: 'notification.created', + resourceType: 'notification', + resourceId: notification.id, + payload: { notification }, + }))) + return created +} + +export async function createNotification(input: CreateNotificationInput) { + const [created] = await createNotifications([input]) + return created ?? null +} + +const jobLabels: Record = { + SCRIPT_GENERATE: '剧本生成', + STORYBOARD_GENERATE: '智能分镜', + ASSET_GENERATE: '画面生成', + TTS_GENERATE: '配音生成', + VIDEO_GENERATE: '视频生成', + LIPSYNC_GENERATE: '口型同步', + EPISODE_RENDER: '成片渲染', + DELIVERY_PUBLISH: '成片交付', +} + +interface JobTerminalInput { + workspaceId: string + userId: string + jobId: string + jobType: string + status: 'SUCCEEDED' | 'FAILED' + errorMessage?: string + projectId?: string + episodeId?: string + output?: Record +} + +export function buildJobTerminalMessage(input: Pick) { + const succeeded = input.status === 'SUCCEEDED' + const label = jobLabels[input.jobType] ?? input.jobType + if (!succeeded) { + return { + title: `${label}失败`, + body: input.errorMessage || '任务执行失败,可前往任务中心重试。', + } + } + if (input.jobType === 'DELIVERY_PUBLISH' && input.output?.status === 'PUBLISHING') { + return { + title: '平台发布已提交', + body: '平台已接收发布任务,正在处理中。最终结果会在发布管理中更新。', + } + } + if (input.jobType === 'DELIVERY_PUBLISH' && input.output?.status === 'PUBLISHED') { + return { + title: '成片交付已完成', + body: '成片已完成交付,可前往发布管理查看详情。', + } + } + return { + title: `${label}已完成`, + body: '产出已保存,可以继续下一步制作。', + } +} + +export async function notifyJobTerminal(input: JobTerminalInput) { + if (input.jobType === 'PIPELINE_HEALTHCHECK') return null + const succeeded = input.status === 'SUCCEEDED' + const page = input.jobType === 'DELIVERY_PUBLISH' ? 'publish' : 'jobs' + const message = buildJobTerminalMessage(input) + return createNotification({ + workspaceId: input.workspaceId, + userId: input.userId, + kind: succeeded ? 'JOB_SUCCEEDED' : 'JOB_FAILED', + tone: succeeded ? 'SUCCESS' : 'ERROR', + title: message.title, + body: message.body, + page, + resourceType: 'generation_job', + resourceId: input.jobId, + dedupeKey: `job:${input.jobId}:${input.status}`, + metadata: { + jobType: input.jobType, + status: input.status, + deliveryStatus: typeof input.output?.status === 'string' ? input.output.status : undefined, + projectId: input.projectId, + episodeId: input.episodeId, + }, + }) +} + +export async function reviewRecipientIds(workspaceId: string, assignedToId?: string | null) { + if (assignedToId) return [assignedToId] + const rows = await db.select({ userId: memberships.userId }).from(memberships) + .where(and( + eq(memberships.workspaceId, workspaceId), + inArray(memberships.role, ['OWNER', 'ADMIN', 'REVIEWER']), + )) + return rows.map((row) => row.userId) +} + +export async function notifyReviewRequested(input: { + workspaceId: string + reviewId: string + requestedById: string + assignedToId?: string | null + summary?: string + targetType: string +}) { + const recipients = (await reviewRecipientIds(input.workspaceId, input.assignedToId)) + .filter((userId) => userId !== input.requestedById) + return createNotifications(recipients.map((userId) => ({ + workspaceId: input.workspaceId, + userId, + kind: 'REVIEW_REQUESTED', + tone: 'WARNING', + title: '收到新的审核任务', + body: input.summary || '有一个制作版本等待审核。', + page: 'reviews', + resourceType: 'review_request', + resourceId: input.reviewId, + dedupeKey: `review:${input.reviewId}:requested`, + metadata: { targetType: input.targetType }, + }))) +} + +export async function notifyReviewAssigned(input: { + workspaceId: string + reviewId: string + assignedToId: string + assignedById: string + summary?: string +}) { + if (input.assignedToId === input.assignedById) return null + return createNotification({ + workspaceId: input.workspaceId, + userId: input.assignedToId, + kind: 'REVIEW_ASSIGNED', + tone: 'WARNING', + title: '审核任务已指派给你', + body: input.summary || '请前往审核中心处理。', + page: 'reviews', + resourceType: 'review_request', + resourceId: input.reviewId, + dedupeKey: `review:${input.reviewId}:assigned:${input.assignedToId}`, + }) +} + +export async function notifyReviewComment(input: { + workspaceId: string + reviewId: string + authorId: string + requestedById: string + assignedToId?: string | null + body: string + commentId: string +}) { + const recipients = [...new Set([input.requestedById, input.assignedToId].filter((value): value is string => Boolean(value)))] + .filter((userId) => userId !== input.authorId) + return createNotifications(recipients.map((userId) => ({ + workspaceId: input.workspaceId, + userId, + kind: 'REVIEW_COMMENTED', + tone: 'INFO', + title: '审核收到新意见', + body: input.body, + page: 'reviews', + resourceType: 'review_request', + resourceId: input.reviewId, + dedupeKey: `review-comment:${input.commentId}:${userId}`, + }))) +} + +export async function notifyReviewResolved(input: { + workspaceId: string + reviewId: string + requestedById: string + resolvedById: string + status: 'APPROVED' | 'CHANGES_REQUESTED' | 'CANCELLED' + summary?: string +}) { + if (input.requestedById === input.resolvedById) return null + const statusCopy = { + APPROVED: { title: '审核已通过', tone: 'SUCCESS' as const }, + CHANGES_REQUESTED: { title: '审核已退回修改', tone: 'WARNING' as const }, + CANCELLED: { title: '审核已取消', tone: 'INFO' as const }, + }[input.status] + return createNotification({ + workspaceId: input.workspaceId, + userId: input.requestedById, + kind: 'REVIEW_RESOLVED', + tone: statusCopy.tone, + title: statusCopy.title, + body: input.summary || '审核状态已经更新。', + page: 'reviews', + resourceType: 'review_request', + resourceId: input.reviewId, + dedupeKey: `review:${input.reviewId}:resolved:${input.status}`, + metadata: { status: input.status }, + }) +} diff --git a/server/src/lib/permissions.ts b/server/src/lib/permissions.ts new file mode 100644 index 0000000..e985942 --- /dev/null +++ b/server/src/lib/permissions.ts @@ -0,0 +1,51 @@ +import type { FastifyRequest } from 'fastify' +import { and, eq } from 'drizzle-orm' +import { db } from '../db/client.js' +import { memberships, projects } from '../db/schema.js' +import { errors } from './errors.js' + +export type WorkspaceRole = 'OWNER' | 'ADMIN' | 'EDITOR' | 'REVIEWER' | 'VIEWER' +export type Permission = + | 'workspace:manage' + | 'members:manage' + | 'project:read' + | 'project:write' + | 'content:write' + | 'review:decide' + | 'render:create' + | 'publish:create' + | 'publishing:manage' + | 'billing:read' + | 'billing:manage' + | 'services:verify' + | 'audit:read' + +const permissions: Record> = { + OWNER: new Set(['workspace:manage', 'members:manage', 'project:read', 'project:write', 'content:write', 'review:decide', 'render:create', 'publish:create', 'publishing:manage', 'billing:read', 'billing:manage', 'services:verify', 'audit:read']), + ADMIN: new Set(['workspace:manage', 'members:manage', 'project:read', 'project:write', 'content:write', 'review:decide', 'render:create', 'publish:create', 'publishing:manage', 'billing:read', 'billing:manage', 'services:verify', 'audit:read']), + EDITOR: new Set(['project:read', 'project:write', 'content:write', 'render:create']), + REVIEWER: new Set(['project:read', 'review:decide']), + VIEWER: new Set(['project:read']), +} + +export function can(role: WorkspaceRole, permission: Permission) { + return permissions[role].has(permission) +} + +export async function requireWorkspacePermission(request: FastifyRequest, workspaceId: string, permission: Permission) { + const [membership] = await db.select({ role: memberships.role }).from(memberships).where(and( + eq(memberships.workspaceId, workspaceId), + eq(memberships.userId, request.user.sub), + )).limit(1) + + if (!membership) throw errors.forbidden('You are not a member of this workspace') + if (!can(membership.role, permission)) throw errors.forbidden() + return membership +} + +export async function requireProjectPermission(request: FastifyRequest, projectId: string, permission: Permission) { + const [project] = await db.select({ id: projects.id, workspaceId: projects.workspaceId }).from(projects).where(eq(projects.id, projectId)).limit(1) + if (!project) throw errors.notFound('Project') + const membership = await requireWorkspacePermission(request, project.workspaceId, permission) + return { project, membership } +} diff --git a/server/src/lib/realtime.ts b/server/src/lib/realtime.ts new file mode 100644 index 0000000..2747d69 --- /dev/null +++ b/server/src/lib/realtime.ts @@ -0,0 +1,90 @@ +import { randomUUID } from 'node:crypto' +import type { Redis } from 'ioredis' +import { createRedisConnection, redis } from '../queue/connection.js' + +export const REALTIME_CHANNEL = 'frameflow:realtime:v1' + +export interface RealtimeEvent { + id: string + workspaceId: string + userId?: string + type: string + resourceType?: string + resourceId?: string + occurredAt: string + payload: Record +} + +export type RealtimeEventInput = Omit & { + id?: string + occurredAt?: string +} + +export function normalizeRealtimeEvent(input: RealtimeEventInput): RealtimeEvent { + return { + id: input.id ?? randomUUID(), + workspaceId: input.workspaceId, + ...(input.userId ? { userId: input.userId } : {}), + type: input.type, + ...(input.resourceType ? { resourceType: input.resourceType } : {}), + ...(input.resourceId ? { resourceId: input.resourceId } : {}), + occurredAt: input.occurredAt ?? new Date().toISOString(), + payload: input.payload, + } +} + +export async function publishRealtimeEvent(input: RealtimeEventInput) { + const event = normalizeRealtimeEvent(input) + try { + await redis.publish(REALTIME_CHANNEL, JSON.stringify(event)) + return true + } catch { + return false + } +} + +interface RealtimeClient { + workspaceId: string + userId: string + send: (event: RealtimeEvent) => void + close: () => void +} + +export class RealtimeHub { + private readonly subscriber: Redis + private readonly clients = new Set() + private readonly ready: Promise + + constructor(onError: (error: Error) => void = () => {}) { + this.subscriber = createRedisConnection() + this.subscriber.on('error', onError) + this.subscriber.on('message', (_channel, message) => { + let event: RealtimeEvent + try { + event = JSON.parse(message) as RealtimeEvent + } catch { + return + } + if (!event.workspaceId || !event.type || !event.id) return + for (const client of this.clients) { + if (client.workspaceId !== event.workspaceId) continue + if (event.userId && client.userId !== event.userId) continue + client.send(event) + } + }) + this.ready = this.subscriber.subscribe(REALTIME_CHANNEL) + } + + async addClient(client: RealtimeClient) { + await this.ready + this.clients.add(client) + return () => this.clients.delete(client) + } + + async close() { + for (const client of this.clients) client.close() + this.clients.clear() + await this.ready.catch(() => undefined) + await this.subscriber.quit().catch(() => undefined) + } +} diff --git a/server/src/lib/remote-media.test.ts b/server/src/lib/remote-media.test.ts new file mode 100644 index 0000000..341103a --- /dev/null +++ b/server/src/lib/remote-media.test.ts @@ -0,0 +1,112 @@ +import { describe, expect, it, vi } from 'vitest' +import { downloadRemoteMedia, type ResolveHost } from './remote-media.js' + +const publicResolver: ResolveHost = async () => [{ address: '93.184.216.34', family: 4 }] + +function options(overrides: Partial[1]> = {}) { + return { + maxBytes: 1024, + timeoutMs: 1000, + maxRedirects: 2, + resolveHost: publicResolver, + ...overrides, + } +} + +describe('remote provider media download', () => { + it('downloads a public HTTPS response with manual redirect handling and a byte limit', async () => { + const fetchMock = vi.fn(async (_url, init) => { + expect(init).toMatchObject({ method: 'GET', redirect: 'manual' }) + expect(init?.signal).toBeInstanceOf(AbortSignal) + return new Response(Buffer.from('generated-media'), { + status: 200, + headers: { 'content-length': '15', 'content-type': 'video/mp4' }, + }) + }) + + const result = await downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock })) + + expect(result).toEqual(Buffer.from('generated-media')) + expect(fetchMock).toHaveBeenCalledOnce() + }) + + it.each([ + 'http://provider.example/output.mp4', + 'https://localhost/output.mp4', + 'https://127.0.0.1/output.mp4', + 'https://10.2.3.4/output.mp4', + 'https://[::1]/output.mp4', + 'https://[fc00::1]/output.mp4', + ])('rejects a non-public source before fetching: %s', async (url) => { + const fetchMock = vi.fn() + await expect(downloadRemoteMedia(url, options({ fetchImpl: fetchMock }))).rejects.toMatchObject({ code: 'BAD_REQUEST' }) + expect(fetchMock).not.toHaveBeenCalled() + }) + + it('rejects DNS answers containing a private address', async () => { + const resolveHost: ResolveHost = async () => [ + { address: '93.184.216.34', family: 4 }, + { address: '169.254.169.254', family: 4 }, + ] + const fetchMock = vi.fn() + + await expect(downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock, resolveHost }))) + .rejects.toThrow('non-public address') + expect(fetchMock).not.toHaveBeenCalled() + }) + + it('validates every redirect and blocks a redirect to metadata services', async () => { + const fetchMock = vi.fn(async () => new Response(null, { + status: 302, + headers: { location: 'https://169.254.169.254/latest/meta-data/' }, + })) + + await expect(downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock }))) + .rejects.toThrow('non-public address') + expect(fetchMock).toHaveBeenCalledOnce() + }) + + it('follows a bounded public redirect and resolves relative destinations', async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(new Response(null, { status: 307, headers: { location: '/signed/output.mp4' } })) + .mockResolvedValueOnce(new Response(Buffer.from('redirected'), { status: 200 })) + + const result = await downloadRemoteMedia('https://provider.example/start', options({ fetchImpl: fetchMock })) + + expect(result).toEqual(Buffer.from('redirected')) + expect(String(fetchMock.mock.calls[1]?.[0])).toBe('https://provider.example/signed/output.mp4') + }) + + it('rejects a declared size above the limit before reading the body', async () => { + const fetchMock = vi.fn(async () => new Response(Buffer.from('small-body'), { + status: 200, + headers: { 'content-length': '2048' }, + })) + + await expect(downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock }))) + .rejects.toThrow('exceeds the configured storage limit') + }) + + it('stops a chunked response as soon as the streamed bytes exceed the limit', async () => { + const body = new ReadableStream({ + start(controller) { + controller.enqueue(Buffer.alloc(700)) + controller.enqueue(Buffer.alloc(700)) + controller.close() + }, + }) + const fetchMock = vi.fn(async () => new Response(body, { status: 200 })) + + await expect(downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock }))) + .rejects.toThrow('exceeds the configured storage limit') + }) + + it('aborts a stalled provider response at the configured timeout', async () => { + const fetchMock = vi.fn(async (_url, init) => new Promise((_resolve, reject) => { + init?.signal?.addEventListener('abort', () => reject(init.signal?.reason), { once: true }) + })) + + await expect(downloadRemoteMedia('https://provider.example/output.mp4', options({ fetchImpl: fetchMock, timeoutMs: 10 }))) + .rejects.toThrow() + }) +}) diff --git a/server/src/lib/remote-media.ts b/server/src/lib/remote-media.ts new file mode 100644 index 0000000..69c4127 --- /dev/null +++ b/server/src/lib/remote-media.ts @@ -0,0 +1,130 @@ +import { lookup } from 'node:dns/promises' +import ipaddr from 'ipaddr.js' +import { errors } from './errors.js' + +export interface ResolvedAddress { + address: string + family: number +} + +export type ResolveHost = (hostname: string) => Promise + +export interface DownloadRemoteMediaOptions { + maxBytes: number + timeoutMs: number + maxRedirects: number + fetchImpl?: typeof fetch + resolveHost?: ResolveHost +} + +const redirectStatuses = new Set([301, 302, 303, 307, 308]) + +async function defaultResolveHost(hostname: string) { + return lookup(hostname, { all: true, verbatim: true }) +} + +function publicAddress(address: string) { + try { + return ipaddr.process(address).range() === 'unicast' + } catch { + return false + } +} + +async function validateRemoteUrl(value: string | URL, resolveHost: ResolveHost) { + let url: URL + try { + url = value instanceof URL ? value : new URL(value) + } catch { + throw errors.badRequest('Provider returned an invalid media URL') + } + if (url.protocol !== 'https:') throw errors.badRequest('Provider media URL must use HTTPS') + if (url.username || url.password) throw errors.badRequest('Provider media URL must not contain credentials') + + const rawHostname = url.hostname.toLowerCase().replace(/\.$/, '') + const hostname = rawHostname.startsWith('[') && rawHostname.endsWith(']') + ? rawHostname.slice(1, -1) + : rawHostname + if (!hostname || hostname === 'localhost' || hostname.endsWith('.localhost') || hostname.endsWith('.local') || hostname.endsWith('.internal')) { + throw errors.badRequest('Provider media URL resolves to a disallowed host') + } + + let addresses: ResolvedAddress[] + if (ipaddr.isValid(hostname)) { + addresses = [{ address: hostname, family: ipaddr.parse(hostname).kind() === 'ipv4' ? 4 : 6 }] + } else { + try { + addresses = await resolveHost(hostname) + } catch { + throw errors.badRequest('Provider media URL could not be resolved') + } + } + if (addresses.length === 0 || addresses.some(({ address }) => !publicAddress(address))) { + throw errors.badRequest('Provider media URL resolves to a non-public address') + } + return url +} + +async function readLimitedBody(response: Response, maxBytes: number) { + const contentLength = response.headers.get('content-length') + if (contentLength !== null) { + const declaredSize = Number(contentLength) + if (!Number.isSafeInteger(declaredSize) || declaredSize < 0) { + await response.body?.cancel() + throw errors.badRequest('Provider media has an invalid content length') + } + if (declaredSize > maxBytes) { + await response.body?.cancel() + throw errors.badRequest('Generated media exceeds the configured storage limit') + } + } + + if (!response.body) throw errors.badRequest('Provider returned empty media') + const reader = response.body.getReader() + const chunks: Uint8Array[] = [] + let total = 0 + while (true) { + const { done, value } = await reader.read() + if (done) break + if (!value) continue + if (total + value.byteLength > maxBytes) { + await reader.cancel() + throw errors.badRequest('Generated media exceeds the configured storage limit') + } + chunks.push(value) + total += value.byteLength + } + if (total === 0) throw errors.badRequest('Provider returned empty media') + return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total) +} + +export async function downloadRemoteMedia(value: string, options: DownloadRemoteMediaOptions) { + const fetchImpl = options.fetchImpl ?? fetch + const resolveHost = options.resolveHost ?? defaultResolveHost + const signal = AbortSignal.timeout(options.timeoutMs) + let url = await validateRemoteUrl(value, resolveHost) + + for (let redirectCount = 0; redirectCount <= options.maxRedirects; redirectCount += 1) { + const response = await fetchImpl(url, { + method: 'GET', + redirect: 'manual', + signal, + headers: { Accept: 'image/*, audio/*, video/*, application/octet-stream' }, + }) + if (redirectStatuses.has(response.status)) { + const location = response.headers.get('location') + await response.body?.cancel() + if (!location) throw errors.badRequest('Provider media redirect is missing a destination') + if (redirectCount === options.maxRedirects) throw errors.badRequest('Provider media exceeded the redirect limit') + url = await validateRemoteUrl(new URL(location, url), resolveHost) + continue + } + if (!response.ok) { + await response.body?.cancel() + throw new Error(`Failed to download provider output (${response.status})`) + } + return readLimitedBody(response, options.maxBytes) + } + + throw errors.badRequest('Provider media exceeded the redirect limit') +} diff --git a/server/src/lib/slug.ts b/server/src/lib/slug.ts new file mode 100644 index 0000000..8fcc9ad --- /dev/null +++ b/server/src/lib/slug.ts @@ -0,0 +1,11 @@ +export function slugify(input: string) { + const ascii = input + .normalize('NFKD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase() + .replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-') + .replace(/^-+|-+$/g, '') + .slice(0, 72) + + return ascii || `project-${Date.now().toString(36)}` +} diff --git a/server/src/lib/stripe-billing.test.ts b/server/src/lib/stripe-billing.test.ts new file mode 100644 index 0000000..022c06e --- /dev/null +++ b/server/src/lib/stripe-billing.test.ts @@ -0,0 +1,69 @@ +import Stripe from 'stripe' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { config } from '../config.js' +import { StripeSdkBillingProvider } from './stripe-billing.js' + +describe.sequential('Stripe SDK billing provider', () => { + const keys = [ + 'STRIPE_SECRET_KEY', + 'STRIPE_WEBHOOK_SECRET', + 'STRIPE_PRO_PRICE_ID', + 'STRIPE_STUDIO_PRICE_ID', + ] as const + const original = Object.fromEntries(keys.map((key) => [key, config[key]])) + + beforeAll(() => { + Object.assign(config, { + STRIPE_SECRET_KEY: 'sk_test_frameflow_contract', + STRIPE_WEBHOOK_SECRET: 'whsec_frameflow_contract', + STRIPE_PRO_PRICE_ID: 'price_pro_contract', + STRIPE_STUDIO_PRICE_ID: 'price_studio_contract', + }) + }) + + afterAll(() => { + Object.assign(config, original) + }) + + it('reports checkout readiness and keeps price mapping server-side', () => { + const provider = new StripeSdkBillingProvider() + expect(provider.readiness()).toMatchObject({ + provider: 'stripe', + status: 'CONFIGURED', + portalConfigured: true, + webhookConfigured: true, + plans: { + PRO: { checkoutAvailable: true }, + STUDIO: { checkoutAvailable: true }, + }, + }) + expect(provider.planForPriceId('price_pro_contract')).toBe('PRO') + expect(provider.planForPriceId('price_studio_contract')).toBe('STUDIO') + expect(provider.planForPriceId('price_unknown')).toBeNull() + }) + + it('uses the official Stripe signature verifier against the exact payload bytes', () => { + const provider = new StripeSdkBillingProvider() + const payload = JSON.stringify({ + id: 'evt_contract', + object: 'event', + api_version: null, + created: 1_800_000_000, + data: { object: { id: 'sub_contract' } }, + livemode: false, + pending_webhooks: 1, + request: null, + type: 'customer.subscription.updated', + }) + const stripe = new Stripe(config.STRIPE_SECRET_KEY!) + const signature = stripe.webhooks.generateTestHeaderString({ + payload, + secret: config.STRIPE_WEBHOOK_SECRET!, + timestamp: 1_800_000_000, + }) + + const event = provider.constructWebhookEvent(Buffer.from(payload), signature) + expect(event.id).toBe('evt_contract') + expect(() => provider.constructWebhookEvent(Buffer.from(`${payload} `), signature)).toThrow() + }) +}) diff --git a/server/src/lib/stripe-billing.ts b/server/src/lib/stripe-billing.ts new file mode 100644 index 0000000..84d0d30 --- /dev/null +++ b/server/src/lib/stripe-billing.ts @@ -0,0 +1,194 @@ +import Stripe from 'stripe' +import { config } from '../config.js' +import { errors } from './errors.js' +import type { PurchasableBillingPlan } from './billing-plans.js' + +const purchasablePlans: PurchasableBillingPlan[] = ['PRO', 'STUDIO'] + +export interface BillingProviderReadiness { + provider: 'stripe' + status: 'NOT_CONFIGURED' | 'PARTIAL' | 'CONFIGURED' + portalConfigured: boolean + webhookConfigured: boolean + missingRequirements: string[] + plans: Record +} + +export interface StripeBillingProvider { + readonly name: 'stripe' + readiness(): BillingProviderReadiness + planForPriceId(priceId: string): PurchasableBillingPlan | null + createCustomer(input: { + workspaceId: string + workspaceName: string + email: string + displayName: string + }): Promise<{ id: string }> + createCheckoutSession(input: { + workspaceId: string + customerId: string + plan: PurchasableBillingPlan + idempotencyKey: string + }): Promise<{ id: string; url: string }> + createPortalSession(input: { + customerId: string + }): Promise<{ id: string; url: string }> + constructWebhookEvent(payload: Buffer, signature: string): Stripe.Event + retrieveSubscription(subscriptionId: string): Promise +} + +function compact(values: Array) { + return values.filter((value): value is string => Boolean(value)) +} + +function returnUrl(kind: 'success' | 'cancel' | 'portal') { + const configured = kind === 'success' + ? config.BILLING_SUCCESS_URL + : kind === 'cancel' + ? config.BILLING_CANCEL_URL + : undefined + const origin = config.WEB_ORIGIN.split(',')[0]?.trim() || 'http://127.0.0.1:4173' + const url = new URL(configured ?? origin) + url.searchParams.set('billing', kind) + if (kind === 'success') { + url.searchParams.set('session_id', 'FRAMEFLOW_CHECKOUT_SESSION') + return url.toString().replace('FRAMEFLOW_CHECKOUT_SESSION', '{CHECKOUT_SESSION_ID}') + } + return url.toString() +} + +export class StripeSdkBillingProvider implements StripeBillingProvider { + readonly name = 'stripe' as const + private stripeClient: Stripe | null = null + + private priceId(plan: PurchasableBillingPlan) { + return plan === 'PRO' ? config.STRIPE_PRO_PRICE_ID : config.STRIPE_STUDIO_PRICE_ID + } + + private client() { + if (!config.STRIPE_SECRET_KEY) { + throw errors.serviceUnavailable('Stripe billing is not configured', { + missingRequirements: ['STRIPE_SECRET_KEY'], + }) + } + this.stripeClient ??= new Stripe(config.STRIPE_SECRET_KEY) + return this.stripeClient + } + + readiness(): BillingProviderReadiness { + const baseMissing = compact([ + config.STRIPE_SECRET_KEY ? null : 'STRIPE_SECRET_KEY', + config.STRIPE_WEBHOOK_SECRET ? null : 'STRIPE_WEBHOOK_SECRET', + ]) + const plans = Object.fromEntries(purchasablePlans.map((plan) => { + const missingRequirements = [...baseMissing, ...(this.priceId(plan) ? [] : [`STRIPE_${plan}_PRICE_ID`])] + return [plan, { checkoutAvailable: missingRequirements.length === 0, missingRequirements }] + })) as BillingProviderReadiness['plans'] + const configuredPlans = purchasablePlans.filter((plan) => plans[plan].checkoutAvailable).length + const hasAnyConfiguration = Boolean( + config.STRIPE_SECRET_KEY + || config.STRIPE_WEBHOOK_SECRET + || config.STRIPE_PRO_PRICE_ID + || config.STRIPE_STUDIO_PRICE_ID, + ) + return { + provider: 'stripe', + status: configuredPlans === purchasablePlans.length + ? 'CONFIGURED' + : hasAnyConfiguration + ? 'PARTIAL' + : 'NOT_CONFIGURED', + portalConfigured: Boolean(config.STRIPE_SECRET_KEY), + webhookConfigured: Boolean(config.STRIPE_SECRET_KEY && config.STRIPE_WEBHOOK_SECRET), + missingRequirements: baseMissing, + plans, + } + } + + planForPriceId(priceId: string) { + return purchasablePlans.find((plan) => this.priceId(plan) === priceId) ?? null + } + + async createCustomer(input: { + workspaceId: string + workspaceName: string + email: string + displayName: string + }) { + const customer = await this.client().customers.create({ + email: input.email, + name: input.workspaceName, + description: `${input.workspaceName} · ${input.displayName}`, + metadata: { frameflowWorkspaceId: input.workspaceId }, + }, { idempotencyKey: `frameflow-customer:${input.workspaceId}` }) + return { id: customer.id } + } + + async createCheckoutSession(input: { + workspaceId: string + customerId: string + plan: PurchasableBillingPlan + idempotencyKey: string + }) { + const readiness = this.readiness().plans[input.plan] + const priceId = this.priceId(input.plan) + if (!readiness.checkoutAvailable || !priceId) { + throw errors.serviceUnavailable(`${input.plan} checkout is not configured`, { + missingRequirements: readiness.missingRequirements, + }) + } + const session = await this.client().checkout.sessions.create({ + mode: 'subscription', + customer: input.customerId, + client_reference_id: input.workspaceId, + line_items: [{ price: priceId, quantity: 1 }], + allow_promotion_codes: true, + success_url: returnUrl('success'), + cancel_url: returnUrl('cancel'), + metadata: { + frameflowWorkspaceId: input.workspaceId, + frameflowPlan: input.plan, + }, + subscription_data: { + metadata: { + frameflowWorkspaceId: input.workspaceId, + frameflowPlan: input.plan, + }, + }, + }, { idempotencyKey: input.idempotencyKey }) + if (!session.url) throw new Error('Stripe Checkout returned no redirect URL') + return { id: session.id, url: session.url } + } + + async createPortalSession(input: { customerId: string }) { + const client = this.client() + const session = await client.billingPortal.sessions.create({ + customer: input.customerId, + return_url: returnUrl('portal'), + ...(config.STRIPE_PORTAL_CONFIGURATION_ID + ? { configuration: config.STRIPE_PORTAL_CONFIGURATION_ID } + : {}), + }) + return { id: session.id, url: session.url } + } + + constructWebhookEvent(payload: Buffer, signature: string) { + if (!config.STRIPE_WEBHOOK_SECRET) { + throw errors.serviceUnavailable('Stripe webhooks are not configured', { + missingRequirements: ['STRIPE_WEBHOOK_SECRET'], + }) + } + return this.client().webhooks.constructEvent(payload, signature, config.STRIPE_WEBHOOK_SECRET) + } + + retrieveSubscription(subscriptionId: string) { + return this.client().subscriptions.retrieve(subscriptionId) + } +} + +export function createStripeBillingProvider(): StripeBillingProvider { + return new StripeSdkBillingProvider() +} diff --git a/server/src/media/ffmpeg.test.ts b/server/src/media/ffmpeg.test.ts new file mode 100644 index 0000000..d7e86e5 --- /dev/null +++ b/server/src/media/ffmpeg.test.ts @@ -0,0 +1,117 @@ +import { execFile } from 'node:child_process' +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { promisify } from 'node:util' +import { afterEach, describe, expect, it } from 'vitest' +import { config } from '../config.js' +import { buildSubtitleDocument, composeEpisode } from './ffmpeg.js' + +const execFileAsync = promisify(execFile) +const temporaryDirectories: string[] = [] + +afterEach(async () => { + await Promise.all(temporaryDirectories.splice(0).map((directory) => rm(directory, { recursive: true, force: true }))) +}) + +describe('composeEpisode', () => { + it('normalizes shots, burns subtitles, mixes music and produces a playable MP4', async () => { + const directory = await mkdtemp(join(tmpdir(), 'frameflow-ffmpeg-test-')) + temporaryDirectories.push(directory) + const imagePath = join(directory, 'frame.jpg') + const audioPath = join(directory, 'voice.wav') + const videoPath = join(directory, 'source.mp4') + await execFileAsync(config.FFMPEG_PATH, [ + '-hide_banner', '-loglevel', 'error', '-y', + '-f', 'lavfi', '-i', 'color=c=0x34515e:s=640x360', + '-frames:v', '1', imagePath, + ]) + await execFileAsync(config.FFMPEG_PATH, [ + '-hide_banner', '-loglevel', 'error', '-y', + '-f', 'lavfi', '-i', 'sine=frequency=440:sample_rate=48000', + '-t', '2', audioPath, + ]) + await execFileAsync(config.FFMPEG_PATH, [ + '-hide_banner', '-loglevel', 'error', '-y', + '-f', 'lavfi', '-i', 'testsrc=size=640x360:rate=24', + '-t', '2', '-pix_fmt', 'yuv420p', videoPath, + ]) + const image = await readFile(imagePath) + const audio = await readFile(audioPath) + const video = await readFile(videoPath) + + const result = await composeEpisode({ + clips: [ + { + durationMs: 800, + subtitleText: 'Scene one', + video: { data: video, extension: 'mp4' }, + audio: { data: audio, extension: 'wav' }, + production: { + trimStartMs: 250, + playbackRate: 1.25, + audioVolume: 0.6, + fit: 'cover', + transition: 'fade', + transitionDurationMs: 200, + }, + }, + { durationMs: 800, subtitleText: 'Scene two', image: { data: image, extension: 'jpg' } }, + ], + settings: { + width: 640, + height: 360, + fps: 24, + quality: 'draft', + burnSubtitles: true, + normalizeAudio: true, + musicVolume: 0.1, + subtitleStyle: { + fontSize: 22, + textColor: '#F2F2F2', + outlineColor: '#111111', + outlineWidth: 2, + bottomMargin: 36, + bold: true, + }, + }, + backgroundMusic: { data: audio, extension: 'wav' }, + }) + + expect(result.durationMs).toBe(1600) + expect(result.data.length).toBeGreaterThan(1000) + const outputPath = join(directory, 'result.mp4') + await writeFile(outputPath, result.data) + const probe = await execFileAsync(config.FFPROBE_PATH, [ + '-v', 'error', '-show_entries', 'format=duration', '-of', 'json', outputPath, + ]) + const duration = Number((JSON.parse(probe.stdout) as { format: { duration: string } }).format.duration) + expect(duration).toBeGreaterThan(1.4) + expect(duration).toBeLessThan(1.9) + }, 30_000) +}) + +describe('buildSubtitleDocument', () => { + const clips = [ + { durationMs: 1_250, subtitleText: '第一句' }, + { durationMs: 750, subtitleText: '' }, + { durationMs: 2_005, subtitleText: '第二句 --> 安全箭头' }, + ] + + it('builds SubRip cues on the complete shot timeline', () => { + expect(buildSubtitleDocument(clips, 'srt')).toBe( + '1\n00:00:00,000 --> 00:00:01,250\n第一句\n\n2\n00:00:02,000 --> 00:00:04,005\n第二句 -> 安全箭头\n', + ) + }) + + it('builds WebVTT cues with the required header', () => { + expect(buildSubtitleDocument(clips, 'vtt')).toBe( + 'WEBVTT\n\n00:00:00.000 --> 00:00:01.250\n第一句\n\n00:00:02.000 --> 00:00:04.005\n第二句 -> 安全箭头\n', + ) + }) + + it('does not create an empty sidecar when every cue is blank', () => { + expect(buildSubtitleDocument([{ durationMs: 1000, subtitleText: ' ' }], 'srt')).toBe('') + expect(buildSubtitleDocument([{ durationMs: 1000, subtitleText: '' }], 'vtt')).toBe('') + }) +}) diff --git a/server/src/media/ffmpeg.ts b/server/src/media/ffmpeg.ts new file mode 100644 index 0000000..76981d0 --- /dev/null +++ b/server/src/media/ffmpeg.ts @@ -0,0 +1,322 @@ +import { spawn } from 'node:child_process' +import { mkdtemp, readFile, rm, writeFile, copyFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { z } from 'zod' +import { config } from '../config.js' + +export const episodeRenderSettingsSchema = z.object({ + width: z.number().int().min(320).max(4096).default(1920), + height: z.number().int().min(320).max(4096).default(1080), + fps: z.union([z.literal(24), z.literal(25), z.literal(30), z.literal(50), z.literal(60)]).default(24), + quality: z.enum(['draft', 'balanced', 'high']).default('balanced'), + burnSubtitles: z.boolean().default(true), + normalizeAudio: z.boolean().default(true), + backgroundMusicStorageKey: z.string().min(1).max(1000).optional(), + musicVolume: z.number().min(0).max(1).default(0.18), + subtitleStyle: z.object({ + fontSize: z.number().int().min(12).max(72).default(24), + textColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default('#FFFFFF'), + outlineColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default('#000000'), + outlineWidth: z.number().min(0).max(6).default(2), + bottomMargin: z.number().int().min(12).max(300).default(48), + bold: z.boolean().default(true), + }).default({ + fontSize: 24, + textColor: '#FFFFFF', + outlineColor: '#000000', + outlineWidth: 2, + bottomMargin: 48, + bold: true, + }), +}) + +export type EpisodeRenderSettings = z.infer + +const shotProductionSettingsShape = { + trimStartMs: z.number().int().min(0).max(600_000), + playbackRate: z.number().min(0.25).max(4), + audioVolume: z.number().min(0).max(2), + fit: z.enum(['contain', 'cover']), + transition: z.enum(['cut', 'fade']), + transitionDurationMs: z.number().int().min(0).max(2_000), +} + +export const shotProductionSettingsSchema = z.object({ + trimStartMs: shotProductionSettingsShape.trimStartMs.default(0), + playbackRate: shotProductionSettingsShape.playbackRate.default(1), + audioVolume: shotProductionSettingsShape.audioVolume.default(1), + fit: shotProductionSettingsShape.fit.default('contain'), + transition: shotProductionSettingsShape.transition.default('cut'), + transitionDurationMs: shotProductionSettingsShape.transitionDurationMs.default(350), +}) + +export const shotProductionSettingsUpdateSchema = z.object(shotProductionSettingsShape).partial() +export type ShotProductionSettings = z.infer + +export interface CompositionClip { + durationMs: number + subtitleText: string + production?: ShotProductionSettings + video?: { data: Buffer; extension: string } + image?: { data: Buffer; extension: string } + audio?: { data: Buffer; extension: string } +} + +export interface EpisodeCompositionInput { + clips: CompositionClip[] + settings: EpisodeRenderSettings + backgroundMusic?: { data: Buffer; extension: string } +} + +const crfByQuality = { draft: '26', balanced: '21', high: '18' } as const +let subtitleFilterAvailable: boolean | undefined + +function run(command: string, args: string[], cwd: string) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { cwd, stdio: ['ignore', 'ignore', 'pipe'] }) + let stderr = '' + child.stderr.setEncoding('utf8') + child.stderr.on('data', (chunk: string) => { + stderr = `${stderr}${chunk}`.slice(-32_000) + }) + child.once('error', reject) + child.once('close', (code) => { + if (code === 0) resolve() + else reject(new Error(`${command} exited with code ${code}: ${stderr.trim()}`)) + }) + }) +} + +function capture(command: string, args: string[], cwd: string) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] }) + let output = '' + const append = (chunk: Buffer | string) => { + output = `${output}${chunk.toString()}`.slice(-2_000_000) + } + child.stdout.on('data', append) + child.stderr.on('data', append) + child.once('error', reject) + child.once('close', (code) => { + if (code === 0) resolve(output) + else reject(new Error(`${command} exited with code ${code}: ${output.slice(-32_000).trim()}`)) + }) + }) +} + +async function hasSubtitleFilter(cwd: string) { + if (subtitleFilterAvailable !== undefined) return subtitleFilterAvailable + try { + const filters = await capture(config.FFMPEG_PATH, ['-hide_banner', '-filters'], cwd) + subtitleFilterAvailable = /^\s*[TSC.]{3}\s+subtitles\s/m.test(filters) + } catch { + subtitleFilterAvailable = false + } + return subtitleFilterAvailable +} + +export type SubtitleFormat = 'srt' | 'vtt' + +function subtitleTimestamp(milliseconds: number, format: SubtitleFormat) { + const total = Math.max(0, Math.round(milliseconds)) + const hours = Math.floor(total / 3_600_000) + const minutes = Math.floor((total % 3_600_000) / 60_000) + const seconds = Math.floor((total % 60_000) / 1000) + const millis = total % 1000 + const separator = format === 'srt' ? ',' : '.' + return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}${separator}${String(millis).padStart(3, '0')}` +} + +export function buildSubtitleDocument( + clips: Array>, + format: SubtitleFormat, +) { + let cursor = 0 + const entries: string[] = [] + for (const clip of clips) { + const text = clip.subtitleText.trim().replace(/\r/g, '').replace(/-->/g, '->') + const start = cursor + cursor += clip.durationMs + if (!text) continue + const sequence = format === 'srt' ? `${entries.length + 1}\n` : '' + entries.push(`${sequence}${subtitleTimestamp(start, format)} --> ${subtitleTimestamp(cursor, format)}\n${text}\n`) + } + if (entries.length === 0) return '' + const body = entries.join('\n') + return format === 'vtt' ? `WEBVTT\n\n${body}` : body +} + +function escapeFilterPath(path: string) { + return path.replace(/\\/g, '\\\\').replace(/:/g, '\\:').replace(/'/g, "\\'").replace(/,/g, '\\,') +} + +function assColor(value: string) { + const red = value.slice(1, 3) + const green = value.slice(3, 5) + const blue = value.slice(5, 7) + return `&H00${blue}${green}${red}` +} + +function subtitleForceStyle(settings: EpisodeRenderSettings['subtitleStyle']) { + return [ + `FontSize=${settings.fontSize}`, + `PrimaryColour=${assColor(settings.textColor)}`, + `OutlineColour=${assColor(settings.outlineColor)}`, + `Outline=${settings.outlineWidth}`, + 'Shadow=0', + `MarginV=${settings.bottomMargin}`, + `Bold=${settings.bold ? -1 : 0}`, + 'Alignment=2', + ].join(',') +} + +function mediaExtension(value: string) { + const safe = value.toLowerCase().replace(/[^a-z0-9]/g, '') + if (!safe) throw new Error('Media extension is invalid') + return safe +} + +export async function composeEpisode(input: EpisodeCompositionInput) { + if (input.clips.length === 0) throw new Error('At least one shot is required to compose an episode') + const directory = await mkdtemp(join(tmpdir(), 'frameflow-render-')) + const normalizedPaths: string[] = [] + const durationMs = input.clips.reduce((total, clip) => total + clip.durationMs, 0) + + try { + for (const [index, clip] of input.clips.entries()) { + if (!clip.video && !clip.image) throw new Error(`Shot ${index + 1} has no video or image source`) + const production = shotProductionSettingsSchema.parse(clip.production ?? {}) + const visual = clip.video ?? clip.image! + const visualPath = join(directory, `visual-${index}.${mediaExtension(visual.extension)}`) + await writeFile(visualPath, visual.data) + + const audioPath = clip.audio + ? join(directory, `audio-${index}.${mediaExtension(clip.audio.extension)}`) + : null + if (audioPath && clip.audio) await writeFile(audioPath, clip.audio.data) + + const outputPath = join(directory, `clip-${String(index).padStart(4, '0')}.mp4`) + const seconds = Math.max(0.1, clip.durationMs / 1000) + const visualArgs = clip.video + ? [ + ...(production.trimStartMs > 0 ? ['-ss', String(production.trimStartMs / 1000)] : []), + '-i', visualPath, + ] + : ['-loop', '1', '-framerate', String(input.settings.fps), '-i', visualPath] + const audioArgs = audioPath + ? ['-i', audioPath] + : ['-f', 'lavfi', '-i', 'anullsrc=channel_layout=stereo:sample_rate=48000'] + const videoFilters = [ + clip.video && production.playbackRate !== 1 + ? `setpts=(PTS-STARTPTS)/${production.playbackRate}` + : 'setpts=PTS-STARTPTS', + production.fit === 'cover' + ? `scale=${input.settings.width}:${input.settings.height}:force_original_aspect_ratio=increase,crop=${input.settings.width}:${input.settings.height}` + : `scale=${input.settings.width}:${input.settings.height}:force_original_aspect_ratio=decrease,pad=${input.settings.width}:${input.settings.height}:(ow-iw)/2:(oh-ih)/2:black`, + `fps=${input.settings.fps}`, + `tpad=stop_mode=clone:stop_duration=${seconds}`, + `trim=duration=${seconds}`, + 'setpts=PTS-STARTPTS', + ] + const audioFilters = [ + 'aresample=48000', + `volume=${production.audioVolume}`, + `apad=pad_dur=${seconds}`, + `atrim=duration=${seconds}`, + 'asetpts=PTS-STARTPTS', + ] + if (production.transition === 'fade') { + const transitionSeconds = Math.min(production.transitionDurationMs / 1000, seconds / 2) + if (transitionSeconds > 0) { + const fadeOutStart = Math.max(0, seconds - transitionSeconds) + videoFilters.push(`fade=t=in:st=0:d=${transitionSeconds}`, `fade=t=out:st=${fadeOutStart}:d=${transitionSeconds}`) + audioFilters.push(`afade=t=in:st=0:d=${transitionSeconds}`, `afade=t=out:st=${fadeOutStart}:d=${transitionSeconds}`) + } + } + videoFilters.push('format=yuv420p') + const filter = `[0:v]${videoFilters.join(',')}[v];[1:a]${audioFilters.join(',')}[a]` + + await run(config.FFMPEG_PATH, [ + '-hide_banner', '-loglevel', 'error', '-y', + ...visualArgs, + ...audioArgs, + '-filter_complex', filter, + '-map', '[v]', '-map', '[a]', + '-t', String(seconds), + '-c:v', 'libx264', '-preset', 'medium', '-crf', crfByQuality[input.settings.quality], + '-c:a', 'aac', '-b:a', '192k', '-ar', '48000', '-ac', '2', + '-movflags', '+faststart', outputPath, + ], directory) + normalizedPaths.push(outputPath) + } + + const concatList = join(directory, 'clips.txt') + await writeFile(concatList, normalizedPaths.map((path) => `file '${path.replace(/'/g, "'\\''")}'`).join('\n')) + const concatenatedPath = join(directory, 'concatenated.mp4') + await run(config.FFMPEG_PATH, [ + '-hide_banner', '-loglevel', 'error', '-y', + '-f', 'concat', '-safe', '0', '-i', concatList, + '-c', 'copy', '-movflags', '+faststart', concatenatedPath, + ], directory) + + const subtitlePath = join(directory, 'subtitles.srt') + const subtitles = buildSubtitleDocument(input.clips, 'srt') + if (subtitles) await writeFile(subtitlePath, subtitles) + + const musicPath = input.backgroundMusic + ? join(directory, `music.${mediaExtension(input.backgroundMusic.extension)}`) + : null + if (musicPath && input.backgroundMusic) await writeFile(musicPath, input.backgroundMusic.data) + + const outputPath = join(directory, 'episode.mp4') + const burnSubtitles = input.settings.burnSubtitles && Boolean(subtitles) && await hasSubtitleFilter(directory) + const embedSubtitles = Boolean(subtitles) && !burnSubtitles + if (!burnSubtitles && !musicPath && !embedSubtitles && !input.settings.normalizeAudio) { + await copyFile(concatenatedPath, outputPath) + } else { + const args = ['-hide_banner', '-loglevel', 'error', '-y', '-i', concatenatedPath] + if (musicPath) args.push('-stream_loop', '-1', '-i', musicPath) + const subtitleInputIndex = musicPath ? 2 : 1 + if (embedSubtitles) args.push('-i', subtitlePath) + + const filters: string[] = [] + if (burnSubtitles) { + filters.push(`[0:v]subtitles=filename='${escapeFilterPath(subtitlePath)}':force_style='${subtitleForceStyle(input.settings.subtitleStyle)}'[v]`) + } + let audioInput = '[0:a]' + if (musicPath) { + const seconds = durationMs / 1000 + const fadeStart = Math.max(0, seconds - 2) + filters.push(`[1:a]volume=${input.settings.musicVolume},atrim=0:${seconds},afade=t=out:st=${fadeStart}:d=2[music]`) + filters.push('[0:a][music]amix=inputs=2:duration=first:dropout_transition=2[mixed]') + audioInput = '[mixed]' + } + if (input.settings.normalizeAudio) { + filters.push(`${audioInput}loudnorm=I=-14:LRA=11:TP=-1.5[a]`) + audioInput = '[a]' + } + if (filters.length > 0) args.push('-filter_complex', filters.join(';')) + const audioFiltered = Boolean(musicPath) || input.settings.normalizeAudio + args.push('-map', burnSubtitles ? '[v]' : '0:v', '-map', audioFiltered ? audioInput : '0:a') + if (embedSubtitles) args.push('-map', `${subtitleInputIndex}:0`) + args.push( + '-c:v', burnSubtitles ? 'libx264' : 'copy', + ...(burnSubtitles ? ['-preset', 'medium', '-crf', crfByQuality[input.settings.quality]] : []), + '-c:a', audioFiltered ? 'aac' : 'copy', + '-b:a', '192k', + ...(embedSubtitles ? ['-c:s', 'mov_text', '-metadata:s:s:0', 'language=zho'] : []), + '-movflags', '+faststart', '-shortest', outputPath, + ) + await run(config.FFMPEG_PATH, args, directory) + } + + return { + data: await readFile(outputPath), + durationMs, + subtitlesMode: !subtitles ? 'none' as const : burnSubtitles ? 'burned' as const : 'embedded' as const, + } + } finally { + await rm(directory, { recursive: true, force: true }) + } +} diff --git a/server/src/media/timeline.test.ts b/server/src/media/timeline.test.ts new file mode 100644 index 0000000..294a126 --- /dev/null +++ b/server/src/media/timeline.test.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from 'vitest' +import { clipTrimFromDrag, locateTimelinePosition, timelineDuration } from '../../../src/timeline.js' + +describe('timeline editing helpers', () => { + const shots = [{ durationMs: 1000 }, { durationMs: 2000 }, { durationMs: 500 }] + + it('locates exact episode positions across clip boundaries', () => { + expect(timelineDuration(shots)).toBe(3500) + expect(locateTimelinePosition(shots, 999)).toMatchObject({ index: 0, localMs: 999, beforeMs: 0 }) + expect(locateTimelinePosition(shots, 1000)).toMatchObject({ index: 1, localMs: 0, beforeMs: 1000 }) + expect(locateTimelinePosition(shots, 3500)).toMatchObject({ index: 2, localMs: 500, beforeMs: 3000 }) + expect(locateTimelinePosition(shots, -20)).toMatchObject({ index: 0, localMs: 0, globalMs: 0 }) + }) + + it('converts trim-handle movement into source in-points and output duration', () => { + const start = clipTrimFromDrag({ + edge: 'start', + deltaPixels: 10, + trackWidth: 100, + totalDurationMs: 3500, + durationMs: 1000, + trimStartMs: 250, + playbackRate: 1.5, + }) + expect(start).toEqual({ durationMs: 650, trimStartMs: 800 }) + + const restored = clipTrimFromDrag({ + edge: 'start', + deltaPixels: -100, + trackWidth: 100, + totalDurationMs: 3500, + durationMs: 1000, + trimStartMs: 250, + playbackRate: 1, + }) + expect(restored).toEqual({ durationMs: 1250, trimStartMs: 0 }) + + const end = clipTrimFromDrag({ + edge: 'end', + deltaPixels: -20, + trackWidth: 100, + totalDurationMs: 3500, + durationMs: 1000, + trimStartMs: 250, + playbackRate: 1, + }) + expect(end).toEqual({ durationMs: 300, trimStartMs: 250 }) + }) +}) diff --git a/server/src/providers/agnes.contract.test.ts b/server/src/providers/agnes.contract.test.ts new file mode 100644 index 0000000..a96d92c --- /dev/null +++ b/server/src/providers/agnes.contract.test.ts @@ -0,0 +1,318 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { config } from '../config.js' +import { AgnesProvider } from './agnes.js' + +const originalConfiguration = { + apiKey: config.AGNES_API_KEY, + textModel: config.AGNES_TEXT_MODEL, + imageModel: config.AGNES_IMAGE_MODEL, + videoModel: config.AGNES_VIDEO_MODEL, +} + +function jsonResponse(payload: unknown, status = 200) { + return new Response(JSON.stringify(payload), { status, headers: { 'content-type': 'application/json' } }) +} + +beforeAll(() => { + config.AGNES_API_KEY = 'contract-agnes-secret' + config.AGNES_TEXT_MODEL = 'agnes-text-contract' + config.AGNES_IMAGE_MODEL = 'agnes-image-contract' + config.AGNES_VIDEO_MODEL = 'agnes-video-contract' +}) + +afterAll(() => { + config.AGNES_API_KEY = originalConfiguration.apiKey + config.AGNES_TEXT_MODEL = originalConfiguration.textModel + config.AGNES_IMAGE_MODEL = originalConfiguration.imageModel + config.AGNES_VIDEO_MODEL = originalConfiguration.videoModel +}) + +describe('Agnes provider contract', () => { + it('generates a schema-validated script through chat completions', async () => { + const document = { + title: '雨夜来信', + logline: '记者在天台发现关键线索。', + estimatedDurationSeconds: 30, + scenes: [{ + number: 1, + location: '旧城天台', + interiorExterior: '外', + time: '夜', + summary: '林遥发现录音机。', + beats: [{ type: 'action', text: '雨水拍打铁门。', character: null, parenthetical: null }], + }], + } + const fetchMock = vi.fn(async (request, init) => { + expect(String(request)).toBe('https://api.agnes-ai.cn/v1/chat/completions') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer contract-agnes-secret') + const body = JSON.parse(init?.body as string) + expect(body).toMatchObject({ model: 'agnes-text-contract', response_format: { type: 'json_object' } }) + expect(body.messages).toHaveLength(2) + return jsonResponse({ + object: 'chat.completion', + choices: [{ index: 0, message: { role: 'assistant', content: JSON.stringify(document) }, finish_reason: 'stop' }], + usage: { prompt_tokens: 100, completion_tokens: 40, total_tokens: 140 }, + }) + }) + + const result = await new AgnesProvider(fetchMock).generateScript({ + instruction: '生成短剧', + projectName: '雾城来信', + genre: '悬疑', + visualBible: {}, + episodeTitle: '第一集', + synopsis: '调查线索', + targetDurationSeconds: 30, + safetyIdentifier: 'user-1', + }) + + expect(result).toMatchObject({ model: 'agnes-text-contract', document: { title: '雨夜来信' } }) + expect(result.usage).toEqual([ + { kind: 'TEXT_INPUT_TOKEN', quantity: 100, credits: 0.1 }, + { kind: 'TEXT_OUTPUT_TOKEN', quantity: 40, credits: 0.08 }, + ]) + }) + + it('generates an image without sending Agnes-unsupported response_format', async () => { + const fetchMock = vi.fn(async (_request, init) => { + const body = JSON.parse(init?.body as string) + expect(body).toMatchObject({ model: 'agnes-image-contract', prompt: expect.stringContaining('雨夜天台'), n: 1, size: '1536x864' }) + expect(body).not.toHaveProperty('response_format') + return jsonResponse({ data: [{ url: 'https://platform-outputs.agnes-ai.space/images/frame.webp' }] }) + }) + const result = await new AgnesProvider(fetchMock).generateImage({ + prompt: '雨夜天台', + negativePrompt: '文字水印', + width: 1536, + height: 864, + references: [], + referenceUrls: ['https://media.example/character.png'], + params: { response_format: 'b64_json', model: 'ignored' }, + safetyIdentifier: 'user-1', + }) + expect(result).toMatchObject({ + url: 'https://platform-outputs.agnes-ai.space/images/frame.webp', + sourceUrl: 'https://platform-outputs.agnes-ai.space/images/frame.webp', + mimeType: 'image/webp', + model: 'agnes-image-contract', + }) + }) + + it('uses the documented Agnes video request and result polling contracts', async () => { + let pollCount = 0 + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url.endsWith('/videos') && init?.method === 'POST') { + const body = JSON.parse(init.body as string) + expect(body).toMatchObject({ + model: 'agnes-video-contract', + prompt: '镜头缓慢推进', + image: 'https://media.example/source.png', + mode: 'ti2vid', + width: 1280, + height: 720, + num_frames: 121, + frame_rate: 24, + }) + expect(body).not.toHaveProperty('seconds') + expect(body).not.toHaveProperty('size') + expect(body).not.toHaveProperty('input_reference') + return jsonResponse({ task_id: 'task-contract', video_id: 'video-contract', status: 'queued', progress: 0 }) + } + if (url === 'https://api.agnes-ai.cn/agnesapi?video_id=video-contract' && init?.method === 'GET') { + pollCount += 1 + expect(new Headers(init.headers).get('authorization')).toBe('Bearer contract-agnes-secret') + return jsonResponse({ + id: 'task-contract', + status: 'completed', + progress: 100, + seconds: 5, + size: '1280x720', + metadata: { url: 'https://platform-outputs.agnes-ai.space/videos/agnes-video-v2.0/task-contract.mp4' }, + }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const result = await new AgnesProvider(fetchMock, { pollIntervalMs: 1, sleep: async () => undefined }).generateVideo({ + prompt: '镜头缓慢推进', + imageUrl: 'https://media.example/source.png', + imageData: Buffer.from('source-image'), + imageMimeType: 'image/png', + durationSeconds: 5, + params: { size: '1280x720' }, + }) + + expect(pollCount).toBe(1) + expect(result).toMatchObject({ + url: 'https://platform-outputs.agnes-ai.space/videos/agnes-video-v2.0/task-contract.mp4', + mimeType: 'video/mp4', + externalId: 'task-contract', + width: 1280, + height: 720, + usage: [{ kind: 'VIDEO_SECOND', quantity: 5, credits: 175 }], + }) + }) + + it('surfaces an Agnes result endpoint error', async () => { + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url.endsWith('/videos') && init?.method === 'POST') { + return jsonResponse({ task_id: 'task-invalid-content', video_id: 'video-invalid-content', status: 'queued', progress: 0 }) + } + if (url.includes('/agnesapi?') && init?.method === 'GET') { + return jsonResponse({ error: { message: 'upstream generation failed' } }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const request = new AgnesProvider(fetchMock, { pollIntervalMs: 1, sleep: async () => undefined }).generateVideo({ + prompt: 'test', + imageUrl: 'https://media.example/source.png', + durationSeconds: 4, + }) + + await expect(request).rejects.toThrow('Agnes video result retrieval failed: upstream generation failed') + }) + + it('backs off and continues when Agnes rate-limits result polling', async () => { + let pollCount = 0 + const sleeps: number[] = [] + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url.endsWith('/videos') && init?.method === 'POST') { + return jsonResponse({ task_id: 'task-rate-limit', video_id: 'video-rate-limit', status: 'queued' }) + } + if (url.includes('/agnesapi?') && init?.method === 'GET') { + pollCount += 1 + return jsonResponse({ error: { message: 'rate limited' } }, 429) + } + if (url.endsWith('/v1/videos/task-rate-limit') && init?.method === 'GET') { + pollCount += 1 + return jsonResponse({ + id: 'task-rate-limit', + status: 'completed', + metadata: { url: 'https://platform-outputs.agnes-ai.space/videos/complete.mp4' }, + }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const result = await new AgnesProvider(fetchMock, { + pollIntervalMs: 1, + predictionDeadlineSeconds: 120, + sleep: async (milliseconds) => { sleeps.push(milliseconds) }, + }).generateVideo({ + prompt: 'test', + imageUrl: 'https://media.example/source.png', + durationSeconds: 4, + }) + + expect(pollCount).toBe(2) + expect(sleeps).toEqual([1, 60_000, 1]) + expect(result.url).toBe('https://platform-outputs.agnes-ai.space/videos/complete.mp4') + }) + + it('falls back to the documented task_id result endpoint', async () => { + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url.endsWith('/videos') && init?.method === 'POST') { + const body = JSON.parse(init.body as string) + expect(body).toMatchObject({ width: 1280, height: 720 }) + return jsonResponse({ id: 'task-fallback', task_id: 'task-fallback', video_id: 'video-fallback', status: 'queued' }) + } + if (url === 'https://api.agnes-ai.cn/agnesapi?video_id=video-fallback') { + return jsonResponse({ id: 'task-fallback', status: 'in_progress', progress: 40 }) + } + if (url === 'https://api.agnes-ai.cn/v1/videos/task-fallback') { + return jsonResponse({ + id: 'task-fallback', + status: 'completed', + progress: 100, + metadata: { url: 'https://platform-outputs.agnes-ai.space/videos/fallback.mp4' }, + }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const result = await new AgnesProvider(fetchMock, { + pollIntervalMs: 1, + sleep: async () => undefined, + }).generateVideo({ + prompt: 'test', + imageUrl: 'https://media.example/source.png', + sourceWidth: 1536, + sourceHeight: 864, + durationSeconds: 4, + }) + + expect(result.url).toBe('https://platform-outputs.agnes-ai.space/videos/fallback.mp4') + }) + + it('accepts the top-level url returned by the live Agnes result endpoint', async () => { + let pollCount = 0 + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url.endsWith('/videos') && init?.method === 'POST') { + return jsonResponse({ id: 'task-live-shape', task_id: 'task-live-shape', video_id: 'video-live-shape', status: 'queued' }) + } + if (url.includes('/agnesapi?') && init?.method === 'GET') { + pollCount += 1 + return pollCount === 1 + ? jsonResponse({ id: 'video-live-shape', status: 'in_progress', progress: 30, url: null }) + : jsonResponse({ + id: 'video-live-shape', + status: 'completed', + progress: 100, + url: 'https://platform-outputs.agnes-ai.space/videos/live-shape.mp4', + }) + } + if (url.endsWith('/v1/videos/task-live-shape') && init?.method === 'GET') { + return jsonResponse({ + id: 'task-live-shape', + status: 'completed', + progress: 100, + url: 'https://platform-outputs.agnes-ai.space/videos/live-shape.mp4', + }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const result = await new AgnesProvider(fetchMock, { + pollIntervalMs: 1, + sleep: async () => undefined, + }).generateVideo({ + prompt: 'test', + imageUrl: 'https://media.example/source.png', + durationSeconds: 3, + }) + + expect(result.url).toBe('https://platform-outputs.agnes-ai.space/videos/live-shape.mp4') + }) + + it('rejects a non-public image URL before creating an Agnes video', async () => { + const fetchMock = vi.fn() + const request = new AgnesProvider(fetchMock).generateVideo({ + prompt: 'test', + imageUrl: 'http://127.0.0.1:9000/private.png', + durationSeconds: 4, + }) + + await expect(request).rejects.toThrow('Agnes image-to-video requires a publicly reachable HTTPS image URL') + expect(fetchMock).not.toHaveBeenCalled() + }) + + it('bounds provider failures without exposing the credential', async () => { + const fetchMock = vi.fn(async () => new Response(`failure contract-agnes-secret ${'x'.repeat(2000)}`, { status: 500 })) + const request = new AgnesProvider(fetchMock).generateImage({ + prompt: 'test', + width: 1024, + height: 1024, + references: [], + referenceUrls: [], + safetyIdentifier: 'user-1', + }) + await expect(request).rejects.toThrow(/^Agnes API 500:/) + await expect(request).rejects.not.toThrow('contract-agnes-secret') + }) +}) diff --git a/server/src/providers/agnes.ts b/server/src/providers/agnes.ts new file mode 100644 index 0000000..f45e9f7 --- /dev/null +++ b/server/src/providers/agnes.ts @@ -0,0 +1,467 @@ +import { setTimeout as delay } from 'node:timers/promises' +import { z } from 'zod' +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import { + scriptDocumentSchema, + scriptJsonSchema, + scriptToPlainText, + storyboardDocumentSchema, + storyboardJsonSchema, +} from './openai.js' +import type { + BinaryGenerationResult, + ImageGenerationInput, + ImageProvider, + LipsyncGenerationInput, + ScriptGenerationInput, + ScriptGenerationResult, + SpeechGenerationInput, + StoryboardGenerationInput, + StoryboardGenerationResult, + TextProvider, + VideoGenerationInput, + VideoProvider, +} from './types.js' + +export const agnesApiOrigin = 'https://api.agnes-ai.cn' +export const agnesApiBaseUrl = `${agnesApiOrigin}/v1` + +interface AgnesRuntimeOptions { + pollIntervalMs?: number + predictionDeadlineSeconds?: number + sleep?: (milliseconds: number) => Promise +} + +class AgnesProviderError extends Error { + constructor(message: string, readonly status?: number) { + super(message) + this.name = 'AgnesProviderError' + } +} + +class AgnesRateLimitError extends AgnesProviderError { + constructor(readonly retryAfterMs: number) { + super('Agnes video generation is temporarily rate limited', 429) + this.name = 'AgnesRateLimitError' + } +} + +const videoResponseSchema = z.object({ + id: z.string().trim().min(1).max(512).optional(), + task_id: z.string().trim().min(1).max(512).nullable().optional(), + video_id: z.string().trim().min(1).max(2048).nullable().optional(), + object: z.literal('video').optional(), + status: z.enum(['queued', 'in_progress', 'completed', 'failed']), + progress: z.number().finite().min(0).max(100).optional(), + seconds: z.union([z.string(), z.number()]).optional(), + size: z.string().trim().max(40).optional(), + url: z.string().url().nullable().optional(), + metadata: z.object({ + url: z.string().url().optional(), + }).passthrough().nullable().optional(), + error: z.object({ message: z.string().max(10_000) }).passthrough().nullable().optional(), +}).passthrough().refine((value) => Boolean(value.id || value.task_id || value.video_id), { + message: 'A video task identifier is required', +}) + +function requireApiKey() { + if (!config.AGNES_API_KEY) throw errors.badRequest('AGNES_API_KEY is not configured') + return config.AGNES_API_KEY +} + +function boundedErrorText(value: string) { + const secret = config.AGNES_API_KEY + return value.replace(secret ?? '', '[redacted]').slice(0, 1000) +} + +function retryAfterMilliseconds(response: Response) { + const value = response.headers.get('retry-after') + if (value) { + const seconds = Number(value) + if (Number.isFinite(seconds) && seconds >= 0) return Math.max(1000, Math.min(300_000, seconds * 1000)) + const date = Date.parse(value) + if (Number.isFinite(date)) return Math.max(1000, Math.min(300_000, date - Date.now())) + } + return 60_000 +} + +function parseJsonContent(value: string, label: string) { + const normalized = value.trim().replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/i, '') + try { + return JSON.parse(normalized) as unknown + } catch { + throw new AgnesProviderError(`Agnes returned malformed JSON for ${label}`) + } +} + +function messageContent(response: unknown) { + if (!response || typeof response !== 'object' || !('choices' in response) || !Array.isArray(response.choices)) { + throw new AgnesProviderError('Agnes returned an invalid chat response') + } + const message = response.choices[0] && typeof response.choices[0] === 'object' && 'message' in response.choices[0] + ? response.choices[0].message + : null + if (!message || typeof message !== 'object' || !('content' in message)) throw new AgnesProviderError('Agnes returned an empty chat response') + const content = message.content + if (typeof content === 'string') return content + if (Array.isArray(content)) { + return content.map((part) => part && typeof part === 'object' && 'text' in part && typeof part.text === 'string' ? part.text : '').join('') + } + throw new AgnesProviderError('Agnes returned an empty chat response') +} + +function usageRows(usage: unknown) { + if (!usage || typeof usage !== 'object') return [] + const input = 'prompt_tokens' in usage && typeof usage.prompt_tokens === 'number' ? usage.prompt_tokens : 0 + const output = 'completion_tokens' in usage && typeof usage.completion_tokens === 'number' ? usage.completion_tokens : 0 + return [ + ...(input > 0 ? [{ kind: 'TEXT_INPUT_TOKEN' as const, quantity: input, credits: input / 1000 }] : []), + ...(output > 0 ? [{ kind: 'TEXT_OUTPUT_TOKEN' as const, quantity: output, credits: output / 500 }] : []), + ] +} + +function imageMimeType(url: string) { + try { + const pathname = new URL(url).pathname.toLowerCase() + if (pathname.endsWith('.jpg') || pathname.endsWith('.jpeg')) return 'image/jpeg' + if (pathname.endsWith('.webp')) return 'image/webp' + } catch { + // The media downloader performs the authoritative URL validation. + } + return 'image/png' +} + +function normalizeFrameRate(value: unknown) { + return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 60 ? value : 24 +} + +function normalizeFrameCount(durationSeconds: number, frameRate: number, value: unknown) { + if (typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 441 && (value - 1) % 8 === 0) return value + const closest = Math.round((durationSeconds * frameRate - 1) / 8) * 8 + 1 + return Math.min(441, Math.max(1, closest)) +} + +function videoDimensions(input: VideoGenerationInput) { + const explicitWidth = input.params?.width + const explicitHeight = input.params?.height + if (typeof explicitWidth === 'number' && Number.isInteger(explicitWidth) && explicitWidth > 0 + && typeof explicitHeight === 'number' && Number.isInteger(explicitHeight) && explicitHeight > 0) { + return { width: explicitWidth, height: explicitHeight } + } + const size = typeof input.params?.size === 'string' ? /^(\d+)x(\d+)$/.exec(input.params.size) : null + if (size) return { width: Number(size[1]), height: Number(size[2]) } + if (input.sourceWidth && input.sourceHeight) { + const scale = Math.min(1, 1280 / Math.max(input.sourceWidth, input.sourceHeight)) + return { + width: Math.max(16, Math.round(input.sourceWidth * scale / 16) * 16), + height: Math.max(16, Math.round(input.sourceHeight * scale / 16) * 16), + } + } + return { width: 1152, height: 768 } +} + +function requirePublicImageUrl(value: string) { + try { + const url = new URL(value) + if (url.protocol !== 'https:' || url.username || url.password) throw new Error('invalid') + return url.toString() + } catch { + throw errors.badRequest('Agnes image-to-video requires a publicly reachable HTTPS image URL') + } +} + +function parseVideo(value: unknown, operation: string) { + if (value && typeof value === 'object' && 'error' in value && value.error && typeof value.error === 'object' + && 'message' in value.error && typeof value.error.message === 'string') { + throw new AgnesProviderError(`Agnes video ${operation} failed: ${boundedErrorText(value.error.message)}`) + } + const parsed = videoResponseSchema.safeParse(value) + if (!parsed.success) throw new AgnesProviderError('Agnes returned a malformed video response') + return parsed.data +} + +function dimensionsFromSize(value: string | undefined) { + const match = /^(\d+)x(\d+)$/.exec(value ?? '') + return match ? { width: Number(match[1]), height: Number(match[2]) } : {} +} + +function videoOutputUrl(video: z.infer) { + return video.metadata?.url || video.url || undefined +} + +export class AgnesProvider implements TextProvider, ImageProvider, VideoProvider { + readonly name = 'agnes' + private readonly apiKey: string + private readonly pollIntervalMs: number + private readonly predictionDeadlineSeconds: number + private readonly sleep: (milliseconds: number) => Promise + + constructor( + private readonly fetchImpl: typeof fetch = fetch, + options: AgnesRuntimeOptions = {}, + ) { + this.apiKey = requireApiKey() + this.pollIntervalMs = options.pollIntervalMs ?? config.AGNES_VIDEO_POLL_INTERVAL_MS + this.predictionDeadlineSeconds = options.predictionDeadlineSeconds ?? config.AGNES_VIDEO_PREDICTION_DEADLINE_SECONDS + this.sleep = options.sleep ?? ((milliseconds) => delay(milliseconds)) + } + + private async requestJson(path: string, body: Record) { + let response: Response + try { + response = await this.fetchImpl(`${agnesApiBaseUrl}${path}`, { + method: 'POST', + headers: { + Authorization: `Bearer ${this.apiKey}`, + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + signal: AbortSignal.timeout(180_000), + }) + } catch (error) { + if (error && typeof error === 'object' && 'name' in error && (error.name === 'AbortError' || error.name === 'TimeoutError')) { + throw new AgnesProviderError('Agnes request timed out') + } + throw new AgnesProviderError('Unable to connect to Agnes') + } + const text = await response.text() + if (response.status === 429) throw new AgnesRateLimitError(retryAfterMilliseconds(response)) + if (!response.ok) throw new AgnesProviderError(`Agnes API ${response.status}: ${boundedErrorText(text)}`, response.status) + try { + return JSON.parse(text) as unknown + } catch { + throw new AgnesProviderError('Agnes returned invalid JSON') + } + } + + private async requestGetUrl(url: string) { + let response: Response + try { + response = await this.fetchImpl(url, { + method: 'GET', + headers: { Authorization: `Bearer ${this.apiKey}`, Accept: 'application/json' }, + signal: AbortSignal.timeout(180_000), + }) + } catch { + throw new AgnesProviderError('Unable to connect to Agnes') + } + const text = await response.text() + if (response.status === 429) throw new AgnesRateLimitError(retryAfterMilliseconds(response)) + if (!response.ok) throw new AgnesProviderError(`Agnes API ${response.status}: ${boundedErrorText(text)}`, response.status) + try { + return JSON.parse(text) as unknown + } catch { + throw new AgnesProviderError('Agnes returned invalid JSON') + } + } + + async generateScript(input: ScriptGenerationInput): Promise { + const response = await this.requestJson('/chat/completions', { + model: config.AGNES_TEXT_MODEL, + messages: [ + { + role: 'system', + content: [ + '你是专业的中文漫剧编剧。只输出 JSON,不要 Markdown 代码围栏或解释。', + '故事必须可拍摄、镜头动作明确、对白简洁,并保持角色动机连续。', + `输出必须符合此 JSON Schema:${JSON.stringify(scriptJsonSchema)}`, + ].join('\n'), + }, + { + role: 'user', + content: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + synopsis: input.synopsis, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + existingScript: input.existingScript ?? null, + }), + }, + ], + response_format: { type: 'json_object' }, + temperature: 0.4, + max_tokens: 12_000, + }) + const document = scriptDocumentSchema.safeParse(parseJsonContent(messageContent(response), 'script')) + if (!document.success) throw new AgnesProviderError('Agnes returned a script that does not match the required schema') + return { + document: document.data, + plainText: scriptToPlainText(document.data), + model: config.AGNES_TEXT_MODEL, + usage: usageRows(response && typeof response === 'object' && 'usage' in response ? response.usage : null), + } + } + + async generateStoryboard(input: StoryboardGenerationInput): Promise { + const response = await this.requestJson('/chat/completions', { + model: config.AGNES_TEXT_MODEL, + messages: [ + { + role: 'system', + content: [ + '你是专业的中文漫剧分镜导演。只输出 JSON,不要 Markdown 代码围栏或解释。', + '把完整剧本拆成可独立生成画面和视频的镜头,画面描述明确人物、动作、构图、光线和环境。', + 'subtitleText 只保留当前镜头需要朗读的对白或旁白;无对白时输出空字符串。', + `输出必须符合此 JSON Schema:${JSON.stringify(storyboardJsonSchema)}`, + ].join('\n'), + }, + { + role: 'user', + content: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + availableCharacters: input.characterNames, + availableScenes: input.sceneNames, + script: input.script, + }), + }, + ], + response_format: { type: 'json_object' }, + temperature: 0.4, + max_tokens: 12_000, + }) + const document = storyboardDocumentSchema.safeParse(parseJsonContent(messageContent(response), 'storyboard')) + if (!document.success) throw new AgnesProviderError('Agnes returned a storyboard that does not match the required schema') + return { + shots: document.data.shots, + model: config.AGNES_TEXT_MODEL, + usage: usageRows(response && typeof response === 'object' && 'usage' in response ? response.usage : null), + } + } + + async generateImage(input: ImageGenerationInput): Promise { + const references = input.referenceUrls.length > 0 + ? `\n保持以下项目参考媒体所代表的角色和场景连续性(参考资产 ID 已在工作流中保存):${input.referenceUrls.join(', ')}` + : '' + const prompt = [input.prompt, input.negativePrompt ? `Avoid: ${input.negativePrompt}` : '', references].filter(Boolean).join('\n') + const customParams = { ...(input.params ?? {}) } + ;['model', 'prompt', 'n', 'size', 'response_format'].forEach((key) => delete customParams[key]) + const response = await this.requestJson('/images/generations', { + ...customParams, + model: config.AGNES_IMAGE_MODEL, + prompt, + n: 1, + size: `${input.width}x${input.height}`, + }) + if (!response || typeof response !== 'object' || !('data' in response) || !Array.isArray(response.data)) { + throw new AgnesProviderError('Agnes returned an invalid image response') + } + const image = response.data[0] + if (!image || typeof image !== 'object') throw new AgnesProviderError('Agnes returned no image data') + if ('b64_json' in image && typeof image.b64_json === 'string' && image.b64_json.length > 0) { + return { + data: Buffer.from(image.b64_json, 'base64'), + mimeType: 'image/png', + model: config.AGNES_IMAGE_MODEL, + width: input.width, + height: input.height, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 120 }], + } + } + if ('url' in image && typeof image.url === 'string' && image.url.length > 0) { + return { + url: image.url, + sourceUrl: image.url, + mimeType: imageMimeType(image.url), + model: config.AGNES_IMAGE_MODEL, + width: input.width, + height: input.height, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 120 }], + } + } + throw new AgnesProviderError('Agnes returned no image data') + } + + async generateVideo(input: VideoGenerationInput): Promise { + const startedAt = Date.now() + const frameRate = normalizeFrameRate(input.params?.frame_rate) + const numFrames = normalizeFrameCount(input.durationSeconds, frameRate, input.params?.num_frames) + const dimensions = videoDimensions(input) + const customParams = { ...(input.params ?? {}) } + ;['model', 'prompt', 'image', 'mode', 'height', 'width', 'num_frames', 'frame_rate', 'extra_body', 'seconds', 'size', 'input_reference'].forEach((key) => delete customParams[key]) + const createBody = { + ...customParams, + model: config.AGNES_VIDEO_MODEL, + prompt: input.prompt, + image: requirePublicImageUrl(input.imageUrl), + mode: 'ti2vid', + width: dimensions.width, + height: dimensions.height, + num_frames: numFrames, + frame_rate: frameRate, + } + let initial: z.infer + while (true) { + try { + initial = parseVideo(await this.requestJson('/videos', createBody), 'creation') + break + } catch (error) { + if (!(error instanceof AgnesRateLimitError)) throw error + if (Date.now() - startedAt + error.retryAfterMs > this.predictionDeadlineSeconds * 1000) { + throw new AgnesProviderError(`Agnes video generation exceeded the ${this.predictionDeadlineSeconds}s deadline`) + } + await this.sleep(error.retryAfterMs) + } + } + const resultVideoId = initial.video_id || initial.task_id || initial.id! + const resultUrl = new URL('/agnesapi', agnesApiOrigin) + resultUrl.searchParams.set('video_id', resultVideoId) + const legacyTaskId = initial.task_id || initial.id + const legacyResultUrl = legacyTaskId + ? `${agnesApiBaseUrl}/videos/${encodeURIComponent(legacyTaskId)}` + : null + let current = initial + let useLegacyResult = false + while (current.status !== 'completed' || !videoOutputUrl(current)) { + if (current.status === 'failed') throw new AgnesProviderError(current.error?.message || 'Agnes video generation failed') + if (Date.now() - startedAt > this.predictionDeadlineSeconds * 1000) { + throw new AgnesProviderError( + `Agnes video ${resultVideoId} remained ${current.status} at ${current.progress ?? 0}% after the ${this.predictionDeadlineSeconds}s deadline`, + ) + } + await this.sleep(this.pollIntervalMs) + try { + const pollUrl = useLegacyResult && legacyResultUrl ? legacyResultUrl : resultUrl.toString() + useLegacyResult = legacyResultUrl ? !useLegacyResult : false + current = parseVideo(await this.requestGetUrl(pollUrl), 'result retrieval') + } catch (error) { + if (!(error instanceof AgnesRateLimitError)) throw error + if (Date.now() - startedAt + error.retryAfterMs > this.predictionDeadlineSeconds * 1000) { + throw new AgnesProviderError( + `Agnes video ${resultVideoId} remained ${current.status} at ${current.progress ?? 0}% after the ${this.predictionDeadlineSeconds}s deadline`, + ) + } + await this.sleep(error.retryAfterMs) + } + } + const actualSeconds = Number(current.seconds) || numFrames / frameRate + const size = dimensionsFromSize(current.size) + const outputUrl = videoOutputUrl(current) + if (!outputUrl) throw new AgnesProviderError('Agnes completed the video without an output URL') + return { + url: outputUrl, + mimeType: 'video/mp4', + model: config.AGNES_VIDEO_MODEL, + externalId: initial.task_id || initial.id || initial.video_id!, + ...size, + usage: [{ kind: 'VIDEO_SECOND', quantity: actualSeconds, credits: actualSeconds * 35 }], + } + } + + async generateLipsync(_input: LipsyncGenerationInput): Promise { + throw errors.badRequest('Agnes does not provide lip-sync generation') + } + + async generateSpeech(_input: SpeechGenerationInput): Promise { + throw errors.badRequest('Agnes does not provide speech generation') + } +} diff --git a/server/src/providers/index.ts b/server/src/providers/index.ts new file mode 100644 index 0000000..07bacd1 --- /dev/null +++ b/server/src/providers/index.ts @@ -0,0 +1,34 @@ +import { AgnesProvider } from './agnes.js' +import { GenericOpenAICompatibleProvider } from './openai-compatible.js' +import { OpenAIProvider } from './openai.js' +import { ReplicateProvider } from './replicate.js' +import type { ImageProvider, SpeechProvider, TextProvider, VideoProvider } from './types.js' + +export function textProvider(name = 'openai'): TextProvider { + if (name === 'openai') return new OpenAIProvider() + if (name === 'agnes') return new AgnesProvider() + if (name === 'generic') return new GenericOpenAICompatibleProvider() + throw new Error(`Unknown text provider: ${name}`) +} + +export function imageProvider(name = 'openai'): ImageProvider { + if (name === 'openai') return new OpenAIProvider() + if (name === 'replicate') return new ReplicateProvider() + if (name === 'agnes') return new AgnesProvider() + if (name === 'generic') return new GenericOpenAICompatibleProvider() + throw new Error(`Unknown image provider: ${name}`) +} + +export function speechProvider(name = 'openai'): SpeechProvider { + if (name === 'openai') return new OpenAIProvider() + throw new Error(`Unknown speech provider: ${name}`) +} + +export function videoProvider(name = 'replicate'): VideoProvider { + if (name === 'replicate') return new ReplicateProvider() + if (name === 'agnes') return new AgnesProvider() + if (name === 'generic') return new GenericOpenAICompatibleProvider() + throw new Error(`Unknown video provider: ${name}`) +} + +export type * from './types.js' diff --git a/server/src/providers/openai-compatible.contract.test.ts b/server/src/providers/openai-compatible.contract.test.ts new file mode 100644 index 0000000..f683271 --- /dev/null +++ b/server/src/providers/openai-compatible.contract.test.ts @@ -0,0 +1,184 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { config } from '../config.js' +import { GenericOpenAICompatibleProvider } from './openai-compatible.js' + +const originalConfiguration = { + textApiKey: config.GENERIC_TEXT_API_KEY, + textBaseUrl: config.GENERIC_TEXT_BASE_URL, + textModel: config.GENERIC_TEXT_MODEL, + imageApiKey: config.GENERIC_IMAGE_API_KEY, + imageBaseUrl: config.GENERIC_IMAGE_BASE_URL, + imageModel: config.GENERIC_IMAGE_MODEL, + videoApiKey: config.GENERIC_VIDEO_API_KEY, + videoBaseUrl: config.GENERIC_VIDEO_BASE_URL, + videoModel: config.GENERIC_VIDEO_MODEL, +} + +function jsonResponse(payload: unknown, status = 200) { + return new Response(JSON.stringify(payload), { status, headers: { 'content-type': 'application/json' } }) +} + +beforeAll(() => { + config.GENERIC_TEXT_API_KEY = 'generic-text-secret' + config.GENERIC_TEXT_BASE_URL = 'https://text.vendor.test/v1' + config.GENERIC_TEXT_MODEL = 'vendor-text-model' + config.GENERIC_IMAGE_API_KEY = 'generic-image-secret' + config.GENERIC_IMAGE_BASE_URL = 'https://image.vendor.test/api/v1/' + config.GENERIC_IMAGE_MODEL = 'vendor-image-model' + config.GENERIC_VIDEO_API_KEY = 'generic-video-secret' + config.GENERIC_VIDEO_BASE_URL = 'https://video.vendor.test/v1' + config.GENERIC_VIDEO_MODEL = 'vendor-video-model' +}) + +afterAll(() => { + config.GENERIC_TEXT_API_KEY = originalConfiguration.textApiKey + config.GENERIC_TEXT_BASE_URL = originalConfiguration.textBaseUrl + config.GENERIC_TEXT_MODEL = originalConfiguration.textModel + config.GENERIC_IMAGE_API_KEY = originalConfiguration.imageApiKey + config.GENERIC_IMAGE_BASE_URL = originalConfiguration.imageBaseUrl + config.GENERIC_IMAGE_MODEL = originalConfiguration.imageModel + config.GENERIC_VIDEO_API_KEY = originalConfiguration.videoApiKey + config.GENERIC_VIDEO_BASE_URL = originalConfiguration.videoBaseUrl + config.GENERIC_VIDEO_MODEL = originalConfiguration.videoModel +}) + +describe('generic OpenAI-compatible provider contract', () => { + it('uses the independently configured text endpoint and validates script JSON', async () => { + const document = { + title: '通用接口剧本', + logline: '一封信改变调查方向。', + estimatedDurationSeconds: 30, + scenes: [{ + number: 1, + location: '档案室', + interiorExterior: '内', + time: '夜', + summary: '主角找到线索。', + beats: [{ type: 'action', text: '灯光闪烁。', character: null, parenthetical: null }], + }], + } + const fetchMock = vi.fn(async (request, init) => { + expect(String(request)).toBe('https://text.vendor.test/v1/chat/completions') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer generic-text-secret') + const body = JSON.parse(init?.body as string) + expect(body).toMatchObject({ model: 'vendor-text-model', response_format: { type: 'json_object' } }) + return jsonResponse({ + choices: [{ message: { content: JSON.stringify(document) } }], + usage: { prompt_tokens: 80, completion_tokens: 20 }, + }) + }) + + const result = await new GenericOpenAICompatibleProvider(fetchMock).generateScript({ + instruction: '生成悬疑短剧', + projectName: '夜间档案', + genre: '悬疑', + visualBible: {}, + episodeTitle: '第一集', + synopsis: '寻找旧案线索', + targetDurationSeconds: 30, + safetyIdentifier: 'user-1', + }) + + expect(result).toMatchObject({ model: 'vendor-text-model', document: { title: '通用接口剧本' } }) + expect(result.usage).toEqual([ + { kind: 'TEXT_INPUT_TOKEN', quantity: 80, credits: 0.08 }, + { kind: 'TEXT_OUTPUT_TOKEN', quantity: 20, credits: 0.04 }, + ]) + }) + + it('uses multipart image edits when continuity references are supplied', async () => { + const fetchMock = vi.fn(async (request, init) => { + expect(String(request)).toBe('https://image.vendor.test/api/v1/images/edits') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer generic-image-secret') + expect(new Headers(init?.headers).has('content-type')).toBe(false) + expect(init?.body).toBeInstanceOf(FormData) + const form = init?.body as FormData + expect(form.get('model')).toBe('vendor-image-model') + expect(form.get('size')).toBe('1024x1024') + expect(form.getAll('image')).toHaveLength(1) + return jsonResponse({ data: [{ url: 'https://cdn.vendor.test/generated/frame.webp' }] }) + }) + + const result = await new GenericOpenAICompatibleProvider(fetchMock).generateImage({ + prompt: '角色转身看向镜头', + width: 1024, + height: 1024, + references: [{ name: 'character.png', mimeType: 'image/png', data: Buffer.from('reference-image') }], + referenceUrls: ['https://media.example/reference.png'], + safetyIdentifier: 'user-1', + }) + + expect(result).toMatchObject({ + url: 'https://cdn.vendor.test/generated/frame.webp', + sourceUrl: 'https://cdn.vendor.test/generated/frame.webp', + mimeType: 'image/webp', + model: 'vendor-image-model', + }) + }) + + it('creates, polls, and downloads a generic asynchronous video job', async () => { + const videoData = Buffer.concat([Buffer.from([0, 0, 0, 24]), Buffer.from('ftypisom'), Buffer.from('generic-contract-mp4')]) + let pollCount = 0 + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + if (url === 'https://video.vendor.test/v1/videos' && init?.method === 'POST') { + expect(new Headers(init.headers).get('authorization')).toBe('Bearer generic-video-secret') + const form = init.body as FormData + expect(form.get('model')).toBe('vendor-video-model') + expect(form.get('prompt')).toBe('镜头向人物推进') + expect(form.get('seconds')).toBe('5') + expect(form.get('size')).toBe('1280x720') + expect(form.get('input_reference')).toBeInstanceOf(Blob) + return jsonResponse({ id: 'video-contract', status: 'queued', progress: 0 }) + } + if (url === 'https://video.vendor.test/v1/videos/video-contract' && init?.method === 'GET') { + pollCount += 1 + return jsonResponse({ id: 'video-contract', status: 'completed', seconds: '5', size: '1280x720', model: 'vendor-video-output' }) + } + if (url === 'https://video.vendor.test/v1/videos/video-contract/content' && init?.method === 'GET') { + expect(new Headers(init.headers).get('authorization')).toBe('Bearer generic-video-secret') + return new Response(videoData, { status: 200, headers: { 'content-type': 'video/mp4' } }) + } + return new Response('unexpected request', { status: 500 }) + }) + + const result = await new GenericOpenAICompatibleProvider(fetchMock, { + pollIntervalMs: 1, + sleep: async () => undefined, + }).generateVideo({ + prompt: '镜头向人物推进', + imageUrl: 'https://media.example/source.png', + imageData: Buffer.from('source-image'), + imageMimeType: 'image/png', + sourceWidth: 1280, + sourceHeight: 720, + durationSeconds: 5, + }) + + expect(pollCount).toBe(1) + expect(result).toMatchObject({ + data: videoData, + mimeType: 'video/mp4', + model: 'vendor-video-output', + externalId: 'video-contract', + width: 1280, + height: 720, + usage: [{ kind: 'VIDEO_SECOND', quantity: 5, credits: 175 }], + }) + }) + + it('redacts independently configured credentials from provider failures', async () => { + const fetchMock = vi.fn(async () => new Response(`failure generic-image-secret ${'x'.repeat(2000)}`, { status: 500 })) + const request = new GenericOpenAICompatibleProvider(fetchMock).generateImage({ + prompt: 'test', + width: 1024, + height: 1024, + references: [], + referenceUrls: [], + safetyIdentifier: 'user-1', + }) + + await expect(request).rejects.not.toThrow('generic-image-secret') + await expect(request).rejects.toThrow(/Generic provider API 500/) + }) +}) diff --git a/server/src/providers/openai-compatible.ts b/server/src/providers/openai-compatible.ts new file mode 100644 index 0000000..3307c54 --- /dev/null +++ b/server/src/providers/openai-compatible.ts @@ -0,0 +1,432 @@ +import { setTimeout as delay } from 'node:timers/promises' +import { z } from 'zod' +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import { + scriptDocumentSchema, + scriptJsonSchema, + scriptToPlainText, + storyboardDocumentSchema, + storyboardJsonSchema, +} from './openai.js' +import type { + BinaryGenerationResult, + ImageGenerationInput, + ImageProvider, + LipsyncGenerationInput, + ScriptGenerationInput, + ScriptGenerationResult, + StoryboardGenerationInput, + StoryboardGenerationResult, + TextProvider, + VideoGenerationInput, + VideoProvider, +} from './types.js' + +interface GenericRuntimeOptions { + pollIntervalMs?: number + predictionDeadlineSeconds?: number + sleep?: (milliseconds: number) => Promise +} + +interface CapabilityConfiguration { + apiKey: string + baseUrl: string + model: string +} + +class GenericProviderError extends Error { + constructor(message: string, readonly status?: number) { + super(message) + this.name = 'GenericProviderError' + } +} + +const videoResponseSchema = z.object({ + id: z.string().trim().min(1).max(2048), + status: z.enum(['queued', 'in_progress', 'processing', 'completed', 'succeeded', 'failed', 'canceled']), + progress: z.number().finite().min(0).max(100).optional(), + seconds: z.union([z.string(), z.number()]).optional(), + size: z.string().trim().max(40).optional(), + model: z.string().trim().min(1).max(255).optional(), + url: z.string().url().optional(), + output_url: z.string().url().optional(), + metadata: z.object({ url: z.string().url().optional() }).passthrough().nullable().optional(), + data: z.array(z.object({ url: z.string().url().optional() }).passthrough()).optional(), + output: z.array(z.object({ url: z.string().url().optional() }).passthrough()).optional(), + error: z.union([ + z.string().max(10_000), + z.object({ message: z.string().max(10_000) }).passthrough(), + ]).nullable().optional(), +}).passthrough() + +function capabilityConfiguration(kind: 'text' | 'image' | 'video'): CapabilityConfiguration { + const values = kind === 'text' + ? [config.GENERIC_TEXT_API_KEY, config.GENERIC_TEXT_BASE_URL, config.GENERIC_TEXT_MODEL] + : kind === 'image' + ? [config.GENERIC_IMAGE_API_KEY, config.GENERIC_IMAGE_BASE_URL, config.GENERIC_IMAGE_MODEL] + : [config.GENERIC_VIDEO_API_KEY, config.GENERIC_VIDEO_BASE_URL, config.GENERIC_VIDEO_MODEL] + const [apiKey, baseUrl, model] = values + if (!apiKey || !baseUrl || !model) { + throw errors.badRequest(`GENERIC_${kind.toUpperCase()}_API_KEY, BASE_URL, and MODEL must be configured together`) + } + return { apiKey, baseUrl, model } +} + +function endpoint(baseUrl: string, path: string) { + const base = new URL(baseUrl) + if (base.username || base.password || base.search || base.hash) { + throw errors.badRequest('Generic provider BASE_URL must not contain credentials, query parameters, or a fragment') + } + return `${base.toString().replace(/\/$/, '')}/${path.replace(/^\//, '')}` +} + +function boundedErrorText(value: string) { + const secrets = [config.GENERIC_TEXT_API_KEY, config.GENERIC_IMAGE_API_KEY, config.GENERIC_VIDEO_API_KEY] + .filter((secret): secret is string => Boolean(secret)) + return secrets.reduce((text, secret) => text.replaceAll(secret, '[redacted]'), value).slice(0, 1000) +} + +function imageMimeType(url: string) { + try { + const pathname = new URL(url).pathname.toLowerCase() + if (pathname.endsWith('.jpg') || pathname.endsWith('.jpeg')) return 'image/jpeg' + if (pathname.endsWith('.webp')) return 'image/webp' + } catch { + // The shared media downloader performs authoritative URL validation. + } + return 'image/png' +} + +function messageContent(response: unknown) { + if (!response || typeof response !== 'object' || !('choices' in response) || !Array.isArray(response.choices)) { + throw new GenericProviderError('Generic text provider returned an invalid chat response') + } + const first = response.choices[0] + const message = first && typeof first === 'object' && 'message' in first ? first.message : null + if (!message || typeof message !== 'object' || !('content' in message)) { + throw new GenericProviderError('Generic text provider returned an empty chat response') + } + if (typeof message.content === 'string') return message.content + if (Array.isArray(message.content)) { + return message.content + .map((part: unknown) => part && typeof part === 'object' && 'text' in part && typeof part.text === 'string' ? part.text : '') + .join('') + } + throw new GenericProviderError('Generic text provider returned an empty chat response') +} + +function parseJsonContent(value: string, label: string) { + const normalized = value.trim().replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/i, '') + try { + return JSON.parse(normalized) as unknown + } catch { + throw new GenericProviderError(`Generic text provider returned malformed JSON for ${label}`) + } +} + +function usageRows(response: unknown) { + const usage = response && typeof response === 'object' && 'usage' in response ? response.usage : null + if (!usage || typeof usage !== 'object') return [] + const input = 'prompt_tokens' in usage && typeof usage.prompt_tokens === 'number' ? usage.prompt_tokens : 0 + const output = 'completion_tokens' in usage && typeof usage.completion_tokens === 'number' ? usage.completion_tokens : 0 + return [ + ...(input > 0 ? [{ kind: 'TEXT_INPUT_TOKEN' as const, quantity: input, credits: input / 1000 }] : []), + ...(output > 0 ? [{ kind: 'TEXT_OUTPUT_TOKEN' as const, quantity: output, credits: output / 500 }] : []), + ] +} + +function appendFormValue(form: FormData, key: string, value: unknown) { + if (value === undefined || value === null) return + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + form.append(key, String(value)) + return + } + form.append(key, JSON.stringify(value)) +} + +function outputVideoUrl(video: z.infer) { + return video.url + || video.output_url + || video.metadata?.url + || video.data?.find((item) => item.url)?.url + || video.output?.find((item) => item.url)?.url +} + +function videoDimensions(input: VideoGenerationInput) { + const requestedSize = typeof input.params?.size === 'string' && /^\d+x\d+$/.test(input.params.size) + ? input.params.size + : null + if (requestedSize) return requestedSize + if (input.sourceWidth && input.sourceHeight) return `${input.sourceWidth}x${input.sourceHeight}` + return '1280x720' +} + +function dimensionsFromSize(value: string | undefined) { + const match = /^(\d+)x(\d+)$/.exec(value ?? '') + return match ? { width: Number(match[1]), height: Number(match[2]) } : {} +} + +function parseVideo(value: unknown) { + const parsed = videoResponseSchema.safeParse(value) + if (!parsed.success) throw new GenericProviderError('Generic video provider returned a malformed response') + return parsed.data +} + +export class GenericOpenAICompatibleProvider implements TextProvider, ImageProvider, VideoProvider { + readonly name = 'generic' + private readonly pollIntervalMs: number + private readonly predictionDeadlineSeconds: number + private readonly sleep: (milliseconds: number) => Promise + + constructor( + private readonly fetchImpl: typeof fetch = fetch, + options: GenericRuntimeOptions = {}, + ) { + this.pollIntervalMs = options.pollIntervalMs ?? config.GENERIC_VIDEO_POLL_INTERVAL_MS + this.predictionDeadlineSeconds = options.predictionDeadlineSeconds ?? config.GENERIC_VIDEO_PREDICTION_DEADLINE_SECONDS + this.sleep = options.sleep ?? ((milliseconds) => delay(milliseconds)) + } + + private async requestJson(configuration: CapabilityConfiguration, path: string, init: RequestInit) { + let response: Response + try { + response = await this.fetchImpl(endpoint(configuration.baseUrl, path), { + ...init, + headers: { + Authorization: `Bearer ${configuration.apiKey}`, + Accept: 'application/json', + ...init.headers, + }, + signal: AbortSignal.timeout(180_000), + }) + } catch (error) { + const name = error && typeof error === 'object' && 'name' in error ? error.name : null + if (name === 'AbortError' || name === 'TimeoutError') throw new GenericProviderError('Generic provider request timed out') + throw new GenericProviderError('Unable to connect to generic provider') + } + const text = await response.text() + if (!response.ok) throw new GenericProviderError(`Generic provider API ${response.status}: ${boundedErrorText(text)}`, response.status) + try { + return JSON.parse(text) as unknown + } catch { + throw new GenericProviderError('Generic provider returned invalid JSON') + } + } + + private async postJson(configuration: CapabilityConfiguration, path: string, body: Record) { + return this.requestJson(configuration, path, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }) + } + + async generateScript(input: ScriptGenerationInput): Promise { + const configuration = capabilityConfiguration('text') + const response = await this.postJson(configuration, '/chat/completions', { + model: configuration.model, + messages: [ + { + role: 'system', + content: [ + '你是专业的中文漫剧编剧。只输出 JSON,不要 Markdown 代码围栏或解释。', + '故事必须可拍摄、镜头动作明确、对白简洁,并保持角色动机连续。', + `输出必须符合此 JSON Schema:${JSON.stringify(scriptJsonSchema)}`, + ].join('\n'), + }, + { + role: 'user', + content: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + synopsis: input.synopsis, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + existingScript: input.existingScript ?? null, + }), + }, + ], + response_format: { type: 'json_object' }, + temperature: 0.4, + max_tokens: 12_000, + }) + const document = scriptDocumentSchema.safeParse(parseJsonContent(messageContent(response), 'script')) + if (!document.success) throw new GenericProviderError('Generic text provider returned a script that does not match the required schema') + return { + document: document.data, + plainText: scriptToPlainText(document.data), + model: configuration.model, + usage: usageRows(response), + } + } + + async generateStoryboard(input: StoryboardGenerationInput): Promise { + const configuration = capabilityConfiguration('text') + const response = await this.postJson(configuration, '/chat/completions', { + model: configuration.model, + messages: [ + { + role: 'system', + content: [ + '你是专业的中文漫剧分镜导演。只输出 JSON,不要 Markdown 代码围栏或解释。', + '把完整剧本拆成可独立生成画面和视频的镜头,明确人物、动作、构图、光线和环境。', + 'subtitleText 只保留当前镜头需要朗读的对白或旁白;无对白时输出空字符串。', + `输出必须符合此 JSON Schema:${JSON.stringify(storyboardJsonSchema)}`, + ].join('\n'), + }, + { + role: 'user', + content: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + availableCharacters: input.characterNames, + availableScenes: input.sceneNames, + script: input.script, + }), + }, + ], + response_format: { type: 'json_object' }, + temperature: 0.4, + max_tokens: 12_000, + }) + const document = storyboardDocumentSchema.safeParse(parseJsonContent(messageContent(response), 'storyboard')) + if (!document.success) throw new GenericProviderError('Generic text provider returned a storyboard that does not match the required schema') + return { shots: document.data.shots, model: configuration.model, usage: usageRows(response) } + } + + async generateImage(input: ImageGenerationInput): Promise { + const configuration = capabilityConfiguration('image') + const references = input.referenceUrls.length > 0 + ? `\nContinuity reference URLs: ${input.referenceUrls.join(', ')}` + : '' + const prompt = [input.prompt, input.negativePrompt ? `Avoid: ${input.negativePrompt}` : '', references].filter(Boolean).join('\n') + const customParams = { ...(input.params ?? {}) } + ;['model', 'prompt', 'n', 'size', 'response_format', 'image'].forEach((key) => delete customParams[key]) + const response = input.references.length > 0 + ? await (() => { + const form = new FormData() + form.append('model', configuration.model) + form.append('prompt', prompt) + form.append('n', '1') + form.append('size', `${input.width}x${input.height}`) + input.references.forEach((reference) => { + form.append('image', new Blob([reference.data], { type: reference.mimeType }), reference.name) + }) + Object.entries(customParams).forEach(([key, value]) => appendFormValue(form, key, value)) + return this.requestJson(configuration, '/images/edits', { method: 'POST', body: form }) + })() + : await this.postJson(configuration, '/images/generations', { + ...customParams, + model: configuration.model, + prompt, + n: 1, + size: `${input.width}x${input.height}`, + }) + if (!response || typeof response !== 'object' || !('data' in response) || !Array.isArray(response.data)) { + throw new GenericProviderError('Generic image provider returned an invalid response') + } + const image = response.data[0] + if (!image || typeof image !== 'object') throw new GenericProviderError('Generic image provider returned no image data') + if ('b64_json' in image && typeof image.b64_json === 'string' && image.b64_json.length > 0) { + return { + data: Buffer.from(image.b64_json, 'base64'), + mimeType: 'image/png', + model: configuration.model, + width: input.width, + height: input.height, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 120 }], + } + } + if ('url' in image && typeof image.url === 'string' && image.url.length > 0) { + return { + url: image.url, + sourceUrl: image.url, + mimeType: imageMimeType(image.url), + model: configuration.model, + width: input.width, + height: input.height, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 120 }], + } + } + throw new GenericProviderError('Generic image provider returned no image data') + } + + async generateVideo(input: VideoGenerationInput): Promise { + const configuration = capabilityConfiguration('video') + const durationSeconds = Math.max(1, Math.round(input.durationSeconds)) + const size = videoDimensions(input) + const form = new FormData() + form.append('model', configuration.model) + form.append('prompt', input.prompt) + form.append('seconds', String(durationSeconds)) + form.append('size', size) + if (input.imageData) { + form.append('input_reference', new Blob([input.imageData], { type: input.imageMimeType ?? 'image/png' }), 'reference-image') + } else { + form.append('input_reference', input.imageUrl) + } + Object.entries(input.params ?? {}) + .filter(([key]) => !['model', 'prompt', 'seconds', 'size', 'input_reference'].includes(key)) + .forEach(([key, value]) => appendFormValue(form, key, value)) + + let current = parseVideo(await this.requestJson(configuration, '/videos', { method: 'POST', body: form })) + const startedAt = Date.now() + while (!['completed', 'succeeded'].includes(current.status)) { + if (current.status === 'failed' || current.status === 'canceled') { + const reason = typeof current.error === 'string' ? current.error : current.error?.message + throw new GenericProviderError(reason || `Generic video generation ${current.status}`) + } + if (Date.now() - startedAt > this.predictionDeadlineSeconds * 1000) { + throw new GenericProviderError(`Generic video generation exceeded the ${this.predictionDeadlineSeconds}s deadline`) + } + await this.sleep(this.pollIntervalMs) + current = parseVideo(await this.requestJson(configuration, `/videos/${encodeURIComponent(current.id)}`, { method: 'GET' })) + } + + const outputUrl = outputVideoUrl(current) + const media = outputUrl + ? { url: outputUrl } + : { data: await this.downloadVideoContent(configuration, current.id) } + const actualSeconds = Number(current.seconds) || durationSeconds + return { + ...media, + mimeType: 'video/mp4', + model: current.model ?? configuration.model, + externalId: current.id, + ...dimensionsFromSize(current.size ?? size), + usage: [{ kind: 'VIDEO_SECOND', quantity: actualSeconds, credits: actualSeconds * 35 }], + } + } + + private async downloadVideoContent(configuration: CapabilityConfiguration, videoId: string) { + let response: Response + try { + response = await this.fetchImpl(endpoint(configuration.baseUrl, `/videos/${encodeURIComponent(videoId)}/content`), { + method: 'GET', + headers: { Authorization: `Bearer ${configuration.apiKey}`, Accept: 'video/mp4' }, + signal: AbortSignal.timeout(180_000), + }) + } catch { + throw new GenericProviderError('Unable to download generic provider video content') + } + if (!response.ok) { + throw new GenericProviderError(`Generic provider video content ${response.status}: ${boundedErrorText(await response.text())}`, response.status) + } + const data = Buffer.from(await response.arrayBuffer()) + if (data.length < 12 || data.subarray(4, 8).toString('ascii') !== 'ftyp') { + throw new GenericProviderError('Generic provider returned invalid MP4 video content') + } + return data + } + + async generateLipsync(_input: LipsyncGenerationInput): Promise { + throw errors.badRequest('Generic OpenAI-compatible provider does not define a lip-sync contract') + } +} diff --git a/server/src/providers/openai.contract.test.ts b/server/src/providers/openai.contract.test.ts new file mode 100644 index 0000000..96c1297 --- /dev/null +++ b/server/src/providers/openai.contract.test.ts @@ -0,0 +1,337 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { config } from '../config.js' +import { OpenAIProvider, openAIImageDimensions } from './openai.js' +import type { ScriptDocument } from './types.js' + +const originalConfiguration = { + apiKey: config.OPENAI_API_KEY, + textModel: config.OPENAI_TEXT_MODEL, + imageModel: config.OPENAI_IMAGE_MODEL, + ttsModel: config.OPENAI_TTS_MODEL, + ttsVoice: config.OPENAI_TTS_VOICE, +} + +function jsonResponse(body: unknown, status = 200) { + return new Response(JSON.stringify(body), { + status, + headers: { 'content-type': 'application/json', 'x-request-id': 'contract-request' }, + }) +} + +function responsesApiBody(id: string, text: string, usage: { input_tokens: number; output_tokens: number }) { + return { + id, + object: 'response', + status: 'completed', + output: [{ + id: `message-${id}`, + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text, annotations: [] }], + }], + usage: { ...usage, total_tokens: usage.input_tokens + usage.output_tokens }, + } +} + +function requestBody(init?: RequestInit) { + expect(typeof init?.body).toBe('string') + return JSON.parse(init?.body as string) as Record +} + +function expectOpenAIRequest(input: Parameters[0], init: Parameters[1], pathname: string) { + expect(new URL(String(input)).pathname).toBe(pathname) + expect(init?.method).toBe('POST') + const headers = new Headers(init?.headers) + expect(headers.get('authorization')).toBe('Bearer contract-openai-key') + return requestBody(init) +} + +beforeAll(() => { + config.OPENAI_API_KEY = 'contract-openai-key' + config.OPENAI_TEXT_MODEL = 'contract-text-model' + config.OPENAI_IMAGE_MODEL = 'contract-image-model' + config.OPENAI_TTS_MODEL = 'contract-tts-model' + config.OPENAI_TTS_VOICE = 'contract-voice' +}) + +afterAll(() => { + config.OPENAI_API_KEY = originalConfiguration.apiKey + config.OPENAI_TEXT_MODEL = originalConfiguration.textModel + config.OPENAI_IMAGE_MODEL = originalConfiguration.imageModel + config.OPENAI_TTS_MODEL = originalConfiguration.ttsModel + config.OPENAI_TTS_VOICE = originalConfiguration.ttsVoice +}) + +describe('OpenAI provider contract', () => { + it('normalizes GPT Image 2 dimensions to documented limits while preserving aspect ratio', () => { + expect(openAIImageDimensions('gpt-image-2', 1920, 1080)).toEqual({ width: 1920, height: 1088, size: '1920x1088' }) + expect(openAIImageDimensions('gpt-image-2-2026-04-21', 2160, 3840)).toEqual({ width: 2160, height: 3840, size: '2160x3840' }) + expect(openAIImageDimensions('gpt-image-1.5', 1920, 1080)).toEqual({ width: 1536, height: 1024, size: '1536x1024' }) + }) + + it('sends a strict Responses API script request and maps structured output and usage', async () => { + const document: ScriptDocument = { + title: '雾港来信', + logline: '记者收到一封来自未来的信。', + estimatedDurationSeconds: 90, + scenes: [{ + number: 1, + location: '旧港仓库', + interiorExterior: '内', + time: '夜', + summary: '林遥找到录音机。', + beats: [ + { type: 'action', text: '卷帘门缓慢升起。', character: null, parenthetical: null }, + { type: 'dialogue', text: '这不是今天录的。', character: '林遥', parenthetical: '压低声音' }, + ], + }], + } + const fetchMock = vi.fn(async (input, init) => { + const body = expectOpenAIRequest(input, init, '/v1/responses') + expect(body).toMatchObject({ + model: 'contract-text-model', + store: false, + safety_identifier: 'user-contract-1', + text: { format: { type: 'json_schema', name: 'comic_drama_script', strict: true } }, + }) + const prompt = JSON.parse(body.input as string) as Record + expect(prompt).toMatchObject({ + task: '强化悬疑钩子', + project: '雾港档案', + episodeTitle: '第一封信', + existingScript: null, + }) + return jsonResponse(responsesApiBody('resp-script', JSON.stringify(document), { input_tokens: 1200, output_tokens: 450 })) + }) + + const result = await new OpenAIProvider(fetchMock).generateScript({ + instruction: '强化悬疑钩子', + projectName: '雾港档案', + genre: '都市悬疑', + visualBible: { palette: 'cold' }, + episodeTitle: '第一封信', + synopsis: '记者追查未来录音。', + targetDurationSeconds: 90, + safetyIdentifier: 'user-contract-1', + }) + + expect(result.document).toEqual(document) + expect(result.plainText).toContain('场 1 · 内 · 旧港仓库 · 夜') + expect(result.plainText).toContain('林遥(压低声音):这不是今天录的。') + expect(result.usage).toEqual([ + { kind: 'TEXT_INPUT_TOKEN', quantity: 1200, credits: 1.2 }, + { kind: 'TEXT_OUTPUT_TOKEN', quantity: 450, credits: 0.9 }, + ]) + expect(fetchMock).toHaveBeenCalledOnce() + }) + + it('sends storyboard assets and maps the strict shot document', async () => { + const shots = [{ + sceneNumber: 1, + title: '仓库门开启', + description: '林遥站在雨夜仓库门前,冷色逆光。', + shotType: '中景', + cameraMotion: '缓慢推进', + durationMs: 3200, + characterNames: ['林遥'], + sceneName: '旧港仓库', + subtitleText: '门后有人。', + }] + const fetchMock = vi.fn(async (input, init) => { + const body = expectOpenAIRequest(input, init, '/v1/responses') + expect(body).toMatchObject({ + model: 'contract-text-model', + safety_identifier: 'user-contract-2', + text: { format: { name: 'comic_drama_storyboard', strict: true } }, + }) + const prompt = JSON.parse(body.input as string) as Record + expect(prompt.availableCharacters).toEqual(['林遥']) + expect(prompt.availableScenes).toEqual(['旧港仓库']) + expect(prompt.script).toBe('场 1,林遥进入仓库。') + return jsonResponse(responsesApiBody('resp-storyboard', JSON.stringify({ shots }), { input_tokens: 800, output_tokens: 300 })) + }) + + const result = await new OpenAIProvider(fetchMock).generateStoryboard({ + projectName: '雾港档案', + genre: '都市悬疑', + visualBible: {}, + episodeTitle: '第一封信', + targetDurationSeconds: 90, + script: '场 1,林遥进入仓库。', + instruction: '拆成电影感镜头', + characterNames: ['林遥'], + sceneNames: ['旧港仓库'], + safetyIdentifier: 'user-contract-2', + }) + + expect(result.shots).toEqual(shots) + expect(result.usage).toHaveLength(2) + }) + + it('generates an image with the requested aspect mapping and binary response', async () => { + const png = Buffer.from('contract-png') + const fetchMock = vi.fn(async (input, init) => { + const body = expectOpenAIRequest(input, init, '/v1/images/generations') + expect(body).toMatchObject({ + model: 'contract-image-model', + prompt: '雨夜仓库\nAvoid: watermark', + size: '1536x1024', + quality: 'high', + output_format: 'png', + user: 'user-contract-3', + }) + return jsonResponse({ created: 1, data: [{ b64_json: png.toString('base64') }] }) + }) + + const result = await new OpenAIProvider(fetchMock).generateImage({ + prompt: '雨夜仓库', + negativePrompt: 'watermark', + width: 1920, + height: 1080, + references: [], + referenceUrls: [], + safetyIdentifier: 'user-contract-3', + }) + + expect(result.data).toEqual(png) + expect(result).toMatchObject({ mimeType: 'image/png', model: 'contract-image-model' }) + }) + + it('uses multipart image editing when character references are supplied', async () => { + const fetchMock = vi.fn(async (input, init) => { + expect(new URL(String(input)).pathname).toBe('/v1/images/edits') + expect(init?.method).toBe('POST') + expect(init?.body).toBeInstanceOf(FormData) + const form = init?.body as FormData + expect(form.get('model')).toBe('contract-image-model') + expect(form.get('input_fidelity')).toBe('high') + expect(form.get('size')).toBe('1024x1536') + expect(String(form.get('prompt'))).toContain('73% fidelity') + const files = form.getAll('image[]') + expect(files).toHaveLength(1) + expect(files[0]).toBeInstanceOf(File) + return jsonResponse({ created: 1, data: [{ url: 'https://provider.example/character.png' }] }) + }) + + const result = await new OpenAIProvider(fetchMock).generateImage({ + prompt: '林遥回头看向镜头', + width: 1080, + height: 1920, + references: [{ name: 'linyao.png', mimeType: 'image/png', data: Buffer.from('reference') }], + referenceUrls: ['https://media.example/linyao.png'], + params: { consistencyStrength: 73 }, + safetyIdentifier: 'user-contract-4', + }) + + expect(result.url).toBe('https://provider.example/character.png') + }) + + it('omits the unsupported input_fidelity field for GPT Image 2 reference edits', async () => { + config.OPENAI_IMAGE_MODEL = 'gpt-image-2' + try { + const fetchMock = vi.fn(async (input, init) => { + expect(new URL(String(input)).pathname).toBe('/v1/images/edits') + const form = init?.body as FormData + expect(form.get('model')).toBe('gpt-image-2') + expect(form.get('input_fidelity')).toBeNull() + expect(form.get('size')).toBe('1088x1920') + return jsonResponse({ created: 1, data: [{ b64_json: Buffer.from('gpt-image-2-result').toString('base64') }] }) + }) + + const result = await new OpenAIProvider(fetchMock).generateImage({ + prompt: '保持人物一致性', + width: 1080, + height: 1920, + references: [{ name: 'reference.png', mimeType: 'image/png', data: Buffer.from('reference') }], + referenceUrls: [], + safetyIdentifier: 'user-contract-gpt-image-2', + }) + + expect(result).toMatchObject({ width: 1088, height: 1920, mimeType: 'image/png' }) + } finally { + config.OPENAI_IMAGE_MODEL = 'contract-image-model' + } + }) + + it('rejects incomplete, refused, and schema-invalid structured responses', async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(jsonResponse({ + id: 'resp-incomplete', + object: 'response', + status: 'incomplete', + incomplete_details: { reason: 'max_output_tokens' }, + output: [], + })) + .mockResolvedValueOnce(jsonResponse({ + id: 'resp-refusal', + object: 'response', + status: 'completed', + output: [{ + id: 'message-refusal', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'refusal', refusal: '该请求无法完成' }], + }], + })) + .mockResolvedValueOnce(jsonResponse(responsesApiBody('resp-invalid-schema', JSON.stringify({ title: '缺少场景' }), { input_tokens: 1, output_tokens: 1 }))) + const provider = new OpenAIProvider(fetchMock) + const input = { + instruction: '生成剧本', + projectName: '雾港档案', + genre: '都市悬疑', + visualBible: {}, + episodeTitle: '第一封信', + synopsis: '记者追查未来录音。', + targetDurationSeconds: 90, + safetyIdentifier: 'user-contract-terminal-states', + } + + await expect(provider.generateScript(input)).rejects.toThrow('max_output_tokens') + await expect(provider.generateScript(input)).rejects.toThrow('该请求无法完成') + await expect(provider.generateScript(input)).rejects.toThrow('does not match the required schema') + }) + + it('requests MP3 speech with voice controls and returns audio bytes', async () => { + const audio = Buffer.from('contract-mp3') + const fetchMock = vi.fn(async (input, init) => { + const body = expectOpenAIRequest(input, init, '/v1/audio/speech') + expect(body).toEqual({ + model: 'contract-tts-model', + voice: 'nova', + input: '门后有人。', + response_format: 'mp3', + instructions: '压低声音,保持紧张', + speed: 0.95, + }) + return new Response(audio, { status: 200, headers: { 'content-type': 'audio/mpeg' } }) + }) + + const result = await new OpenAIProvider(fetchMock).generateSpeech({ + text: '门后有人。', + voice: 'nova', + instructions: '压低声音,保持紧张', + speed: 0.95, + safetyIdentifier: 'user-contract-5', + }) + + expect(result.data).toEqual(audio) + expect(result.mimeType).toBe('audio/mpeg') + expect(result.usage[0]?.kind).toBe('AUDIO_SECOND') + }) + + it('propagates a provider error without exposing the API key', async () => { + const fetchMock = vi.fn(async () => jsonResponse({ error: { message: 'invalid request', type: 'invalid_request_error' } }, 400)) + const provider = new OpenAIProvider(fetchMock) + + await expect(provider.generateSpeech({ + text: 'test', + safetyIdentifier: 'user-contract-error', + })).rejects.toThrow('invalid request') + await expect(provider.generateSpeech({ + text: 'test', + safetyIdentifier: 'user-contract-error', + })).rejects.not.toThrow('contract-openai-key') + }) +}) diff --git a/server/src/providers/openai.ts b/server/src/providers/openai.ts new file mode 100644 index 0000000..07f03c4 --- /dev/null +++ b/server/src/providers/openai.ts @@ -0,0 +1,381 @@ +import OpenAI, { toFile } from 'openai' +import { z } from 'zod' +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import type { + BinaryGenerationResult, + ImageGenerationInput, + ImageProvider, + ScriptDocument, + ScriptGenerationInput, + ScriptGenerationResult, + SpeechGenerationInput, + SpeechProvider, + StoryboardGenerationInput, + StoryboardGenerationResult, + TextProvider, +} from './types.js' + +export const scriptJsonSchema = { + type: 'object', + additionalProperties: false, + required: ['title', 'logline', 'estimatedDurationSeconds', 'scenes'], + properties: { + title: { type: 'string' }, + logline: { type: 'string' }, + estimatedDurationSeconds: { type: 'integer' }, + scenes: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['number', 'location', 'interiorExterior', 'time', 'summary', 'beats'], + properties: { + number: { type: 'integer' }, + location: { type: 'string' }, + interiorExterior: { type: 'string', enum: ['内', '外'] }, + time: { type: 'string' }, + summary: { type: 'string' }, + beats: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['type', 'text', 'character', 'parenthetical'], + properties: { + type: { type: 'string', enum: ['action', 'dialogue', 'transition'] }, + text: { type: 'string' }, + character: { type: ['string', 'null'] }, + parenthetical: { type: ['string', 'null'] }, + }, + }, + }, + }, + }, + }, + }, +} satisfies Record + +export const storyboardJsonSchema = { + type: 'object', + additionalProperties: false, + required: ['shots'], + properties: { + shots: { + type: 'array', + minItems: 1, + maxItems: 300, + items: { + type: 'object', + additionalProperties: false, + required: ['sceneNumber', 'title', 'description', 'shotType', 'cameraMotion', 'durationMs', 'characterNames', 'sceneName', 'subtitleText'], + properties: { + sceneNumber: { type: 'integer', minimum: 1 }, + title: { type: 'string' }, + description: { type: 'string' }, + shotType: { type: 'string' }, + cameraMotion: { type: 'string' }, + durationMs: { type: 'integer', minimum: 500, maximum: 30000 }, + characterNames: { type: 'array', items: { type: 'string' } }, + sceneName: { type: ['string', 'null'] }, + subtitleText: { type: 'string' }, + }, + }, + }, + }, +} satisfies Record + +export const scriptDocumentSchema = z.object({ + title: z.string().trim().min(1).max(180), + logline: z.string().max(2000), + estimatedDurationSeconds: z.number().int().positive().max(24 * 60 * 60), + scenes: z.array(z.object({ + number: z.number().int().positive(), + location: z.string().trim().min(1).max(500), + interiorExterior: z.enum(['内', '外']), + time: z.string().trim().min(1).max(160), + summary: z.string().max(4000), + beats: z.array(z.object({ + type: z.enum(['action', 'dialogue', 'transition']), + text: z.string().min(1).max(10_000), + character: z.string().max(180).nullable(), + parenthetical: z.string().max(500).nullable(), + })).max(2000), + })).min(1).max(500), +}) satisfies z.ZodType + +export const storyboardDocumentSchema = z.object({ + shots: z.array(z.object({ + sceneNumber: z.number().int().min(1), + title: z.string().trim().min(1).max(180), + description: z.string().trim().min(1).max(10_000), + shotType: z.string().trim().min(1).max(50), + cameraMotion: z.string().trim().min(1).max(50), + durationMs: z.number().int().min(500).max(30_000), + characterNames: z.array(z.string().trim().min(1).max(180)).max(20), + sceneName: z.string().trim().min(1).max(180).nullable(), + subtitleText: z.string().max(10_000), + })).min(1).max(300), +}) satisfies z.ZodType<{ shots: StoryboardGenerationResult['shots'] }> + +function responseRefusal(response: unknown) { + if (!response || typeof response !== 'object' || !('output' in response) || !Array.isArray(response.output)) return null + for (const item of response.output) { + if (!item || typeof item !== 'object' || !('content' in item) || !Array.isArray(item.content)) continue + for (const part of item.content) { + if (part && typeof part === 'object' && 'type' in part && part.type === 'refusal' && 'refusal' in part && typeof part.refusal === 'string') { + return part.refusal.slice(0, 1000) + } + } + } + return null +} + +function parseStructuredResponse(response: unknown, schema: z.ZodType, label: string): T { + if (!response || typeof response !== 'object') throw new Error(`OpenAI returned an invalid ${label} response`) + const refusal = responseRefusal(response) + if (refusal) throw new Error(`OpenAI refused the ${label} request: ${refusal}`) + const status = 'status' in response && typeof response.status === 'string' ? response.status : null + if (status && status !== 'completed') { + const reason = 'incomplete_details' in response && response.incomplete_details && typeof response.incomplete_details === 'object' + && 'reason' in response.incomplete_details && typeof response.incomplete_details.reason === 'string' + ? response.incomplete_details.reason + : status + throw new Error(`OpenAI ${label} response did not complete: ${reason}`) + } + const outputText = 'output_text' in response && typeof response.output_text === 'string' ? response.output_text : '' + if (!outputText) throw new Error(`OpenAI returned an empty ${label} response`) + let document: unknown + try { + document = JSON.parse(outputText) + } catch { + throw new Error(`OpenAI returned malformed JSON for ${label}`) + } + const parsed = schema.safeParse(document) + if (!parsed.success) throw new Error(`OpenAI returned a ${label} document that does not match the required schema`) + return parsed.data +} + +const GPT_IMAGE_2 = /^gpt-image-2(?:-|$)/ +const GPT_IMAGE_2_MIN_PIXELS = 655_360 +const GPT_IMAGE_2_MAX_PIXELS = 8_294_400 +const GPT_IMAGE_2_MAX_EDGE = 3840 + +function align16(value: number) { + return Math.max(16, Math.round(value / 16) * 16) +} + +export function openAIImageDimensions(model: string, requestedWidth: number, requestedHeight: number) { + if (!GPT_IMAGE_2.test(model)) { + if (requestedWidth > requestedHeight) return { width: 1536, height: 1024, size: '1536x1024' as const } + if (requestedHeight > requestedWidth) return { width: 1024, height: 1536, size: '1024x1536' as const } + return { width: 1024, height: 1024, size: '1024x1024' as const } + } + + let width = Math.max(16, requestedWidth) + let height = Math.max(16, requestedHeight) + if (width / height > 3) width = height * 3 + if (height / width > 3) height = width * 3 + const edgeScale = Math.min(1, GPT_IMAGE_2_MAX_EDGE / Math.max(width, height)) + width *= edgeScale + height *= edgeScale + const pixelCount = width * height + const pixelScale = pixelCount > GPT_IMAGE_2_MAX_PIXELS + ? Math.sqrt(GPT_IMAGE_2_MAX_PIXELS / pixelCount) + : pixelCount < GPT_IMAGE_2_MIN_PIXELS + ? Math.sqrt(GPT_IMAGE_2_MIN_PIXELS / pixelCount) + : 1 + width = align16(width * pixelScale) + height = align16(height * pixelScale) + while (width * height > GPT_IMAGE_2_MAX_PIXELS) { + if (width >= height) width -= 16 + else height -= 16 + } + while (width * height < GPT_IMAGE_2_MIN_PIXELS) { + if (width >= height) width += 16 + else height += 16 + } + return { width, height, size: `${width}x${height}` } +} + +function requireApiKey() { + if (!config.OPENAI_API_KEY) throw errors.badRequest('OPENAI_API_KEY is not configured') + return config.OPENAI_API_KEY +} + +export function scriptToPlainText(document: ScriptDocument) { + return document.scenes.map((scene) => { + const heading = `场 ${scene.number} · ${scene.interiorExterior} · ${scene.location} · ${scene.time}` + const beats = scene.beats.map((beat) => { + if (beat.type !== 'dialogue') return beat.text + const parenthetical = beat.parenthetical ? `(${beat.parenthetical})` : '' + return `${beat.character ?? '角色'}${parenthetical}:${beat.text}` + }) + return [heading, ...beats].join('\n') + }).join('\n\n') +} + +export class OpenAIProvider implements TextProvider, ImageProvider, SpeechProvider { + readonly name = 'openai' + private readonly client: OpenAI + + constructor(fetchImpl?: typeof fetch) { + this.client = new OpenAI({ + apiKey: requireApiKey(), + ...(fetchImpl ? { fetch: fetchImpl } : {}), + }) + } + + async generateScript(input: ScriptGenerationInput): Promise { + const response = await this.client.responses.create({ + model: config.OPENAI_TEXT_MODEL, + instructions: [ + '你是专业的中文漫剧编剧。输出严格遵循给定 JSON Schema。', + '故事必须可拍摄、镜头动作明确、对白简洁,并保持角色动机连续。', + '不要解释创作过程,不要输出 Schema 之外的字段。', + ].join('\n'), + input: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + synopsis: input.synopsis, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + existingScript: input.existingScript ?? null, + }), + text: { + format: { + type: 'json_schema', + name: 'comic_drama_script', + strict: true, + schema: scriptJsonSchema, + }, + verbosity: 'medium', + }, + safety_identifier: input.safetyIdentifier, + store: false, + }) + + const document = parseStructuredResponse(response, scriptDocumentSchema, 'script') + const usage = response.usage + + return { + document, + plainText: scriptToPlainText(document), + model: config.OPENAI_TEXT_MODEL, + usage: usage ? [ + { kind: 'TEXT_INPUT_TOKEN', quantity: usage.input_tokens, credits: usage.input_tokens / 1000 }, + { kind: 'TEXT_OUTPUT_TOKEN', quantity: usage.output_tokens, credits: usage.output_tokens / 500 }, + ] : [], + } + } + + async generateStoryboard(input: StoryboardGenerationInput): Promise { + const response = await this.client.responses.create({ + model: config.OPENAI_TEXT_MODEL, + instructions: [ + '你是专业的中文漫剧分镜导演。输出严格遵循给定 JSON Schema。', + '把完整剧本拆成可以独立生成画面和视频的镜头,画面描述必须明确人物、动作、构图、光线和环境。', + '优先使用给定的人物与场景资产名称,保持人物连续性,并让镜头总时长接近目标时长。', + 'subtitleText 只保留当前镜头需要朗读的对白或旁白;无对白时输出空字符串。', + '不要解释创作过程,不要输出 Schema 之外的字段。', + ].join('\n'), + input: JSON.stringify({ + task: input.instruction, + project: input.projectName, + genre: input.genre, + episodeTitle: input.episodeTitle, + targetDurationSeconds: input.targetDurationSeconds, + visualBible: input.visualBible, + availableCharacters: input.characterNames, + availableScenes: input.sceneNames, + script: input.script, + }), + text: { + format: { + type: 'json_schema', + name: 'comic_drama_storyboard', + strict: true, + schema: storyboardJsonSchema, + }, + verbosity: 'medium', + }, + safety_identifier: input.safetyIdentifier, + store: false, + }) + + const document = parseStructuredResponse(response, storyboardDocumentSchema, 'storyboard') + const usage = response.usage + return { + shots: document.shots, + model: config.OPENAI_TEXT_MODEL, + usage: usage ? [ + { kind: 'TEXT_INPUT_TOKEN', quantity: usage.input_tokens, credits: usage.input_tokens / 1000 }, + { kind: 'TEXT_OUTPUT_TOKEN', quantity: usage.output_tokens, credits: usage.output_tokens / 500 }, + ] : [], + } + } + + async generateImage(input: ImageGenerationInput): Promise { + const dimensions = openAIImageDimensions(config.OPENAI_IMAGE_MODEL, input.width, input.height) + const consistencyStrength = Math.max(50, Math.min(100, Number(input.params?.consistencyStrength) || 82)) + const referenceInstruction = input.references.length > 0 + ? `Use the supplied images as strict continuity references. Preserve recognizable identity, facial structure, costume signatures, scene geometry, and visual style at approximately ${consistencyStrength}% fidelity while following the new composition.` + : '' + const fullPrompt = [input.prompt, referenceInstruction, input.negativePrompt ? `Avoid: ${input.negativePrompt}` : ''].filter(Boolean).join('\n') + + const response = input.references.length > 0 + ? await this.client.images.edit({ + model: config.OPENAI_IMAGE_MODEL, + image: await Promise.all(input.references.map((reference) => toFile(reference.data, reference.name, { type: reference.mimeType }))), + prompt: fullPrompt, + size: dimensions.size, + quality: 'high', + ...(!GPT_IMAGE_2.test(config.OPENAI_IMAGE_MODEL) ? { input_fidelity: 'high' as const } : {}), + output_format: 'png', + user: input.safetyIdentifier, + }) + : await this.client.images.generate({ + model: config.OPENAI_IMAGE_MODEL, + prompt: fullPrompt, + size: dimensions.size, + quality: 'high', + output_format: 'png', + user: input.safetyIdentifier, + }) + + const image = response.data?.[0] + if (!image?.b64_json && !image?.url) throw new Error('OpenAI returned no image data') + const media = image.b64_json + ? { data: Buffer.from(image.b64_json, 'base64') } + : { url: image.url! } + return { + ...media, + mimeType: 'image/png', + model: config.OPENAI_IMAGE_MODEL, + width: dimensions.width, + height: dimensions.height, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 120 }], + } + } + + async generateSpeech(input: SpeechGenerationInput): Promise { + const response = await this.client.audio.speech.create({ + model: config.OPENAI_TTS_MODEL, + voice: input.voice ?? config.OPENAI_TTS_VOICE, + input: input.text, + response_format: 'mp3', + ...(input.instructions ? { instructions: input.instructions } : {}), + ...(input.speed !== undefined ? { speed: input.speed } : {}), + }) + const data = Buffer.from(await response.arrayBuffer()) + const estimatedSeconds = Math.max(1, input.text.length / 4.2) + return { + data, + mimeType: 'audio/mpeg', + model: config.OPENAI_TTS_MODEL, + usage: [{ kind: 'AUDIO_SECOND', quantity: estimatedSeconds, credits: estimatedSeconds * 0.6 }], + } + } +} diff --git a/server/src/providers/readiness.test.ts b/server/src/providers/readiness.test.ts new file mode 100644 index 0000000..25c97f9 --- /dev/null +++ b/server/src/providers/readiness.test.ts @@ -0,0 +1,96 @@ +import { describe, expect, it } from 'vitest' +import { AppError } from '../lib/errors.js' +import { assertJobProviderConfigured, buildProviderReadiness, type ProviderConfiguration } from './readiness.js' + +const emptyConfiguration: ProviderConfiguration = { + openaiTextModel: 'text-model', + openaiImageModel: 'image-model', + openaiTtsModel: 'tts-model', +} + +describe('provider readiness', () => { + it('reports missing requirements without exposing credential values', () => { + const readiness = buildProviderReadiness(emptyConfiguration) + expect(readiness.status).toBe('NOT_CONFIGURED') + expect(readiness.summary).toEqual({ configuredWorkflows: 0, totalWorkflows: 6 }) + expect(readiness.workflows.find((item) => item.id === 'video')?.missingRequirements).toEqual([ + 'AGNES_API_KEY', + 'AGNES_VIDEO_MODEL', + ]) + }) + + it('distinguishes partial provider setup from configured workflows', () => { + const readiness = buildProviderReadiness({ + ...emptyConfiguration, + openaiApiKey: 'secret-openai-key', + replicateApiToken: 'secret-replicate-token', + replicateVideoVersion: 'video-version', + }) + expect(readiness.status).toBe('PARTIAL') + expect(readiness.summary.configuredWorkflows).toBe(5) + expect(readiness.providers.find((item) => item.id === 'openai')?.status).toBe('CONFIGURED') + expect(readiness.providers.find((item) => item.id === 'replicate')?.status).toBe('PARTIAL') + expect(JSON.stringify(readiness)).not.toContain('secret-openai-key') + expect(JSON.stringify(readiness)).not.toContain('secret-replicate-token') + }) + + it('rejects unavailable cloud jobs before they enter the queue', () => { + expect(() => assertJobProviderConfigured('VIDEO_GENERATE', {}, emptyConfiguration)).toThrow(AppError) + try { + assertJobProviderConfigured('VIDEO_GENERATE', {}, emptyConfiguration) + } catch (error) { + expect(error).toMatchObject({ + statusCode: 400, + code: 'BAD_REQUEST', + details: { + provider: 'replicate', + capability: 'video-replicate', + missingRequirements: ['REPLICATE_API_TOKEN', 'REPLICATE_VIDEO_VERSION'], + }, + }) + } + expect(() => assertJobProviderConfigured('EPISODE_RENDER', {}, emptyConfiguration)).not.toThrow() + }) + + it('tracks generic text, image, and video configuration independently', () => { + const configuration: ProviderConfiguration = { + ...emptyConfiguration, + genericTextApiKey: 'generic-text-secret', + genericTextBaseUrl: 'https://text.vendor.test/v1', + genericTextModel: 'text-v1', + genericImageApiKey: 'generic-image-secret', + genericImageBaseUrl: 'https://image.vendor.test/v1', + genericImageModel: 'image-v1', + genericVideoApiKey: 'generic-video-secret', + genericVideoBaseUrl: 'https://video.vendor.test/v1', + genericVideoModel: 'video-v1', + } + const readiness = buildProviderReadiness(configuration) + const generic = readiness.providers.find((item) => item.id === 'generic') + expect(generic).toMatchObject({ status: 'CONFIGURED', configuredCapabilities: 4, totalCapabilities: 4 }) + expect(readiness.workflows.find((item) => item.id === 'script')).toMatchObject({ provider: 'generic', model: 'text-v1' }) + expect(() => assertJobProviderConfigured('ASSET_GENERATE', { provider: 'generic' }, configuration)).not.toThrow() + expect(JSON.stringify(readiness)).not.toContain('generic-text-secret') + }) + + it('reports the exact missing generic capability settings', () => { + expect(() => assertJobProviderConfigured('VIDEO_GENERATE', { provider: 'generic' }, { + ...emptyConfiguration, + genericVideoApiKey: 'generic-video-secret', + })).toThrow(AppError) + try { + assertJobProviderConfigured('VIDEO_GENERATE', { provider: 'generic' }, { + ...emptyConfiguration, + genericVideoApiKey: 'generic-video-secret', + }) + } catch (error) { + expect(error).toMatchObject({ + details: { + provider: 'generic', + capability: 'video-generic', + missingRequirements: ['GENERIC_VIDEO_BASE_URL', 'GENERIC_VIDEO_MODEL'], + }, + }) + } + }) +}) diff --git a/server/src/providers/readiness.ts b/server/src/providers/readiness.ts new file mode 100644 index 0000000..04f370c --- /dev/null +++ b/server/src/providers/readiness.ts @@ -0,0 +1,280 @@ +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import type { JobKind } from '../queue/types.js' + +export interface ProviderConfiguration { + openaiApiKey?: string + openaiTextModel: string + openaiImageModel: string + openaiTtsModel: string + agnesApiKey?: string + agnesTextModel?: string + agnesImageModel?: string + agnesVideoModel?: string + genericTextApiKey?: string + genericTextBaseUrl?: string + genericTextModel?: string + genericImageApiKey?: string + genericImageBaseUrl?: string + genericImageModel?: string + genericVideoApiKey?: string + genericVideoBaseUrl?: string + genericVideoModel?: string + replicateApiToken?: string + replicateImageVersion?: string + replicateVideoVersion?: string + replicateLipsyncVersion?: string +} + +type ProviderId = 'openai' | 'replicate' | 'agnes' | 'generic' +type CapabilityId = + | 'script-openai' + | 'storyboard-openai' + | 'image-openai' + | 'tts' + | 'image-replicate' + | 'video-replicate' + | 'lipsync' + | 'script-agnes' + | 'storyboard-agnes' + | 'image-agnes' + | 'video-agnes' + | 'script-generic' + | 'storyboard-generic' + | 'image-generic' + | 'video-generic' +type WorkflowId = 'script' | 'storyboard' | 'image' | 'tts' | 'video' | 'lipsync' + +interface CapabilityDefinition { + id: CapabilityId + label: string + provider: ProviderId + model: string | undefined + requirementKeys: Array +} + +const publicRequirementNames: Partial> = { + openaiApiKey: 'OPENAI_API_KEY', + agnesApiKey: 'AGNES_API_KEY', + agnesTextModel: 'AGNES_TEXT_MODEL', + agnesImageModel: 'AGNES_IMAGE_MODEL', + agnesVideoModel: 'AGNES_VIDEO_MODEL', + genericTextApiKey: 'GENERIC_TEXT_API_KEY', + genericTextBaseUrl: 'GENERIC_TEXT_BASE_URL', + genericTextModel: 'GENERIC_TEXT_MODEL', + genericImageApiKey: 'GENERIC_IMAGE_API_KEY', + genericImageBaseUrl: 'GENERIC_IMAGE_BASE_URL', + genericImageModel: 'GENERIC_IMAGE_MODEL', + genericVideoApiKey: 'GENERIC_VIDEO_API_KEY', + genericVideoBaseUrl: 'GENERIC_VIDEO_BASE_URL', + genericVideoModel: 'GENERIC_VIDEO_MODEL', + replicateApiToken: 'REPLICATE_API_TOKEN', + replicateImageVersion: 'REPLICATE_IMAGE_VERSION', + replicateVideoVersion: 'REPLICATE_VIDEO_VERSION', + replicateLipsyncVersion: 'REPLICATE_LIPSYNC_VERSION', +} + +export function providerConfiguration(): ProviderConfiguration { + return { + ...(config.OPENAI_API_KEY ? { openaiApiKey: config.OPENAI_API_KEY } : {}), + openaiTextModel: config.OPENAI_TEXT_MODEL, + openaiImageModel: config.OPENAI_IMAGE_MODEL, + openaiTtsModel: config.OPENAI_TTS_MODEL, + ...(config.AGNES_API_KEY ? { agnesApiKey: config.AGNES_API_KEY } : {}), + agnesTextModel: config.AGNES_TEXT_MODEL, + agnesImageModel: config.AGNES_IMAGE_MODEL, + agnesVideoModel: config.AGNES_VIDEO_MODEL, + ...(config.GENERIC_TEXT_API_KEY ? { genericTextApiKey: config.GENERIC_TEXT_API_KEY } : {}), + ...(config.GENERIC_TEXT_BASE_URL ? { genericTextBaseUrl: config.GENERIC_TEXT_BASE_URL } : {}), + ...(config.GENERIC_TEXT_MODEL ? { genericTextModel: config.GENERIC_TEXT_MODEL } : {}), + ...(config.GENERIC_IMAGE_API_KEY ? { genericImageApiKey: config.GENERIC_IMAGE_API_KEY } : {}), + ...(config.GENERIC_IMAGE_BASE_URL ? { genericImageBaseUrl: config.GENERIC_IMAGE_BASE_URL } : {}), + ...(config.GENERIC_IMAGE_MODEL ? { genericImageModel: config.GENERIC_IMAGE_MODEL } : {}), + ...(config.GENERIC_VIDEO_API_KEY ? { genericVideoApiKey: config.GENERIC_VIDEO_API_KEY } : {}), + ...(config.GENERIC_VIDEO_BASE_URL ? { genericVideoBaseUrl: config.GENERIC_VIDEO_BASE_URL } : {}), + ...(config.GENERIC_VIDEO_MODEL ? { genericVideoModel: config.GENERIC_VIDEO_MODEL } : {}), + ...(config.REPLICATE_API_TOKEN ? { replicateApiToken: config.REPLICATE_API_TOKEN } : {}), + ...(config.REPLICATE_IMAGE_VERSION ? { replicateImageVersion: config.REPLICATE_IMAGE_VERSION } : {}), + ...(config.REPLICATE_VIDEO_VERSION ? { replicateVideoVersion: config.REPLICATE_VIDEO_VERSION } : {}), + ...(config.REPLICATE_LIPSYNC_VERSION ? { replicateLipsyncVersion: config.REPLICATE_LIPSYNC_VERSION } : {}), + } +} + +function capabilityDefinitions(configuration: ProviderConfiguration): CapabilityDefinition[] { + return [ + { id: 'script-openai', label: '剧本生成', provider: 'openai', model: configuration.openaiTextModel, requirementKeys: ['openaiApiKey'] }, + { id: 'storyboard-openai', label: '智能分镜', provider: 'openai', model: configuration.openaiTextModel, requirementKeys: ['openaiApiKey'] }, + { id: 'image-openai', label: '画面生成', provider: 'openai', model: configuration.openaiImageModel, requirementKeys: ['openaiApiKey'] }, + { id: 'tts', label: '语音生成', provider: 'openai', model: configuration.openaiTtsModel, requirementKeys: ['openaiApiKey'] }, + { id: 'image-replicate', label: '画面生成', provider: 'replicate', model: configuration.replicateImageVersion, requirementKeys: ['replicateApiToken', 'replicateImageVersion'] }, + { id: 'video-replicate', label: '图生视频', provider: 'replicate', model: configuration.replicateVideoVersion, requirementKeys: ['replicateApiToken', 'replicateVideoVersion'] }, + { id: 'lipsync', label: '口型同步', provider: 'replicate', model: configuration.replicateLipsyncVersion, requirementKeys: ['replicateApiToken', 'replicateLipsyncVersion'] }, + { id: 'script-agnes', label: '剧本生成', provider: 'agnes', model: configuration.agnesTextModel, requirementKeys: ['agnesApiKey', 'agnesTextModel'] }, + { id: 'storyboard-agnes', label: '智能分镜', provider: 'agnes', model: configuration.agnesTextModel, requirementKeys: ['agnesApiKey', 'agnesTextModel'] }, + { id: 'image-agnes', label: '画面生成', provider: 'agnes', model: configuration.agnesImageModel, requirementKeys: ['agnesApiKey', 'agnesImageModel'] }, + { id: 'video-agnes', label: '图生视频', provider: 'agnes', model: configuration.agnesVideoModel, requirementKeys: ['agnesApiKey', 'agnesVideoModel'] }, + { id: 'script-generic', label: '剧本生成', provider: 'generic', model: configuration.genericTextModel, requirementKeys: ['genericTextApiKey', 'genericTextBaseUrl', 'genericTextModel'] }, + { id: 'storyboard-generic', label: '智能分镜', provider: 'generic', model: configuration.genericTextModel, requirementKeys: ['genericTextApiKey', 'genericTextBaseUrl', 'genericTextModel'] }, + { id: 'image-generic', label: '画面生成', provider: 'generic', model: configuration.genericImageModel, requirementKeys: ['genericImageApiKey', 'genericImageBaseUrl', 'genericImageModel'] }, + { id: 'video-generic', label: '图生视频', provider: 'generic', model: configuration.genericVideoModel, requirementKeys: ['genericVideoApiKey', 'genericVideoBaseUrl', 'genericVideoModel'] }, + ] +} + +function configured(value: unknown) { + return typeof value === 'string' && value.trim().length > 0 +} + +function missingRequirements(definition: CapabilityDefinition, configuration: ProviderConfiguration) { + return definition.requirementKeys + .filter((key) => !configured(configuration[key])) + .map((key) => publicRequirementNames[key]) + .filter((key): key is string => Boolean(key)) +} + +function publicCapability(definition: CapabilityDefinition, configuration: ProviderConfiguration) { + const missing = missingRequirements(definition, configuration) + return { + id: definition.id, + label: definition.label, + provider: definition.provider, + model: definition.model ?? null, + status: missing.length === 0 ? 'CONFIGURED' as const : 'NOT_CONFIGURED' as const, + missingRequirements: missing, + } +} + +const workflowCandidates: Array<{ id: WorkflowId, label: string, candidates: CapabilityId[] }> = [ + { id: 'script', label: '剧本生成', candidates: ['script-agnes', 'script-generic', 'script-openai'] }, + { id: 'storyboard', label: '智能分镜', candidates: ['storyboard-agnes', 'storyboard-generic', 'storyboard-openai'] }, + { id: 'image', label: '画面生成', candidates: ['image-agnes', 'image-generic', 'image-openai', 'image-replicate'] }, + { id: 'tts', label: '语音生成', candidates: ['tts'] }, + { id: 'video', label: '图生视频', candidates: ['video-agnes', 'video-generic', 'video-replicate'] }, + { id: 'lipsync', label: '口型同步', candidates: ['lipsync'] }, +] + +export function buildProviderReadiness(configuration = providerConfiguration()) { + const definitions = capabilityDefinitions(configuration) + const capabilities = definitions.map((definition) => publicCapability(definition, configuration)) + const workflows = workflowCandidates.map((workflow) => { + const candidates = workflow.candidates.map((id) => capabilities.find((capability) => capability.id === id)!) + const selected = candidates.find((capability) => capability.status === 'CONFIGURED') ?? candidates[0]! + return { + ...selected, + id: workflow.id, + label: workflow.label, + alternatives: candidates.map((capability) => ({ + id: capability.id, + provider: capability.provider, + model: capability.model, + status: capability.status, + missingRequirements: capability.missingRequirements, + })), + } + }) + + const providerRows = ([ + { id: 'openai' as const, label: 'OpenAI' }, + { id: 'replicate' as const, label: 'Replicate' }, + { id: 'agnes' as const, label: 'Agnes AI' }, + { id: 'generic' as const, label: '通用兼容接口' }, + ]).map((provider) => { + const providerCapabilities = capabilities.filter((capability) => capability.provider === provider.id) + const configuredCount = providerCapabilities.filter((capability) => capability.status === 'CONFIGURED').length + const hasCredential = provider.id === 'openai' + ? configured(configuration.openaiApiKey) + : provider.id === 'replicate' + ? configured(configuration.replicateApiToken) + : provider.id === 'agnes' + ? configured(configuration.agnesApiKey) + : configured(configuration.genericTextApiKey) + || configured(configuration.genericImageApiKey) + || configured(configuration.genericVideoApiKey) + const status = configuredCount === providerCapabilities.length + ? 'CONFIGURED' as const + : hasCredential + ? 'PARTIAL' as const + : 'NOT_CONFIGURED' as const + return { + ...provider, + status, + verification: status === 'NOT_CONFIGURED' ? 'NOT_RUN' as const : 'CONFIGURATION_ONLY' as const, + configuredCapabilities: configuredCount, + totalCapabilities: providerCapabilities.length, + capabilities: providerCapabilities, + } + }) + + const configuredWorkflows = workflows.filter((workflow) => workflow.status === 'CONFIGURED').length + const status = configuredWorkflows === workflows.length + ? 'CONFIGURED' as const + : configuredWorkflows > 0 + ? 'PARTIAL' as const + : 'NOT_CONFIGURED' as const + + return { + status, + verificationMode: 'CONFIGURATION' as const, + summary: { configuredWorkflows, totalWorkflows: workflows.length }, + workflows, + providers: providerRows, + } +} + +function capabilityForJob(type: JobKind, payload: Record, configuration: ProviderConfiguration): CapabilityId | null { + const provider = typeof payload.provider === 'string' ? payload.provider : null + switch (type) { + case 'SCRIPT_GENERATE': + if (provider === 'agnes') return 'script-agnes' + if (provider === 'generic') return 'script-generic' + if (provider === 'openai') return 'script-openai' + if (!provider) return configured(configuration.agnesApiKey) ? 'script-agnes' : 'script-openai' + break + case 'STORYBOARD_GENERATE': + if (provider === 'agnes') return 'storyboard-agnes' + if (provider === 'generic') return 'storyboard-generic' + if (provider === 'openai') return 'storyboard-openai' + if (!provider) return configured(configuration.agnesApiKey) ? 'storyboard-agnes' : 'storyboard-openai' + break + case 'TTS_GENERATE': + if (!provider || provider === 'openai') return 'tts' + break + case 'VIDEO_GENERATE': + if (provider === 'agnes') return 'video-agnes' + if (provider === 'generic') return 'video-generic' + if (provider === 'replicate') return 'video-replicate' + if (!provider) return configured(configuration.agnesApiKey) ? 'video-agnes' : 'video-replicate' + break + case 'LIPSYNC_GENERATE': + if (!provider || provider === 'replicate') return 'lipsync' + break + case 'ASSET_GENERATE': + if (provider === 'agnes') return 'image-agnes' + if (provider === 'generic') return 'image-generic' + if (provider === 'replicate') return 'image-replicate' + if (provider === 'openai') return 'image-openai' + if (!provider) return configured(configuration.agnesApiKey) ? 'image-agnes' : 'image-openai' + break + default: + return null + } + throw errors.badRequest(`Unsupported provider ${String(provider)} for ${type}`) +} + +export function assertJobProviderConfigured( + type: JobKind, + payload: Record, + configuration = providerConfiguration(), +) { + const capabilityId = capabilityForJob(type, payload, configuration) + if (!capabilityId) return + const definition = capabilityDefinitions(configuration).find((item) => item.id === capabilityId) + if (!definition) throw new Error(`Capability definition ${capabilityId} is missing`) + const missing = missingRequirements(definition, configuration) + if (missing.length > 0) { + throw errors.badRequest(`${definition.label}服务尚未配置`, { + provider: definition.provider, + capability: capabilityId, + missingRequirements: missing, + }) + } +} diff --git a/server/src/providers/replicate.contract.test.ts b/server/src/providers/replicate.contract.test.ts new file mode 100644 index 0000000..e55acf5 --- /dev/null +++ b/server/src/providers/replicate.contract.test.ts @@ -0,0 +1,254 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { config } from '../config.js' +import { ReplicateProvider } from './replicate.js' + +const originalConfiguration = { + token: config.REPLICATE_API_TOKEN, + imageVersion: config.REPLICATE_IMAGE_VERSION, + videoVersion: config.REPLICATE_VIDEO_VERSION, + lipsyncVersion: config.REPLICATE_LIPSYNC_VERSION, + deadlineSeconds: config.REPLICATE_PREDICTION_DEADLINE_SECONDS, +} + +function predictionResponse(output: unknown, id: string) { + return new Response(JSON.stringify({ + id, + status: 'succeeded', + output, + urls: { + get: `https://api.replicate.com/v1/predictions/${id}`, + cancel: `https://api.replicate.com/v1/predictions/${id}/cancel`, + }, + }), { status: 200, headers: { 'content-type': 'application/json' } }) +} + +function expectPredictionRequest(input: Parameters[0], init: Parameters[1], version: string) { + expect(String(input)).toBe('https://api.replicate.com/v1/predictions') + expect(init?.method).toBe('POST') + const headers = new Headers(init?.headers) + expect(headers.get('authorization')).toBe('Bearer contract-replicate-token') + expect(headers.get('prefer')).toBe('wait=60') + expect(headers.get('cancel-after')).toBe('900s') + const body = JSON.parse(init?.body as string) as { version: string; input: Record } + expect(body.version).toBe(version) + return body.input +} + +beforeAll(() => { + config.REPLICATE_API_TOKEN = 'contract-replicate-token' + config.REPLICATE_IMAGE_VERSION = 'contract-image-version' + config.REPLICATE_VIDEO_VERSION = 'contract-video-version' + config.REPLICATE_LIPSYNC_VERSION = 'contract-lipsync-version' + config.REPLICATE_PREDICTION_DEADLINE_SECONDS = 900 +}) + +afterAll(() => { + config.REPLICATE_API_TOKEN = originalConfiguration.token + config.REPLICATE_IMAGE_VERSION = originalConfiguration.imageVersion + config.REPLICATE_VIDEO_VERSION = originalConfiguration.videoVersion + config.REPLICATE_LIPSYNC_VERSION = originalConfiguration.lipsyncVersion + config.REPLICATE_PREDICTION_DEADLINE_SECONDS = originalConfiguration.deadlineSeconds +}) + +describe('Replicate provider contract', () => { + it('sends image generation and continuity references and accepts array output', async () => { + const fetchMock = vi.fn(async (request, init) => { + const input = expectPredictionRequest(request, init, 'contract-image-version') + expect(input).toEqual({ + guidance: 4.5, + prompt: '雨夜中的林遥', + negative_prompt: 'extra fingers', + width: 1024, + height: 1536, + num_outputs: 1, + image: 'https://media.example/linyao.png', + reference_image: 'https://media.example/linyao.png', + }) + return predictionResponse(['https://replicate.delivery/image.png'], 'prediction-image') + }) + + const result = await new ReplicateProvider(fetchMock).generateImage({ + prompt: '雨夜中的林遥', + negativePrompt: 'extra fingers', + width: 1024, + height: 1536, + references: [], + referenceUrls: ['https://media.example/linyao.png'], + params: { + guidance: 4.5, + prompt: 'overridden prompt', + width: 8, + num_outputs: 99, + image: 'https://attacker.example/reference.png', + }, + safetyIdentifier: 'user-replicate-image', + }) + + expect(result).toMatchObject({ + url: 'https://replicate.delivery/image.png', + mimeType: 'image/png', + model: 'contract-image-version', + externalId: 'prediction-image', + }) + }) + + it('sends image-to-video parameters and accepts object URL output', async () => { + const fetchMock = vi.fn(async (request, init) => { + const input = expectPredictionRequest(request, init, 'contract-video-version') + expect(input).toEqual({ + image: 'https://media.example/shot.png', + prompt: '镜头缓慢推进', + duration: 6, + motion_strength: 0.7, + }) + return predictionResponse({ url: 'https://replicate.delivery/video.mp4' }, 'prediction-video') + }) + + const result = await new ReplicateProvider(fetchMock).generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: '镜头缓慢推进', + durationSeconds: 6, + params: { + motion_strength: 0.7, + image: 'https://attacker.example/shot.png', + prompt: 'overridden prompt', + duration: 300, + }, + }) + + expect(result.url).toBe('https://replicate.delivery/video.mp4') + expect(result.usage).toEqual([{ kind: 'VIDEO_SECOND', quantity: 6, credits: 210 }]) + }) + + it('sends video and audio inputs for lipsync and accepts string output', async () => { + const fetchMock = vi.fn(async (request, init) => { + const input = expectPredictionRequest(request, init, 'contract-lipsync-version') + expect(input).toEqual({ + video: 'https://media.example/shot.mp4', + audio: 'https://media.example/dialogue.mp3', + face_enhance: true, + }) + return predictionResponse('https://replicate.delivery/lipsync.mp4', 'prediction-lipsync') + }) + + const result = await new ReplicateProvider(fetchMock).generateLipsync({ + videoUrl: 'https://media.example/shot.mp4', + audioUrl: 'https://media.example/dialogue.mp3', + params: { + face_enhance: true, + video: 'https://attacker.example/shot.mp4', + audio: 'https://attacker.example/dialogue.mp3', + }, + }) + + expect(result).toMatchObject({ + url: 'https://replicate.delivery/lipsync.mp4', + mimeType: 'video/mp4', + externalId: 'prediction-lipsync', + }) + }) + + it('propagates terminal and HTTP failures without exposing the token', async () => { + const terminalFetch = vi.fn(async () => new Response(JSON.stringify({ + id: 'prediction-failed', + status: 'failed', + error: 'model failed safely', + urls: { + get: 'https://api.replicate.com/v1/predictions/prediction-failed', + cancel: 'https://api.replicate.com/v1/predictions/prediction-failed/cancel', + }, + }), { status: 200, headers: { 'content-type': 'application/json' } })) + await expect(new ReplicateProvider(terminalFetch).generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: 'test', + durationSeconds: 5, + })).rejects.toThrow('model failed safely') + + const httpFetch = vi.fn(async () => new Response('rate limited', { status: 429 })) + const request = new ReplicateProvider(httpFetch).generateLipsync({ + videoUrl: 'https://media.example/shot.mp4', + audioUrl: 'https://media.example/dialogue.mp3', + }) + await expect(request).rejects.toThrow('Replicate API 429: rate limited') + await expect(request).rejects.not.toThrow('contract-replicate-token') + }) + + it('rejects untrusted polling URLs before sending the bearer token', async () => { + const fetchMock = vi.fn(async () => new Response(JSON.stringify({ + id: 'prediction-polling', + status: 'processing', + urls: { + get: 'https://api.replicate.com.attacker.example/v1/predictions/prediction-polling', + cancel: 'https://api.replicate.com/v1/predictions/prediction-polling/cancel', + }, + }), { status: 200, headers: { 'content-type': 'application/json' } })) + + await expect(new ReplicateProvider(fetchMock).generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: 'test', + durationSeconds: 5, + })).rejects.toThrow('untrusted get URL') + expect(fetchMock).toHaveBeenCalledTimes(1) + }) + + it('rejects malformed prediction responses and invalid JSON', async () => { + const malformedFetch = vi.fn(async () => new Response(JSON.stringify({ + id: 'prediction-malformed', + status: 'unknown', + output: 'https://replicate.delivery/video.mp4', + }), { status: 200, headers: { 'content-type': 'application/json' } })) + await expect(new ReplicateProvider(malformedFetch).generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: 'test', + durationSeconds: 5, + })).rejects.toThrow('malformed prediction response') + + const invalidJsonFetch = vi.fn(async () => new Response('{', { status: 200 })) + await expect(new ReplicateProvider(invalidJsonFetch).generateLipsync({ + videoUrl: 'https://media.example/shot.mp4', + audioUrl: 'https://media.example/dialogue.mp3', + })).rejects.toThrow('invalid JSON') + }) + + it('bounds HTTP error details', async () => { + const fetchMock = vi.fn(async () => new Response(`provider failure ${'x'.repeat(1000)}END`, { status: 500 })) + const request = new ReplicateProvider(fetchMock).generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: 'test', + durationSeconds: 5, + }) + await expect(request).rejects.toThrow(/^Replicate API 500: provider failure/) + await expect(request).rejects.not.toThrow('END') + }) + + it('cancels a prediction when its local deadline expires', async () => { + let now = 0 + const fetchMock = vi.fn(async (request, init) => { + const url = String(request) + const canceled = url.endsWith('/cancel') && init?.method === 'POST' + return new Response(JSON.stringify({ + id: 'prediction-timeout', + status: canceled ? 'canceled' : 'processing', + urls: { + get: 'https://api.replicate.com/v1/predictions/prediction-timeout', + cancel: 'https://api.replicate.com/v1/predictions/prediction-timeout/cancel', + }, + }), { status: 200, headers: { 'content-type': 'application/json' } }) + }) + const provider = new ReplicateProvider(fetchMock, { + predictionDeadlineSeconds: 5, + pollIntervalMs: 2000, + now: () => now, + sleep: async (milliseconds) => { now += milliseconds }, + }) + + await expect(provider.generateVideo({ + imageUrl: 'https://media.example/shot.png', + prompt: 'test', + durationSeconds: 5, + })).rejects.toThrow('exceeded the 5s deadline and was canceled') + const finalCall = fetchMock.mock.calls.at(-1) + expect(String(finalCall?.[0])).toBe('https://api.replicate.com/v1/predictions/prediction-timeout/cancel') + expect(finalCall?.[1]?.method).toBe('POST') + }) +}) diff --git a/server/src/providers/replicate.ts b/server/src/providers/replicate.ts new file mode 100644 index 0000000..dde0af6 --- /dev/null +++ b/server/src/providers/replicate.ts @@ -0,0 +1,251 @@ +import { setTimeout as delay } from 'node:timers/promises' +import { z } from 'zod' +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import type { + BinaryGenerationResult, + ImageGenerationInput, + ImageProvider, + LipsyncGenerationInput, + VideoGenerationInput, + VideoProvider, +} from './types.js' + +const replicateApiOrigin = 'https://api.replicate.com' +const terminalStatuses = new Set(['succeeded', 'failed', 'canceled']) +const predictionSchema = z.object({ + id: z.string().min(1).max(255).regex(/^[A-Za-z0-9_-]+$/), + status: z.enum(['starting', 'processing', 'succeeded', 'failed', 'canceled']), + output: z.unknown().optional(), + error: z.string().max(10_000).nullable().optional(), + urls: z.object({ + get: z.url().max(2048), + cancel: z.url().max(2048), + }), + metrics: z.object({ predict_time: z.number().finite().nonnegative().optional() }).passthrough().optional(), +}).passthrough() +type Prediction = z.infer + +interface ReplicateRuntimeOptions { + predictionDeadlineSeconds?: number + pollIntervalMs?: number + now?: () => number + sleep?: (milliseconds: number) => Promise +} + +function requireToken() { + if (!config.REPLICATE_API_TOKEN) throw errors.badRequest('REPLICATE_API_TOKEN is not configured') + return config.REPLICATE_API_TOKEN +} + +function requireVersion(value: string | undefined, name: string) { + if (!value) throw errors.badRequest(`${name} is not configured`) + return value +} + +function outputUrl(output: unknown) { + if (typeof output === 'string') return output + if (Array.isArray(output) && typeof output[0] === 'string') return output[0] + if (output && typeof output === 'object' && 'url' in output && typeof output.url === 'string') return output.url + throw new Error('Replicate prediction returned no output URL') +} + +function predictionApiUrl(value: string, predictionId: string, operation: 'get' | 'cancel') { + let url: URL + try { + url = new URL(value) + } catch { + throw new Error(`Replicate prediction returned an invalid ${operation} URL`) + } + const suffix = operation === 'cancel' ? '/cancel' : '' + const expectedPath = `/v1/predictions/${predictionId}${suffix}` + if (url.origin !== replicateApiOrigin + || url.username + || url.password + || url.pathname !== expectedPath + || url.search + || url.hash) { + throw new Error(`Replicate prediction returned an untrusted ${operation} URL`) + } + return url.toString() +} + +function parsePrediction(payload: unknown) { + const parsed = predictionSchema.safeParse(payload) + if (!parsed.success) throw new Error('Replicate API returned a malformed prediction response') + return { + ...parsed.data, + urls: { + get: predictionApiUrl(parsed.data.urls.get, parsed.data.id, 'get'), + cancel: predictionApiUrl(parsed.data.urls.cancel, parsed.data.id, 'cancel'), + }, + } +} + +function protectedInput( + params: Record | undefined, + protectedKeys: string[], + core: Record, +) { + const custom = { ...(params ?? {}) } + protectedKeys.forEach((key) => delete custom[key]) + return { ...custom, ...core } +} + +async function limitedErrorText(response: Response, limit = 500) { + if (!response.body) return '' + const reader = response.body.getReader() + const decoder = new TextDecoder() + let result = '' + let bytesRead = 0 + let truncated = false + try { + while (bytesRead < limit) { + const { done, value } = await reader.read() + if (done) break + const remaining = limit - bytesRead + const chunk = value.subarray(0, remaining) + result += decoder.decode(chunk, { stream: true }) + bytesRead += chunk.byteLength + if (chunk.byteLength < value.byteLength) { + truncated = true + break + } + } + result += decoder.decode() + } finally { + if (truncated || bytesRead >= limit) await reader.cancel().catch(() => undefined) + reader.releaseLock() + } + return result +} + +export class ReplicateProvider implements ImageProvider, VideoProvider { + readonly name = 'replicate' + private readonly token: string + private readonly predictionDeadlineSeconds: number + private readonly pollIntervalMs: number + private readonly now: () => number + private readonly sleep: (milliseconds: number) => Promise + + constructor( + private readonly fetchImpl: typeof fetch = fetch, + options: ReplicateRuntimeOptions = {}, + ) { + this.token = requireToken() + this.predictionDeadlineSeconds = options.predictionDeadlineSeconds ?? config.REPLICATE_PREDICTION_DEADLINE_SECONDS + this.pollIntervalMs = options.pollIntervalMs ?? 2000 + this.now = options.now ?? Date.now + this.sleep = options.sleep ?? ((milliseconds) => delay(milliseconds)) + } + + private async request(url: string, init?: RequestInit, timeoutMs = 60_000) { + const target = new URL(url) + if (target.origin !== replicateApiOrigin || target.username || target.password) { + throw new Error('Refusing to send Replicate credentials to an untrusted URL') + } + const headers = new Headers(init?.headers) + headers.set('Authorization', `Bearer ${this.token}`) + headers.set('Content-Type', 'application/json') + headers.set('Accept', 'application/json') + const response = await this.fetchImpl(url, { + ...init, + headers, + signal: AbortSignal.timeout(Math.max(1, timeoutMs)), + }) + if (!response.ok) { + const message = await limitedErrorText(response) + throw new Error(`Replicate API ${response.status}${message ? `: ${message}` : ''}`) + } + let payload: unknown + try { + payload = await response.json() + } catch { + throw new Error('Replicate API returned invalid JSON') + } + return parsePrediction(payload) + } + + private async predict(version: string, input: Record) { + const deadlineAt = this.now() + this.predictionDeadlineSeconds * 1000 + let prediction = await this.request('https://api.replicate.com/v1/predictions', { + method: 'POST', + headers: { + Prefer: 'wait=60', + 'Cancel-After': `${this.predictionDeadlineSeconds}s`, + }, + body: JSON.stringify({ version, input }), + }, Math.min(60_000, this.predictionDeadlineSeconds * 1000)) + + while (!terminalStatuses.has(prediction.status)) { + const remainingMs = deadlineAt - this.now() + if (remainingMs <= 0) { + await this.request(prediction.urls.cancel, { method: 'POST' }, 10_000).catch(() => undefined) + throw new Error(`Replicate prediction exceeded the ${this.predictionDeadlineSeconds}s deadline and was canceled`) + } + await this.sleep(Math.min(this.pollIntervalMs, remainingMs)) + const requestRemainingMs = deadlineAt - this.now() + if (requestRemainingMs <= 0) continue + prediction = await this.request(prediction.urls.get, undefined, Math.min(60_000, requestRemainingMs)) + } + + if (prediction.status !== 'succeeded') throw new Error(prediction.error || `Replicate prediction ended with ${prediction.status}`) + return prediction + } + + async generateImage(input: ImageGenerationInput): Promise { + const version = requireVersion(config.REPLICATE_IMAGE_VERSION, 'REPLICATE_IMAGE_VERSION') + const referenceUrl = input.referenceUrls[0] + const prediction = await this.predict(version, protectedInput( + input.params, + ['prompt', 'negative_prompt', 'width', 'height', 'num_outputs', 'image', 'reference_image'], + { + prompt: input.prompt, + negative_prompt: input.negativePrompt, + width: input.width, + height: input.height, + num_outputs: 1, + ...(referenceUrl ? { image: referenceUrl, reference_image: referenceUrl } : {}), + }, + )) + return { + url: outputUrl(prediction.output), + mimeType: 'image/png', + model: version, + externalId: prediction.id, + usage: [{ kind: 'IMAGE', quantity: 1, credits: 100 }], + } + } + + async generateVideo(input: VideoGenerationInput): Promise { + const version = requireVersion(config.REPLICATE_VIDEO_VERSION, 'REPLICATE_VIDEO_VERSION') + const prediction = await this.predict(version, protectedInput( + input.params, + ['image', 'prompt', 'duration'], + { image: input.imageUrl, prompt: input.prompt, duration: input.durationSeconds }, + )) + return { + url: outputUrl(prediction.output), + mimeType: 'video/mp4', + model: version, + externalId: prediction.id, + usage: [{ kind: 'VIDEO_SECOND', quantity: input.durationSeconds, credits: input.durationSeconds * 35 }], + } + } + + async generateLipsync(input: LipsyncGenerationInput): Promise { + const version = requireVersion(config.REPLICATE_LIPSYNC_VERSION, 'REPLICATE_LIPSYNC_VERSION') + const prediction = await this.predict(version, protectedInput( + input.params, + ['video', 'audio'], + { video: input.videoUrl, audio: input.audioUrl }, + )) + return { + url: outputUrl(prediction.output), + mimeType: 'video/mp4', + model: version, + externalId: prediction.id, + usage: [{ kind: 'VIDEO_SECOND', quantity: 1, credits: 60 }], + } + } +} diff --git a/server/src/providers/types.ts b/server/src/providers/types.ts new file mode 100644 index 0000000..7d33ac0 --- /dev/null +++ b/server/src/providers/types.ts @@ -0,0 +1,154 @@ +export interface ProviderUsage { + kind: 'TEXT_INPUT_TOKEN' | 'TEXT_OUTPUT_TOKEN' | 'IMAGE' | 'AUDIO_SECOND' | 'VIDEO_SECOND' + quantity: number + credits: number + providerCostUsd?: number +} + +export interface ScriptSceneBeat { + type: 'action' | 'dialogue' | 'transition' + text: string + character: string | null + parenthetical: string | null +} + +export interface ScriptDocument { + title: string + logline: string + estimatedDurationSeconds: number + scenes: Array<{ + number: number + location: string + interiorExterior: '内' | '外' + time: string + summary: string + beats: ScriptSceneBeat[] + }> +} + +export interface ScriptGenerationInput { + instruction: string + projectName: string + genre: string + visualBible: Record + episodeTitle: string + synopsis: string + targetDurationSeconds: number + existingScript?: string + safetyIdentifier: string +} + +export interface ScriptGenerationResult { + document: ScriptDocument + plainText: string + model: string + usage: ProviderUsage[] +} + +export interface StoryboardShot { + sceneNumber: number + title: string + description: string + shotType: string + cameraMotion: string + durationMs: number + characterNames: string[] + sceneName: string | null + subtitleText: string +} + +export interface StoryboardGenerationInput { + projectName: string + genre: string + visualBible: Record + episodeTitle: string + targetDurationSeconds: number + script: string + instruction: string + characterNames: string[] + sceneNames: string[] + safetyIdentifier: string +} + +export interface StoryboardGenerationResult { + shots: StoryboardShot[] + model: string + usage: ProviderUsage[] +} + +export interface ImageReference { + name: string + mimeType: string + data: Buffer +} + +export interface ImageGenerationInput { + prompt: string + negativePrompt?: string + width: number + height: number + references: ImageReference[] + referenceUrls: string[] + params?: Record + safetyIdentifier: string +} + +export interface BinaryGenerationResult { + data?: Buffer + url?: string + sourceUrl?: string + mimeType: string + model: string + width?: number + height?: number + externalId?: string + seed?: string + usage: ProviderUsage[] +} + +export interface SpeechGenerationInput { + text: string + voice?: string + instructions?: string + speed?: number + safetyIdentifier: string +} + +export interface VideoGenerationInput { + prompt: string + imageUrl: string + imageData?: Buffer + imageMimeType?: string + sourceWidth?: number + sourceHeight?: number + durationSeconds: number + params?: Record +} + +export interface LipsyncGenerationInput { + videoUrl: string + audioUrl: string + params?: Record +} + +export interface TextProvider { + readonly name: string + generateScript(input: ScriptGenerationInput): Promise + generateStoryboard(input: StoryboardGenerationInput): Promise +} + +export interface ImageProvider { + readonly name: string + generateImage(input: ImageGenerationInput): Promise +} + +export interface SpeechProvider { + readonly name: string + generateSpeech(input: SpeechGenerationInput): Promise +} + +export interface VideoProvider { + readonly name: string + generateVideo(input: VideoGenerationInput): Promise + generateLipsync(input: LipsyncGenerationInput): Promise +} diff --git a/server/src/providers/verification.test.ts b/server/src/providers/verification.test.ts new file mode 100644 index 0000000..a8e18cb --- /dev/null +++ b/server/src/providers/verification.test.ts @@ -0,0 +1,190 @@ +import { describe, expect, it, vi } from 'vitest' +import type { ProviderConfiguration } from './readiness.js' +import { + providerCredentialConfigured, + providerVerificationFingerprint, + verifyProviderConnection, +} from './verification.js' + +const configuration: ProviderConfiguration = { + openaiApiKey: 'openai-verification-secret', + openaiTextModel: 'text-model', + openaiImageModel: 'image-model', + openaiTtsModel: 'text-model', + agnesApiKey: 'agnes-verification-secret', + agnesTextModel: 'agnes-2.5-flash', + agnesImageModel: 'agnes-image-2.1-flash', + agnesVideoModel: 'agnes-video-v2.0', + replicateApiToken: 'replicate-verification-secret', + replicateImageVersion: 'image-version', + replicateVideoVersion: 'video-version', + replicateLipsyncVersion: 'lipsync-version', + genericTextApiKey: 'generic-text-verification-secret', + genericTextBaseUrl: 'https://text.vendor.test/v1', + genericTextModel: 'generic-text-model', + genericImageApiKey: 'generic-image-verification-secret', + genericImageBaseUrl: 'https://image.vendor.test/v1', + genericImageModel: 'generic-image-model', + genericVideoApiKey: 'generic-video-verification-secret', + genericVideoBaseUrl: 'https://video.vendor.test/v1', + genericVideoModel: 'generic-video-model', +} + +function jsonResponse(payload: unknown, status = 200) { + return new Response(JSON.stringify(payload), { + status, + headers: { 'content-type': 'application/json' }, + }) +} + +describe('provider connection verification', () => { + it('retrieves every distinct configured OpenAI model with bearer authentication', async () => { + const fetchMock = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + const model = decodeURIComponent(new URL(String(url)).pathname.split('/').at(-1)!) + return jsonResponse({ id: model, created: 1, object: 'model', owned_by: 'openai' }) + }) + + const result = await verifyProviderConnection('openai', configuration, fetchMock as typeof fetch) + + expect(result).toMatchObject({ + status: 'VERIFIED', + errorCode: null, + details: { scope: 'credentials_and_models', models: ['text-model', 'image-model'] }, + }) + expect(fetchMock).toHaveBeenCalledTimes(2) + expect(fetchMock.mock.calls.map(([url]) => String(url))).toEqual([ + 'https://api.openai.com/v1/models/text-model', + 'https://api.openai.com/v1/models/image-model', + ]) + for (const [, init] of fetchMock.mock.calls) { + expect(init?.method).toBe('GET') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer openai-verification-secret') + expect(init?.redirect).toBe('error') + } + }) + + it('verifies Replicate through the authenticated account endpoint', async () => { + const fetchMock = vi.fn(async () => jsonResponse({ type: 'organization', name: 'FrameFlow' })) + const result = await verifyProviderConnection('replicate', configuration, fetchMock as typeof fetch) + + expect(result).toMatchObject({ + status: 'VERIFIED', + details: { scope: 'credentials', accountType: 'organization' }, + }) + expect(fetchMock).toHaveBeenCalledTimes(1) + const [url, init] = fetchMock.mock.calls[0] + expect(String(url)).toBe('https://api.replicate.com/v1/account') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer replicate-verification-secret') + }) + + it('verifies every configured Agnes model through the authenticated model list', async () => { + const fetchMock = vi.fn(async () => jsonResponse({ + object: 'list', + data: [ + { id: 'agnes-2.5-flash', object: 'model' }, + { id: 'agnes-image-2.1-flash', object: 'model' }, + { id: 'agnes-video-v2.0', object: 'model' }, + ], + })) + + const result = await verifyProviderConnection('agnes', configuration, fetchMock as typeof fetch) + + expect(result).toMatchObject({ + status: 'VERIFIED', + errorCode: null, + details: { + scope: 'credentials_and_models', + models: ['agnes-2.5-flash', 'agnes-image-2.1-flash', 'agnes-video-v2.0'], + }, + }) + expect(fetchMock).toHaveBeenCalledTimes(1) + const [url, init] = fetchMock.mock.calls[0] + expect(String(url)).toBe('https://api.agnes-ai.cn/v1/models') + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer agnes-verification-secret') + }) + + it('verifies each independently configured generic capability', async () => { + const fetchMock = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + const model = decodeURIComponent(new URL(String(url)).pathname.split('/').at(-1)!) + const hostname = new URL(String(url)).hostname + const expectedKey = hostname.startsWith('text.') + ? 'generic-text-verification-secret' + : hostname.startsWith('image.') + ? 'generic-image-verification-secret' + : 'generic-video-verification-secret' + expect(new Headers(init?.headers).get('authorization')).toBe(`Bearer ${expectedKey}`) + return jsonResponse({ id: model, object: 'model' }) + }) + + const result = await verifyProviderConnection('generic', configuration, fetchMock as typeof fetch) + + expect(result).toMatchObject({ + status: 'VERIFIED', + details: { + scope: 'credentials_and_models', + capabilities: [ + { capability: 'text', model: 'generic-text-model' }, + { capability: 'image', model: 'generic-image-model' }, + { capability: 'video', model: 'generic-video-model' }, + ], + }, + }) + expect(fetchMock.mock.calls.map(([url]) => String(url))).toEqual([ + 'https://text.vendor.test/v1/models/generic-text-model', + 'https://image.vendor.test/v1/models/generic-image-model', + 'https://video.vendor.test/v1/models/generic-video-model', + ]) + }) + + it.each([ + { + label: 'provider authentication failure', + fetchImpl: async () => new Response('openai-verification-secret', { status: 401 }), + code: 'AUTHENTICATION_FAILED', + }, + { + label: 'timeout', + fetchImpl: async () => { throw Object.assign(new Error('openai-verification-secret'), { name: 'TimeoutError' }) }, + code: 'TIMEOUT', + }, + { + label: 'malformed JSON', + fetchImpl: async () => new Response('{not-json', { status: 200, headers: { 'content-type': 'application/json' } }), + code: 'INVALID_RESPONSE', + }, + ])('returns a bounded sanitized result for $label', async ({ fetchImpl, code }) => { + const result = await verifyProviderConnection('openai', configuration, fetchImpl as typeof fetch) + expect(result.status).toBe('FAILED') + expect(result.errorCode).toBe(code) + expect(JSON.stringify(result)).not.toContain('openai-verification-secret') + expect(JSON.stringify(result).length).toBeLessThan(1000) + }) + + it('detects missing credentials without calling the network', async () => { + const fetchMock = vi.fn() + const missing = { ...configuration, openaiApiKey: undefined } + expect(providerCredentialConfigured('openai', missing)).toBe(false) + const result = await verifyProviderConnection('openai', missing, fetchMock as typeof fetch) + expect(result).toMatchObject({ status: 'FAILED', errorCode: 'NOT_CONFIGURED' }) + expect(fetchMock).not.toHaveBeenCalled() + }) + + it('invalidates persisted results when credentials or model configuration changes', () => { + const fingerprint = providerVerificationFingerprint('openai', configuration) + expect(fingerprint).toHaveLength(64) + expect(providerVerificationFingerprint('openai', { ...configuration })).toBe(fingerprint) + expect(providerVerificationFingerprint('openai', { ...configuration, openaiApiKey: 'rotated-secret' })).not.toBe(fingerprint) + expect(providerVerificationFingerprint('openai', { ...configuration, openaiImageModel: 'next-image-model' })).not.toBe(fingerprint) + + const agnesFingerprint = providerVerificationFingerprint('agnes', configuration) + expect(agnesFingerprint).toHaveLength(64) + expect(providerVerificationFingerprint('agnes', { ...configuration })).toBe(agnesFingerprint) + expect(providerVerificationFingerprint('agnes', { ...configuration, agnesApiKey: 'rotated-secret' })).not.toBe(agnesFingerprint) + expect(providerVerificationFingerprint('agnes', { ...configuration, agnesVideoModel: 'next-video-model' })).not.toBe(agnesFingerprint) + + const genericFingerprint = providerVerificationFingerprint('generic', configuration) + expect(genericFingerprint).toHaveLength(64) + expect(providerVerificationFingerprint('generic', { ...configuration })).toBe(genericFingerprint) + expect(providerVerificationFingerprint('generic', { ...configuration, genericVideoModel: 'next-video-model' })).not.toBe(genericFingerprint) + }) +}) diff --git a/server/src/providers/verification.ts b/server/src/providers/verification.ts new file mode 100644 index 0000000..a7284e4 --- /dev/null +++ b/server/src/providers/verification.ts @@ -0,0 +1,283 @@ +import { createHash } from 'node:crypto' +import { z } from 'zod' +import type { ProviderConfiguration } from './readiness.js' + +export const providerIds = ['openai', 'replicate', 'agnes', 'generic'] as const +export type ProviderId = typeof providerIds[number] + +export interface ProviderVerificationResult { + status: 'VERIFIED' | 'FAILED' + latencyMs: number + errorCode: string | null + message: string | null + details: Record +} + +const openAIModelSchema = z.object({ + id: z.string().trim().min(1).max(255), + created: z.number().int().nonnegative(), + object: z.literal('model'), + owned_by: z.string().trim().min(1).max(255), +}).passthrough() + +const replicateAccountSchema = z.object({ + type: z.enum(['user', 'organization']), +}).passthrough() + +const agnesModelListSchema = z.object({ + object: z.literal('list'), + data: z.array(z.object({ + id: z.string().trim().min(1).max(255), + object: z.literal('model'), + }).passthrough()), +}).passthrough() + +const genericModelSchema = z.object({ + id: z.string().trim().min(1).max(255), + object: z.string().trim().min(1).max(80).optional(), +}).passthrough() + +class VerificationFailure extends Error { + constructor(readonly code: string, message: string) { + super(message) + this.name = 'VerificationFailure' + } +} + +function elapsedMs(startedAt: number) { + return Math.max(0, Math.round(performance.now() - startedAt)) +} + +function httpFailure(provider: ProviderId, status: number) { + const label = provider === 'openai' + ? 'OpenAI' + : provider === 'replicate' + ? 'Replicate' + : provider === 'agnes' + ? 'Agnes AI' + : '通用兼容接口' + if (status === 401 || status === 403) return new VerificationFailure('AUTHENTICATION_FAILED', `${label} 凭证无效或无权访问`) + if (status === 404) return new VerificationFailure('MODEL_NOT_FOUND', `${label} 模型或验证端点不可访问`) + if (status === 429) return new VerificationFailure('RATE_LIMITED', `${label} 暂时限流,请稍后重试`) + if (status >= 500) return new VerificationFailure('PROVIDER_UNAVAILABLE', `${label} 服务暂时不可用`) + return new VerificationFailure('PROVIDER_REJECTED', `${label} 拒绝了验证请求`) +} + +async function requestJson(input: { + provider: ProviderId + url: string + credential: string + fetchImpl: typeof fetch + signal: AbortSignal +}) { + let response: Response + try { + response = await input.fetchImpl(input.url, { + method: 'GET', + headers: { + Authorization: `Bearer ${input.credential}`, + Accept: 'application/json', + 'User-Agent': 'FrameFlow-Provider-Verification/1.0', + }, + redirect: 'error', + signal: input.signal, + }) + } catch (error) { + const name = error && typeof error === 'object' && 'name' in error ? error.name : null + if (name === 'TimeoutError' || name === 'AbortError') { + throw new VerificationFailure('TIMEOUT', '供应商连接验证超时') + } + throw new VerificationFailure('NETWORK_ERROR', '无法连接供应商验证端点') + } + if (!response.ok) throw httpFailure(input.provider, response.status) + try { + return await response.json() as unknown + } catch { + throw new VerificationFailure('INVALID_RESPONSE', '供应商返回了无法解析的验证响应') + } +} + +export function providerCredentialConfigured(provider: ProviderId, configuration: ProviderConfiguration) { + if (provider === 'openai') return Boolean(configuration.openaiApiKey?.trim()) + if (provider === 'replicate') return Boolean(configuration.replicateApiToken?.trim()) + if (provider === 'agnes') return Boolean(configuration.agnesApiKey?.trim()) + return Boolean( + configuration.genericTextApiKey?.trim() + || configuration.genericImageApiKey?.trim() + || configuration.genericVideoApiKey?.trim(), + ) +} + +export function providerVerificationFingerprint(provider: ProviderId, configuration: ProviderConfiguration) { + const values = provider === 'openai' + ? [provider, configuration.openaiApiKey ?? '', configuration.openaiTextModel, configuration.openaiImageModel, configuration.openaiTtsModel] + : provider === 'replicate' + ? [provider, configuration.replicateApiToken ?? '', configuration.replicateImageVersion ?? '', configuration.replicateVideoVersion ?? '', configuration.replicateLipsyncVersion ?? ''] + : provider === 'agnes' + ? [provider, configuration.agnesApiKey ?? '', configuration.agnesTextModel ?? '', configuration.agnesImageModel ?? '', configuration.agnesVideoModel ?? ''] + : [ + provider, + configuration.genericTextApiKey ?? '', configuration.genericTextBaseUrl ?? '', configuration.genericTextModel ?? '', + configuration.genericImageApiKey ?? '', configuration.genericImageBaseUrl ?? '', configuration.genericImageModel ?? '', + configuration.genericVideoApiKey ?? '', configuration.genericVideoBaseUrl ?? '', configuration.genericVideoModel ?? '', + ] + return createHash('sha256').update(JSON.stringify(values)).digest('hex') +} + +export async function verifyProviderConnection( + provider: ProviderId, + configuration: ProviderConfiguration, + fetchImpl: typeof fetch = fetch, +): Promise { + const startedAt = performance.now() + try { + if (!providerCredentialConfigured(provider, configuration)) { + const requirement = provider === 'openai' + ? 'OPENAI_API_KEY' + : provider === 'replicate' + ? 'REPLICATE_API_TOKEN' + : provider === 'agnes' + ? 'AGNES_API_KEY' + : 'GENERIC_TEXT_API_KEY、GENERIC_IMAGE_API_KEY 或 GENERIC_VIDEO_API_KEY' + throw new VerificationFailure('NOT_CONFIGURED', `${requirement} 尚未配置`) + } + const signal = AbortSignal.timeout(15_000) + if (provider === 'openai') { + const credential = configuration.openaiApiKey! + const models = [...new Set([ + configuration.openaiTextModel, + configuration.openaiImageModel, + configuration.openaiTtsModel, + ])] + const verifiedModels: string[] = [] + for (const model of models) { + const payload = await requestJson({ + provider, + url: `https://api.openai.com/v1/models/${encodeURIComponent(model)}`, + credential, + fetchImpl, + signal, + }) + const parsed = openAIModelSchema.safeParse(payload) + if (!parsed.success) throw new VerificationFailure('INVALID_RESPONSE', 'OpenAI 返回了不符合契约的模型响应') + verifiedModels.push(model) + } + return { + status: 'VERIFIED', + latencyMs: elapsedMs(startedAt), + errorCode: null, + message: null, + details: { scope: 'credentials_and_models', models: verifiedModels }, + } + } + + if (provider === 'agnes') { + const payload = await requestJson({ + provider, + url: 'https://api.agnes-ai.cn/v1/models', + credential: configuration.agnesApiKey!, + fetchImpl, + signal, + }) + const parsed = agnesModelListSchema.safeParse(payload) + if (!parsed.success) throw new VerificationFailure('INVALID_RESPONSE', 'Agnes AI 返回了不符合契约的模型清单') + const available = new Set(parsed.data.data.map((model) => model.id)) + const configuredModels = [...new Set([ + configuration.agnesTextModel, + configuration.agnesImageModel, + configuration.agnesVideoModel, + ].filter((model): model is string => Boolean(model)))] + const missing = configuredModels.filter((model) => !available.has(model)) + if (missing.length > 0) throw new VerificationFailure('MODEL_NOT_FOUND', `Agnes AI 模型不可访问:${missing.join('、')}`) + return { + status: 'VERIFIED', + latencyMs: elapsedMs(startedAt), + errorCode: null, + message: null, + details: { scope: 'credentials_and_models', models: configuredModels }, + } + } + + if (provider === 'generic') { + const capabilities = [ + { + capability: 'text', + apiKey: configuration.genericTextApiKey, + baseUrl: configuration.genericTextBaseUrl, + model: configuration.genericTextModel, + }, + { + capability: 'image', + apiKey: configuration.genericImageApiKey, + baseUrl: configuration.genericImageBaseUrl, + model: configuration.genericImageModel, + }, + { + capability: 'video', + apiKey: configuration.genericVideoApiKey, + baseUrl: configuration.genericVideoBaseUrl, + model: configuration.genericVideoModel, + }, + ].filter((item) => item.apiKey && item.baseUrl && item.model) as Array<{ + capability: string + apiKey: string + baseUrl: string + model: string + }> + if (capabilities.length === 0) { + throw new VerificationFailure('NOT_CONFIGURED', '通用兼容接口至少需要一组完整的 API_KEY、BASE_URL 和 MODEL') + } + const verified: Array<{ capability: string; model: string }> = [] + for (const capability of capabilities) { + const modelUrl = `${capability.baseUrl.replace(/\/$/, '')}/models/${encodeURIComponent(capability.model)}` + const payload = await requestJson({ + provider, + url: modelUrl, + credential: capability.apiKey, + fetchImpl, + signal, + }) + const parsed = genericModelSchema.safeParse(payload) + if (!parsed.success || parsed.data.id !== capability.model) { + throw new VerificationFailure('INVALID_RESPONSE', `通用${capability.capability}接口返回了不符合契约的模型响应`) + } + verified.push({ capability: capability.capability, model: capability.model }) + } + return { + status: 'VERIFIED', + latencyMs: elapsedMs(startedAt), + errorCode: null, + message: null, + details: { scope: 'credentials_and_models', capabilities: verified }, + } + } + + const payload = await requestJson({ + provider, + url: 'https://api.replicate.com/v1/account', + credential: configuration.replicateApiToken!, + fetchImpl, + signal, + }) + const parsed = replicateAccountSchema.safeParse(payload) + if (!parsed.success) throw new VerificationFailure('INVALID_RESPONSE', 'Replicate 返回了不符合契约的账号响应') + return { + status: 'VERIFIED', + latencyMs: elapsedMs(startedAt), + errorCode: null, + message: null, + details: { scope: 'credentials', accountType: parsed.data.type }, + } + } catch (error) { + const failure = error instanceof VerificationFailure + ? error + : new VerificationFailure('VERIFICATION_FAILED', '供应商连接验证失败') + return { + status: 'FAILED', + latencyMs: elapsedMs(startedAt), + errorCode: failure.code, + message: failure.message, + details: {}, + } + } +} diff --git a/server/src/publishing/connector.test.ts b/server/src/publishing/connector.test.ts new file mode 100644 index 0000000..7f3bff8 --- /dev/null +++ b/server/src/publishing/connector.test.ts @@ -0,0 +1,63 @@ +import { describe, expect, it, vi } from 'vitest' +import { ConnectorPublishingAdapter, connectorWebhookSignature, verifyConnectorWebhookSignature } from './connector.js' + +function jsonResponse(body: unknown, status = 200) { + return new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } }) +} + +describe('publishing connector adapter', () => { + it('sends authenticated platform-scoped OAuth and publishing requests', async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(jsonResponse({ authorizationUrl: 'https://open.example.cn/oauth', codeVerifier: 'v'.repeat(48) })) + .mockResolvedValueOnce(jsonResponse({ + externalAccountId: 'creator-1', + displayName: '创作者一号', + accessToken: 'access-one', + refreshToken: 'refresh-one', + tokenExpiresAt: '2026-08-01T00:00:00.000Z', + scopes: ['video.publish'], + })) + .mockResolvedValueOnce(jsonResponse({ status: 'PUBLISHING', externalId: 'video-1' })) + .mockResolvedValueOnce(jsonResponse({ revoked: true })) + const adapter = new ConnectorPublishingAdapter('DOUYIN', { + url: 'https://publisher.frameflow.cn/root', + secret: 'connector-secret-with-32-characters', + timeoutMs: 5000, + }, fetchMock) + + const authorization = await adapter.createAuthorization({ state: 'state-one', callbackUrl: 'https://studio.frameflow.cn/callback' }) + expect(authorization.codeVerifier).toHaveLength(48) + const account = await adapter.exchangeAuthorization({ code: 'code-one', callbackUrl: 'https://studio.frameflow.cn/callback', codeVerifier: authorization.codeVerifier }) + const published = await adapter.publish({ + deliveryId: crypto.randomUUID(), + sourceUrl: 'https://media.frameflow.cn/render.mp4?signature=secret', + callbackUrl: 'https://studio.frameflow.cn/webhook', + account: { externalAccountId: account.externalAccountId, accessToken: account.accessToken, refreshToken: account.refreshToken }, + destination: { title: '第一集' }, + }) + await adapter.revoke({ externalAccountId: account.externalAccountId, accessToken: account.accessToken }) + + expect(published).toEqual({ status: 'PUBLISHING', externalId: 'video-1' }) + expect(fetchMock).toHaveBeenCalledTimes(4) + for (const call of fetchMock.mock.calls) { + const init = call[1] + expect(new Headers(init?.headers).get('authorization')).toBe('Bearer connector-secret-with-32-characters') + expect(JSON.parse(String(init?.body)).platform).toBe('DOUYIN') + } + expect(String(fetchMock.mock.calls[0]?.[0])).toBe('https://publisher.frameflow.cn/v1/oauth/authorize') + expect(String(fetchMock.mock.calls[2]?.[0])).toBe('https://publisher.frameflow.cn/v1/publish') + }) + + it('reports missing connector configuration and authenticates webhook bytes', () => { + const adapter = new ConnectorPublishingAdapter('BILIBILI', { timeoutMs: 5000 }) + expect(adapter.readiness()).toEqual({ + status: 'NOT_CONFIGURED', + missingRequirements: ['PUBLISHING_CONNECTOR_URL', 'PUBLISHING_CONNECTOR_SECRET'], + }) + const payload = Buffer.from('{"eventId":"event-1"}') + const secret = 'webhook-secret-with-at-least-32-characters' + const signature = connectorWebhookSignature(payload, secret) + expect(verifyConnectorWebhookSignature(payload, signature, secret)).toBe(true) + expect(verifyConnectorWebhookSignature(Buffer.from(`${payload} `), signature, secret)).toBe(false) + }) +}) diff --git a/server/src/publishing/connector.ts b/server/src/publishing/connector.ts new file mode 100644 index 0000000..a050127 --- /dev/null +++ b/server/src/publishing/connector.ts @@ -0,0 +1,164 @@ +import { createHmac, timingSafeEqual } from 'node:crypto' +import { z } from 'zod' +import { config } from '../config.js' +import { errors } from '../lib/errors.js' +import { + externalPublishingPlatforms, + type ExternalPublishingPlatform, + type PublishingAccountCredentials, + type PublishingAdapter, + type PublishingAdapterRegistry, + type PublishingAuthorizationResult, + type PublishingResult, +} from './types.js' + +const authorizationResponse = z.object({ + authorizationUrl: z.url(), + codeVerifier: z.string().min(32).max(512).optional(), +}) +const accountResponse = z.object({ + externalAccountId: z.string().min(1).max(255), + displayName: z.string().min(1).max(180), + avatarUrl: z.url().optional(), + accessToken: z.string().min(1), + refreshToken: z.string().min(1).optional(), + tokenExpiresAt: z.iso.datetime({ offset: true }).optional(), + scopes: z.array(z.string().max(160)).max(100).optional(), + metadata: z.record(z.string(), z.unknown()).optional(), +}) +const publishResponse = z.object({ + status: z.enum(['PUBLISHING', 'PUBLISHED']), + externalId: z.string().min(1).max(255), + publishedUrl: z.url().optional(), + credentials: z.object({ + accessToken: z.string().min(1), + refreshToken: z.string().min(1).optional(), + tokenExpiresAt: z.iso.datetime({ offset: true }).optional(), + scopes: z.array(z.string().max(160)).max(100).optional(), + }).optional(), +}) + +type ConnectorConfiguration = { + url?: string + secret?: string + timeoutMs: number +} + +function connectorConfiguration(): ConnectorConfiguration { + return { + ...(config.PUBLISHING_CONNECTOR_URL ? { url: config.PUBLISHING_CONNECTOR_URL } : {}), + ...(config.PUBLISHING_CONNECTOR_SECRET ? { secret: config.PUBLISHING_CONNECTOR_SECRET } : {}), + timeoutMs: config.PUBLISHING_CONNECTOR_TIMEOUT_MS, + } +} + +export class ConnectorPublishingAdapter implements PublishingAdapter { + constructor( + readonly platform: ExternalPublishingPlatform, + private readonly configuration: ConnectorConfiguration = connectorConfiguration(), + private readonly fetchImpl: typeof fetch = fetch, + ) {} + + readiness() { + const missingRequirements = [ + ...(!this.configuration.url ? ['PUBLISHING_CONNECTOR_URL'] : []), + ...(!this.configuration.secret ? ['PUBLISHING_CONNECTOR_SECRET'] : []), + ] + return { + status: missingRequirements.length === 0 ? 'CONFIGURED' as const : 'NOT_CONFIGURED' as const, + missingRequirements, + } + } + + private async call(path: string, body: Record, schema: z.ZodType): Promise { + const readiness = this.readiness() + if (readiness.status !== 'CONFIGURED' || !this.configuration.url || !this.configuration.secret) { + throw errors.serviceUnavailable(`${this.platform} publishing connector is not configured`, { + platform: this.platform, + missingRequirements: readiness.missingRequirements, + }) + } + const response = await this.fetchImpl(new URL(path, `${this.configuration.url.replace(/\/$/, '')}/`), { + method: 'POST', + headers: { + authorization: `Bearer ${this.configuration.secret}`, + 'content-type': 'application/json', + 'user-agent': 'FrameFlow-Publishing/1.0', + }, + body: JSON.stringify({ platform: this.platform, ...body }), + signal: AbortSignal.timeout(this.configuration.timeoutMs), + }) + if (!response.ok) { + const message = (await response.text()).slice(0, 500) + throw new Error(`Publishing connector returned ${response.status}${message ? `: ${message}` : ''}`) + } + return schema.parse(await response.json()) + } + + async createAuthorization(input: { state: string; callbackUrl: string }): Promise { + const result = await this.call('/v1/oauth/authorize', input, authorizationResponse) + return { + authorizationUrl: result.authorizationUrl, + ...(result.codeVerifier ? { codeVerifier: result.codeVerifier } : {}), + } + } + + async exchangeAuthorization(input: { code: string; callbackUrl: string; codeVerifier?: string }): Promise { + const result = await this.call('/v1/oauth/exchange', input, accountResponse) + return { + externalAccountId: result.externalAccountId, + displayName: result.displayName, + accessToken: result.accessToken, + ...(result.avatarUrl ? { avatarUrl: result.avatarUrl } : {}), + ...(result.refreshToken ? { refreshToken: result.refreshToken } : {}), + ...(result.tokenExpiresAt ? { tokenExpiresAt: result.tokenExpiresAt } : {}), + ...(result.scopes ? { scopes: result.scopes } : {}), + ...(result.metadata ? { metadata: result.metadata } : {}), + } + } + + publish(input: { + deliveryId: string + sourceUrl: string + callbackUrl: string + account: { externalAccountId: string; accessToken: string; refreshToken?: string } + destination: Record + }): Promise { + return this.call('/v1/publish', input, publishResponse).then((result) => ({ + status: result.status, + externalId: result.externalId, + ...(result.publishedUrl ? { publishedUrl: result.publishedUrl } : {}), + ...(result.credentials ? { + credentials: { + accessToken: result.credentials.accessToken, + ...(result.credentials.refreshToken ? { refreshToken: result.credentials.refreshToken } : {}), + ...(result.credentials.tokenExpiresAt ? { tokenExpiresAt: result.credentials.tokenExpiresAt } : {}), + ...(result.credentials.scopes ? { scopes: result.credentials.scopes } : {}), + }, + } : {}), + })) + } + + async revoke(input: { externalAccountId: string; accessToken: string; refreshToken?: string }) { + await this.call('/v1/oauth/revoke', input, z.object({ revoked: z.boolean() })) + } +} + +export function createPublishingAdapterRegistry(): PublishingAdapterRegistry { + return new Map(externalPublishingPlatforms.map((platform) => [platform, new ConnectorPublishingAdapter(platform)])) +} + +export function publishingConnectorCallbackUrl() { + return new URL('/api/v1/publishing/webhooks/connector', `${config.API_PUBLIC_ORIGIN}/`).toString() +} + +export function connectorWebhookSignature(payload: Buffer | string, secret = config.PUBLISHING_CONNECTOR_SECRET ?? '') { + return `sha256=${createHmac('sha256', secret).update(payload).digest('hex')}` +} + +export function verifyConnectorWebhookSignature(payload: Buffer, signature: string | undefined, secret = config.PUBLISHING_CONNECTOR_SECRET) { + if (!secret || !signature) return false + const expected = Buffer.from(connectorWebhookSignature(payload, secret)) + const actual = Buffer.from(signature) + return expected.length === actual.length && timingSafeEqual(expected, actual) +} diff --git a/server/src/publishing/types.ts b/server/src/publishing/types.ts new file mode 100644 index 0000000..a4cd58c --- /dev/null +++ b/server/src/publishing/types.ts @@ -0,0 +1,71 @@ +export const externalPublishingPlatforms = ['DOUYIN', 'KUAISHOU', 'BILIBILI', 'XIAOHONGSHU'] as const +export type ExternalPublishingPlatform = typeof externalPublishingPlatforms[number] +export type PublishingPlatform = 'DOWNLOAD' | ExternalPublishingPlatform + +export const publishingPlatformDetails: Record = { + DOWNLOAD: { label: '下载交付', description: '生成限时安全下载链接' }, + DOUYIN: { label: '抖音', description: '发布到已授权的抖音创作者账号' }, + KUAISHOU: { label: '快手', description: '发布到已授权的快手创作者账号' }, + BILIBILI: { label: 'B 站', description: '发布到已授权的哔哩哔哩账号' }, + XIAOHONGSHU: { label: '小红书', description: '发布到已授权的小红书专业号' }, +} + +export interface PublishingAdapterReadiness { + status: 'CONFIGURED' | 'NOT_CONFIGURED' + missingRequirements: string[] +} + +export interface PublishingAuthorizationResult { + authorizationUrl: string + codeVerifier?: string +} + +export interface PublishingAccountCredentials { + externalAccountId: string + displayName: string + avatarUrl?: string + accessToken: string + refreshToken?: string + tokenExpiresAt?: string + scopes?: string[] + metadata?: Record +} + +export interface PublishingResult { + status: 'PUBLISHING' | 'PUBLISHED' + externalId: string + publishedUrl?: string + credentials?: Pick +} + +export interface PublishingAdapter { + readonly platform: ExternalPublishingPlatform + readiness(): PublishingAdapterReadiness + createAuthorization(input: { + state: string + callbackUrl: string + }): Promise + exchangeAuthorization(input: { + code: string + callbackUrl: string + codeVerifier?: string + }): Promise + publish(input: { + deliveryId: string + sourceUrl: string + callbackUrl: string + account: { + externalAccountId: string + accessToken: string + refreshToken?: string + } + destination: Record + }): Promise + revoke(input: { + externalAccountId: string + accessToken: string + refreshToken?: string + }): Promise +} + +export type PublishingAdapterRegistry = ReadonlyMap diff --git a/server/src/queue/client.ts b/server/src/queue/client.ts new file mode 100644 index 0000000..fed01c9 --- /dev/null +++ b/server/src/queue/client.ts @@ -0,0 +1,132 @@ +import { FlowProducer, Queue } from 'bullmq' +import { and, eq, gte, inArray, lt, sql } from 'drizzle-orm' +import { db } from '../db/client.js' +import { generationJobs, usageLedger, workspaces } from '../db/schema.js' +import { billingPeriod, estimateJobCredits } from '../lib/billing.js' +import { errors } from '../lib/errors.js' +import { publishRealtimeEvent } from '../lib/realtime.js' +import { assertJobProviderConfigured } from '../providers/readiness.js' +import { createRedisConnection } from './connection.js' +import { GENERATION_QUEUE, type GenerationJobData, type GenerationJobResult, type JobKind } from './types.js' + +const queueConnection = createRedisConnection() +const flowConnection = createRedisConnection() + +export const generationQueue = new Queue(GENERATION_QUEUE, { + connection: queueConnection, + defaultJobOptions: { + attempts: 3, + backoff: { type: 'exponential', delay: 3000 }, + removeOnComplete: { age: 24 * 60 * 60, count: 1000 }, + removeOnFail: { age: 7 * 24 * 60 * 60, count: 5000 }, + }, +}) + +export const generationFlowProducer = new FlowProducer({ connection: flowConnection }) + +export async function enqueueGeneration(input: { + workspaceId: string + projectId?: string + episodeId?: string + userId: string + type: JobKind + idempotencyKey: string + payload: Record + maxAttempts?: number + delayMs?: number +}) { + const estimatedCredits = await estimateJobCredits(input.type, input.payload) + const persisted = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`billing:${input.workspaceId}`}))`) + const [existing] = await tx.select().from(generationJobs).where(and( + eq(generationJobs.workspaceId, input.workspaceId), + eq(generationJobs.idempotencyKey, input.idempotencyKey), + )).limit(1) + if (existing) return { record: existing, deduplicated: true } + + const [workspace] = await tx.select({ monthlyCreditLimit: workspaces.monthlyCreditLimit }).from(workspaces) + .where(eq(workspaces.id, input.workspaceId)).limit(1) + if (!workspace) throw errors.notFound('Workspace') + const { start, end } = billingPeriod() + const [[usage], [reservation]] = await Promise.all([ + tx.select({ credits: sql`coalesce(sum(${usageLedger.credits}), 0)` }).from(usageLedger).where(and( + eq(usageLedger.workspaceId, input.workspaceId), + gte(usageLedger.occurredAt, start), + lt(usageLedger.occurredAt, end), + )), + tx.select({ credits: sql`coalesce(sum(${generationJobs.estimatedCredits}), 0)` }).from(generationJobs).where(and( + eq(generationJobs.workspaceId, input.workspaceId), + inArray(generationJobs.status, ['QUEUED', 'RUNNING']), + )), + ]) + const usedCredits = Number(usage?.credits ?? 0) + const reservedCredits = Number(reservation?.credits ?? 0) + const remainingCredits = Math.max(0, workspace.monthlyCreditLimit - usedCredits - reservedCredits) + if (estimatedCredits > remainingCredits) { + throw errors.creditLimitExceeded({ + monthlyCreditLimit: workspace.monthlyCreditLimit, + usedCredits, + reservedCredits, + remainingCredits, + estimatedCredits, + }) + } + + assertJobProviderConfigured(input.type, input.payload) + + const [record] = await tx.insert(generationJobs).values({ + workspaceId: input.workspaceId, + projectId: input.projectId, + episodeId: input.episodeId, + createdById: input.userId, + type: input.type, + idempotencyKey: input.idempotencyKey, + input: input.payload, + maxAttempts: input.maxAttempts ?? 3, + estimatedCredits: estimatedCredits.toString(), + }).returning() + if (!record) throw new Error('Failed to persist generation job') + return { record, deduplicated: false } + }) + if (persisted.deduplicated) return { job: persisted.record, deduplicated: true } + const record = persisted.record + + try { + await generationQueue.add(input.type, { + databaseId: record.id, + workspaceId: input.workspaceId, + userId: input.userId, + type: input.type, + input: input.payload, + ...(input.projectId ? { projectId: input.projectId } : {}), + ...(input.episodeId ? { episodeId: input.episodeId } : {}), + }, { + jobId: record.id, + attempts: input.maxAttempts ?? 3, + ...(input.delayMs && input.delayMs > 0 ? { delay: input.delayMs } : {}), + }) + await publishRealtimeEvent({ + workspaceId: input.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: record.id, + payload: { id: record.id, type: input.type, status: 'QUEUED', progress: 0 }, + }) + } catch (error) { + await db.update(generationJobs).set({ + status: 'FAILED', + errorCode: 'QUEUE_UNAVAILABLE', + errorMessage: error instanceof Error ? error.message : 'Failed to enqueue job', + completedAt: new Date(), + updatedAt: new Date(), + }).where(eq(generationJobs.id, record.id)) + throw error + } + + return { job: record, deduplicated: false } +} + +export async function closeQueue() { + await Promise.all([generationQueue.close(), generationFlowProducer.close()]) + await Promise.all([queueConnection.quit(), flowConnection.quit()]) +} diff --git a/server/src/queue/connection.ts b/server/src/queue/connection.ts new file mode 100644 index 0000000..d12ca08 --- /dev/null +++ b/server/src/queue/connection.ts @@ -0,0 +1,17 @@ +import { Redis } from 'ioredis' +import { config } from '../config.js' + +export function createRedisConnection() { + return new Redis(config.REDIS_URL, { + maxRetriesPerRequest: null, + enableReadyCheck: true, + lazyConnect: false, + }) +} + +export const redis = createRedisConnection() + +export async function checkRedis() { + const response = await redis.ping() + if (response !== 'PONG') throw new Error('Redis ping failed') +} diff --git a/server/src/queue/heartbeat.test.ts b/server/src/queue/heartbeat.test.ts new file mode 100644 index 0000000..811d478 --- /dev/null +++ b/server/src/queue/heartbeat.test.ts @@ -0,0 +1,34 @@ +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { createRedisConnection } from './connection.js' +import { publishWorkerHeartbeat, readWorkerHeartbeat } from './heartbeat.js' + +describe.sequential('worker heartbeat', () => { + const client = createRedisConnection() + const key = `frameflow:test:worker-heartbeat:${crypto.randomUUID()}` + + beforeAll(async () => { + await client.del(key) + }) + + afterAll(async () => { + await client.del(key) + await client.quit() + }) + + it('publishes a TTL-backed heartbeat and reports its age', async () => { + const now = new Date('2026-07-30T12:00:00.000Z') + await publishWorkerHeartbeat({ client, key, instanceId: 'worker-test-1', now, ttlSeconds: 60 }) + const heartbeat = await readWorkerHeartbeat({ client, key, now: new Date(now.getTime() + 4_000), maximumAgeMs: 10_000 }) + expect(heartbeat).toEqual({ instanceId: 'worker-test-1', updatedAt: now.toISOString(), ageMs: 4_000 }) + expect(await client.ttl(key)).toBeGreaterThan(0) + }) + + it('rejects stale or malformed heartbeat values', async () => { + const writtenAt = new Date('2026-07-30T12:00:00.000Z') + await publishWorkerHeartbeat({ client, key, instanceId: 'worker-test-2', now: writtenAt, ttlSeconds: 60 }) + expect(await readWorkerHeartbeat({ client, key, now: new Date(writtenAt.getTime() + 15_000), maximumAgeMs: 10_000 })).toBeNull() + + await client.set(key, 'not-json', 'EX', 60) + expect(await readWorkerHeartbeat({ client, key })).toBeNull() + }) +}) diff --git a/server/src/queue/heartbeat.ts b/server/src/queue/heartbeat.ts new file mode 100644 index 0000000..4270954 --- /dev/null +++ b/server/src/queue/heartbeat.ts @@ -0,0 +1,56 @@ +import type { Redis } from 'ioredis' +import { config } from '../config.js' +import { redis } from './connection.js' + +export interface WorkerHeartbeat { + instanceId: string + updatedAt: string +} + +export async function publishWorkerHeartbeat(input: { + client?: Redis + key?: string + instanceId: string + now?: Date + ttlSeconds?: number +}) { + const client = input.client ?? redis + const now = input.now ?? new Date() + const heartbeat: WorkerHeartbeat = { instanceId: input.instanceId, updatedAt: now.toISOString() } + await client.set( + input.key ?? config.WORKER_HEARTBEAT_KEY, + JSON.stringify(heartbeat), + 'EX', + input.ttlSeconds ?? config.WORKER_HEARTBEAT_TTL_SECONDS, + ) + return heartbeat +} + +export async function readWorkerHeartbeat(input: { + client?: Redis + key?: string + now?: Date + maximumAgeMs?: number +} = {}) { + const client = input.client ?? redis + const value = await client.get(input.key ?? config.WORKER_HEARTBEAT_KEY) + if (!value) return null + let heartbeat: WorkerHeartbeat + try { + heartbeat = JSON.parse(value) as WorkerHeartbeat + } catch { + return null + } + const updatedAtMs = Date.parse(heartbeat.updatedAt) + if (!heartbeat.instanceId || !Number.isFinite(updatedAtMs)) return null + const ageMs = Math.max(0, (input.now ?? new Date()).getTime() - updatedAtMs) + const maximumAgeMs = input.maximumAgeMs ?? config.WORKER_HEARTBEAT_TTL_SECONDS * 1000 + if (ageMs > maximumAgeMs) return null + return { ...heartbeat, ageMs } +} + +export async function checkWorkerHeartbeat() { + const heartbeat = await readWorkerHeartbeat() + if (!heartbeat) throw new Error('Generation worker heartbeat is missing or stale') + return heartbeat +} diff --git a/server/src/queue/processors.ts b/server/src/queue/processors.ts new file mode 100644 index 0000000..8753d59 --- /dev/null +++ b/server/src/queue/processors.ts @@ -0,0 +1,1004 @@ +import { and, asc, desc, eq, inArray, sql } from 'drizzle-orm' +import { z } from 'zod' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { + assets, + assetVersions, + deliveries, + episodes, + generationJobs, + publishingChannelAccounts, + projects, + renders, + scriptVersions, + shots, + shotVersions, +} from '../db/schema.js' +import type { RenderSourceManifest } from '../db/schema.js' +import { errors } from '../lib/errors.js' +import { decryptCredential, encryptCredential } from '../lib/credential-vault.js' +import { downloadRemoteMedia } from '../lib/remote-media.js' +import { + applyCharacterConsistency, + readCharacterConsistencyProfile, + type AppliedCharacterProfile, +} from '../lib/character-consistency.js' +import { buildSubtitleDocument, composeEpisode, episodeRenderSettingsSchema, shotProductionSettingsSchema } from '../media/ffmpeg.js' +import { imageProvider, speechProvider, textProvider, videoProvider } from '../providers/index.js' +import type { BinaryGenerationResult } from '../providers/types.js' +import { createPublishingAdapterRegistry, publishingConnectorCallbackUrl } from '../publishing/connector.js' +import { externalPublishingPlatforms, type PublishingAdapterRegistry } from '../publishing/types.js' +import { publishRealtimeEvent } from '../lib/realtime.js' +import { + generatedObjectKey, + getObjectBuffer, + presignDownload, + putObject, +} from '../storage/client.js' +import type { GenerationJobData, GenerationJobResult } from './types.js' + +const scriptInputSchema = z.object({ + instruction: z.string().trim().min(1).max(20_000).default('根据项目设定和本集梗概生成完整分场剧本'), + provider: z.enum(['openai', 'agnes', 'generic']).default(config.AGNES_API_KEY ? 'agnes' : 'openai'), + includeExistingScript: z.boolean().default(true), +}) + +const storyboardInputSchema = z.object({ + instruction: z.string().trim().min(1).max(20_000).default('根据当前剧本生成完整、可制作的漫剧分镜'), + provider: z.enum(['openai', 'agnes', 'generic']).default(config.AGNES_API_KEY ? 'agnes' : 'openai'), + replaceExisting: z.boolean().default(false), +}) + +const assetInputSchema = z.object({ + assetId: z.uuid().optional(), + shotId: z.uuid().optional(), + prompt: z.string().trim().min(1).max(32_000), + negativePrompt: z.string().max(10_000).default(''), + width: z.number().int().min(256).max(4096).default(1024), + height: z.number().int().min(256).max(4096).default(1024), + referenceAssetVersionIds: z.array(z.uuid()).max(16).default([]), + provider: z.enum(['openai', 'replicate', 'agnes', 'generic']).default(config.AGNES_API_KEY ? 'agnes' : 'openai'), + params: z.record(z.string(), z.unknown()).default({}), +}).refine((input) => Boolean(input.assetId) !== Boolean(input.shotId), { + message: 'Exactly one of assetId or shotId is required', +}) + +const speechInputSchema = z.object({ + shotId: z.uuid(), + text: z.string().trim().min(1).max(4096), + voice: z.string().trim().min(1).max(80).optional(), + instructions: z.string().max(2000).optional(), + speed: z.number().min(0.25).max(4).optional(), + provider: z.enum(['openai']).default('openai'), +}) + +const videoInputSchema = z.object({ + shotId: z.uuid(), + prompt: z.string().trim().min(1).max(20_000), + imageAssetVersionId: z.uuid().optional(), + durationSeconds: z.number().min(1).max(30).optional(), + provider: z.enum(['replicate', 'agnes', 'generic']).default(config.AGNES_API_KEY ? 'agnes' : 'replicate'), + params: z.record(z.string(), z.unknown()).default({}), +}) + +const lipsyncInputSchema = z.object({ + shotId: z.uuid(), + videoStorageKey: z.string().min(1).max(1000).optional(), + audioStorageKey: z.string().min(1).max(1000).optional(), + provider: z.enum(['replicate']).default('replicate'), + params: z.record(z.string(), z.unknown()).default({}), +}) + +const renderInputSchema = z.object({ + renderId: z.uuid(), + prerequisiteJobIds: z.array(z.uuid()).max(2000).default([]), +}) +const deliveryInputSchema = z.object({ deliveryId: z.uuid() }) + +export class JobCancelledError extends Error { + constructor() { + super('Generation job was cancelled') + this.name = 'JobCancelledError' + } +} + +function parseInput(schema: z.ZodType, input: Record): T { + const parsed = schema.safeParse(input) + if (!parsed.success) throw errors.badRequest('Invalid generation job input', parsed.error.issues) + return parsed.data +} + +function requireScopeId(value: string | undefined, name: 'projectId' | 'episodeId') { + if (!value) throw errors.badRequest(`${name} is required for this job type`) + return value +} + +async function ensureNotCancelled(data: GenerationJobData) { + const [record] = await db.select({ status: generationJobs.status }).from(generationJobs) + .where(eq(generationJobs.id, data.databaseId)).limit(1) + if (!record || record.status === 'CANCELLED') throw new JobCancelledError() +} + +function assertScope(data: GenerationJobData, row: { workspaceId: string; projectId: string; episodeId?: string }) { + if (row.workspaceId !== data.workspaceId) throw errors.forbidden('Job workspace does not own this resource') + if (data.projectId && row.projectId !== data.projectId) throw errors.badRequest('Job project does not match the target resource') + if (data.episodeId && row.episodeId && row.episodeId !== data.episodeId) throw errors.badRequest('Job episode does not match the target resource') +} + +async function episodeContext(episodeId: string) { + const [row] = await db.select({ episode: episodes, project: projects }).from(episodes) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(episodes.id, episodeId)).limit(1) + if (!row) throw errors.notFound('Episode') + return row +} + +async function assetContext(assetId: string) { + const [row] = await db.select({ asset: assets, project: projects }).from(assets) + .innerJoin(projects, eq(projects.id, assets.projectId)) + .where(eq(assets.id, assetId)).limit(1) + if (!row) throw errors.notFound('Asset') + return row +} + +async function shotContext(shotId: string) { + const [row] = await db.select({ shot: shots, episode: episodes, project: projects }).from(shots) + .innerJoin(episodes, eq(episodes.id, shots.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(shots.id, shotId)).limit(1) + if (!row) throw errors.notFound('Shot') + return row +} + +function extensionForMimeType(mimeType: string) { + const extensions: Record = { + 'image/png': 'png', + 'image/jpeg': 'jpg', + 'image/webp': 'webp', + 'audio/mpeg': 'mp3', + 'audio/wav': 'wav', + 'audio/flac': 'flac', + 'video/mp4': 'mp4', + 'video/webm': 'webm', + } + const extension = extensions[mimeType] + if (!extension) throw errors.badRequest(`Unsupported generated media type: ${mimeType}`) + return extension +} + +async function materializeBinary(result: BinaryGenerationResult) { + const body = result.data + ? result.data + : result.url + ? await downloadRemoteMedia(result.url, { + maxBytes: config.MAX_UPLOAD_BYTES, + timeoutMs: config.PROVIDER_DOWNLOAD_TIMEOUT_MS, + maxRedirects: config.PROVIDER_DOWNLOAD_MAX_REDIRECTS, + }) + : null + if (!body) throw new Error('Provider returned neither binary data nor an output URL') + if (body.length > config.MAX_UPLOAD_BYTES) throw errors.badRequest('Generated media exceeds the configured storage limit') + if (result.mimeType === 'video/mp4' && (body.length < 12 || body.subarray(4, 8).toString('ascii') !== 'ftyp')) { + throw errors.badRequest('Provider returned invalid MP4 video content') + } + return body +} + +async function storeGeneratedMedia(input: { + data: GenerationJobData + result: BinaryGenerationResult + category: string +}) { + const projectId = requireScopeId(input.data.projectId, 'projectId') + const body = await materializeBinary(input.result) + const key = generatedObjectKey(input.data.workspaceId, projectId, input.category, extensionForMimeType(input.result.mimeType)) + await putObject({ + key, + body, + contentType: input.result.mimeType, + metadata: { projectId, jobId: input.data.databaseId, provider: input.result.model }, + }) + return { key, byteSize: body.length } +} + +async function createShotMediaVersion(input: { + data: GenerationJobData + shotId: string + generationParams: Record + imageAssetVersionId?: string | null + videoStorageKey?: string | null + audioStorageKey?: string | null + subtitleText?: string +}) { + return db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`shot:${input.shotId}`}))`) + const [latest] = await tx.select().from(shotVersions).where(eq(shotVersions.shotId, input.shotId)) + .orderBy(desc(shotVersions.version)).limit(1) + const [current] = await tx.select().from(shotVersions).where(and( + eq(shotVersions.shotId, input.shotId), + eq(shotVersions.isCurrent, true), + )).limit(1) + const base = current ?? latest + await tx.update(shotVersions).set({ isCurrent: false }).where(eq(shotVersions.shotId, input.shotId)) + const [created] = await tx.insert(shotVersions).values({ + shotId: input.shotId, + version: (latest?.version ?? 0) + 1, + imageAssetVersionId: input.imageAssetVersionId !== undefined ? input.imageAssetVersionId : base?.imageAssetVersionId, + videoStorageKey: input.videoStorageKey !== undefined ? input.videoStorageKey : base?.videoStorageKey, + audioStorageKey: input.audioStorageKey !== undefined ? input.audioStorageKey : base?.audioStorageKey, + subtitleText: input.subtitleText ?? base?.subtitleText ?? '', + generationParams: { ...(base?.generationParams ?? {}), ...input.generationParams, jobId: input.data.databaseId }, + isCurrent: true, + createdById: input.data.userId, + }).returning() + if (!created) throw new Error('Failed to persist generated shot version') + await tx.update(shots).set({ status: 'REVIEW', updatedAt: new Date() }).where(eq(shots.id, input.shotId)) + return created + }) +} + +async function processScript(data: GenerationJobData): Promise { + const episodeId = requireScopeId(data.episodeId, 'episodeId') + const input = parseInput(scriptInputSchema, data.input) + const row = await episodeContext(episodeId) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId }) + const [current] = input.includeExistingScript + ? await db.select().from(scriptVersions).where(and(eq(scriptVersions.episodeId, episodeId), eq(scriptVersions.isCurrent, true))).limit(1) + : [] + const provider = textProvider(input.provider) + const result = await provider.generateScript({ + instruction: input.instruction, + projectName: row.project.name, + genre: row.project.genre, + visualBible: row.project.visualBible, + episodeTitle: row.episode.title, + synopsis: row.episode.synopsis, + targetDurationSeconds: row.episode.targetDurationSeconds, + safetyIdentifier: data.userId, + ...(current?.plainText ? { existingScript: current.plainText } : {}), + }) + await ensureNotCancelled(data) + + const version = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`script:${episodeId}`}))`) + const [latest] = await tx.select({ version: scriptVersions.version }).from(scriptVersions) + .where(eq(scriptVersions.episodeId, episodeId)).orderBy(desc(scriptVersions.version)).limit(1) + await tx.update(scriptVersions).set({ isCurrent: false }).where(eq(scriptVersions.episodeId, episodeId)) + const [created] = await tx.insert(scriptVersions).values({ + episodeId, + version: (latest?.version ?? 0) + 1, + title: result.document.title, + content: result.document as unknown as Record, + plainText: result.plainText, + changeSummary: current ? 'AI 改写生成' : 'AI 初稿生成', + isCurrent: true, + createdById: data.userId, + }).returning() + if (!created) throw new Error('Failed to persist generated script') + await tx.update(episodes).set({ status: 'SCRIPTING', updatedAt: new Date() }).where(eq(episodes.id, episodeId)) + return created + }) + + return { + provider: provider.name, + providerModel: result.model, + output: { episodeId, scriptVersionId: version.id, version: version.version, title: version.title }, + usage: result.usage, + } +} + +function matchAssetId(name: string | null, candidates: Array<{ id: string; name: string }>) { + if (!name) return null + const normalized = name.trim().toLocaleLowerCase('zh-CN') + return candidates.find((candidate) => { + const candidateName = candidate.name.trim().toLocaleLowerCase('zh-CN') + return candidateName === normalized || candidateName.includes(normalized) || normalized.includes(candidateName) + })?.id ?? null +} + +async function processStoryboard(data: GenerationJobData): Promise { + const episodeId = requireScopeId(data.episodeId, 'episodeId') + const input = parseInput(storyboardInputSchema, data.input) + const row = await episodeContext(episodeId) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId }) + + const [currentScript] = await db.select().from(scriptVersions) + .where(and(eq(scriptVersions.episodeId, episodeId), eq(scriptVersions.isCurrent, true))).limit(1) + if (!currentScript?.plainText) throw errors.badRequest('A saved script is required before generating a storyboard') + + const existingShots = await db.select({ id: shots.id, status: shots.status }).from(shots) + .where(eq(shots.episodeId, episodeId)) + if (existingShots.length > 0 && !input.replaceExisting) { + throw errors.conflict('This episode already has shots; confirm replacement to regenerate the storyboard') + } + if (input.replaceExisting && existingShots.some((shot) => shot.status !== 'DRAFT')) { + throw errors.conflict('Only a draft-only storyboard can be replaced; archive produced shots manually first') + } + + const projectAssets = await db.select({ id: assets.id, name: assets.name, type: assets.type }).from(assets) + .where(eq(assets.projectId, row.project.id)) + const characterAssets = projectAssets.filter((asset) => asset.type === 'CHARACTER') + const sceneAssets = projectAssets.filter((asset) => asset.type === 'SCENE') + const provider = textProvider(input.provider) + const result = await provider.generateStoryboard({ + projectName: row.project.name, + genre: row.project.genre, + visualBible: row.project.visualBible, + episodeTitle: row.episode.title, + targetDurationSeconds: row.episode.targetDurationSeconds, + script: currentScript.plainText, + instruction: input.instruction, + characterNames: characterAssets.map((asset) => asset.name), + sceneNames: sceneAssets.map((asset) => asset.name), + safetyIdentifier: data.userId, + }) + await ensureNotCancelled(data) + + const storyboardShots = z.array(z.object({ + sceneNumber: z.number().int().min(1), + title: z.string().trim().min(1).max(180), + description: z.string().trim().min(1).max(10_000), + shotType: z.string().trim().min(1).max(50), + cameraMotion: z.string().trim().min(1).max(50), + durationMs: z.number().int().min(500).max(30_000), + characterNames: z.array(z.string().trim().min(1)).max(20), + sceneName: z.string().trim().min(1).nullable(), + subtitleText: z.string().max(10_000), + })).min(1).max(300).parse(result.shots) + + const created = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`storyboard:${episodeId}`}))`) + if (input.replaceExisting && existingShots.length > 0) { + await tx.delete(shots).where(eq(shots.episodeId, episodeId)) + } + const createdShots = await tx.insert(shots).values(storyboardShots.map((shot, index) => ({ + episodeId, + shotNumber: index + 1, + sceneNumber: shot.sceneNumber, + title: shot.title, + description: shot.description, + shotType: shot.shotType, + cameraMotion: shot.cameraMotion, + durationMs: shot.durationMs, + characterAssetIds: [...new Set(shot.characterNames.map((name) => matchAssetId(name, characterAssets)).filter((id): id is string => Boolean(id)))], + sceneAssetId: matchAssetId(shot.sceneName, sceneAssets), + sortOrder: (index + 1) * 100, + status: 'DRAFT' as const, + createdById: data.userId, + }))).returning() + const versionRows = createdShots.map((shot, index) => ({ + shotId: shot.id, + version: 1, + subtitleText: storyboardShots[index]?.subtitleText ?? '', + generationParams: { operation: 'storyboard', scriptVersionId: currentScript.id, jobId: data.databaseId }, + isCurrent: true, + createdById: data.userId, + })) + if (versionRows.length > 0) await tx.insert(shotVersions).values(versionRows) + await tx.update(episodes).set({ status: 'STORYBOARDING', updatedAt: new Date() }).where(eq(episodes.id, episodeId)) + return createdShots + }) + + return { + provider: provider.name, + providerModel: result.model, + output: { episodeId, scriptVersionId: currentScript.id, shotCount: created.length, shotIds: created.map((shot) => shot.id) }, + usage: result.usage, + } +} + +async function processAsset(data: GenerationJobData): Promise { + const projectId = requireScopeId(data.projectId, 'projectId') + const input = parseInput(assetInputSchema, data.input) + let targetAsset: typeof assets.$inferSelect + let targetShot: typeof shots.$inferSelect | undefined + if (input.assetId) { + const row = await assetContext(input.assetId) + targetAsset = row.asset + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id }) + } else { + const row = await shotContext(input.shotId!) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + targetShot = row.shot + const [created] = await db.insert(assets).values({ + projectId: row.project.id, + type: 'SHOT', + name: `镜头 ${String(row.shot.shotNumber).padStart(2, '0')} · ${row.shot.title}`, + description: input.prompt, + status: 'GENERATING', + tags: ['镜头画面'], + metadata: { shotId: row.shot.id }, + createdById: data.userId, + }).returning() + if (!created) throw new Error('Failed to create shot image asset') + targetAsset = created + } + try { + await db.update(assets).set({ status: 'GENERATING', updatedAt: new Date() }).where(eq(assets.id, targetAsset.id)) + + const appliedProfiles: AppliedCharacterProfile[] = [] + let otherAutomaticReferenceIds: string[] = [] + if (targetAsset.type === 'CHARACTER') { + const profile = readCharacterConsistencyProfile(targetAsset.metadata) + if (profile?.identityLocked) appliedProfiles.push({ ...profile, assetId: targetAsset.id, assetName: targetAsset.name }) + } + if (targetShot) { + const referenceAssetIds = [...targetShot.characterAssetIds, ...(targetShot.sceneAssetId ? [targetShot.sceneAssetId] : [])] + if (referenceAssetIds.length > 0) { + const referenceAssets = await db.select({ + id: assets.id, + name: assets.name, + type: assets.type, + metadata: assets.metadata, + }).from(assets).where(and(eq(assets.projectId, projectId), inArray(assets.id, referenceAssetIds))) + const currentAssetIds: string[] = [] + for (const referenceAsset of referenceAssets) { + const profile = referenceAsset.type === 'CHARACTER' + ? readCharacterConsistencyProfile(referenceAsset.metadata) + : null + if (profile?.identityLocked) { + appliedProfiles.push({ ...profile, assetId: referenceAsset.id, assetName: referenceAsset.name }) + } else { + currentAssetIds.push(referenceAsset.id) + } + } + if (currentAssetIds.length > 0) { + const currentReferences = await db.select({ id: assetVersions.id }).from(assetVersions) + .where(and(inArray(assetVersions.assetId, currentAssetIds), eq(assetVersions.isCurrent, true))) + otherAutomaticReferenceIds = currentReferences.map((reference) => reference.id) + } + } + } + const consistency = applyCharacterConsistency({ + prompt: input.prompt, + negativePrompt: input.negativePrompt, + params: input.params, + manualReferenceAssetVersionIds: input.referenceAssetVersionIds, + profiles: appliedProfiles, + otherAutomaticReferenceAssetVersionIds: otherAutomaticReferenceIds, + }) + const referenceRows = consistency.referenceAssetVersionIds.length > 0 + ? await db.select({ + id: assetVersions.id, + storageKey: assetVersions.storageKey, + mimeType: assetVersions.mimeType, + assetName: assets.name, + }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .where(and(inArray(assetVersions.id, consistency.referenceAssetVersionIds), eq(assets.projectId, projectId))) + : [] + if (referenceRows.length !== consistency.referenceAssetVersionIds.length || referenceRows.some((reference) => !reference.storageKey || !reference.mimeType?.startsWith('image/'))) { + throw errors.badRequest('Every reference must be a stored image asset version from the same project') + } + const referenceById = new Map(referenceRows.map((reference) => [reference.id, reference])) + const orderedReferenceRows = consistency.referenceAssetVersionIds.map((id) => referenceById.get(id)!) + const references = await Promise.all(orderedReferenceRows.map(async (reference) => ({ + name: `${reference.assetName}-${reference.id}`, + mimeType: reference.mimeType!, + data: await getObjectBuffer(reference.storageKey!), + }))) + const referenceUrls = await Promise.all(orderedReferenceRows.map((reference) => presignDownload(reference.storageKey!, 3600))) + + const provider = imageProvider(input.provider) + const result = await provider.generateImage({ + prompt: consistency.prompt, + negativePrompt: consistency.negativePrompt, + width: input.width, + height: input.height, + references, + referenceUrls, + params: consistency.params, + safetyIdentifier: data.userId, + }) + await ensureNotCancelled(data) + const stored = await storeGeneratedMedia({ data, result, category: `assets/${targetAsset.type.toLowerCase()}` }) + + const version = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`asset:${targetAsset.id}`}))`) + const [latest] = await tx.select({ version: assetVersions.version }).from(assetVersions) + .where(eq(assetVersions.assetId, targetAsset.id)).orderBy(desc(assetVersions.version)).limit(1) + await tx.update(assetVersions).set({ isCurrent: false }).where(eq(assetVersions.assetId, targetAsset.id)) + const [created] = await tx.insert(assetVersions).values({ + assetId: targetAsset.id, + version: (latest?.version ?? 0) + 1, + storageKey: stored.key, + mimeType: result.mimeType, + byteSize: stored.byteSize, + width: result.width ?? input.width, + height: result.height ?? input.height, + prompt: consistency.prompt, + negativePrompt: consistency.negativePrompt, + provider: provider.name, + providerModel: result.model, + seed: result.seed, + generationParams: { + ...consistency.params, + referenceAssetVersionIds: consistency.referenceAssetVersionIds, + appliedCharacterConsistencyProfiles: consistency.profileSnapshots, + requestedPrompt: input.prompt, + requestedNegativePrompt: input.negativePrompt, + externalId: result.externalId, + ...(result.sourceUrl ? { providerSourceUrl: result.sourceUrl } : {}), + jobId: data.databaseId, + }, + isCurrent: true, + createdById: data.userId, + }).returning() + if (!created) throw new Error('Failed to persist generated asset version') + await tx.update(assets).set({ status: 'REVIEW', updatedAt: new Date() }).where(eq(assets.id, targetAsset.id)) + return created + }) + if (targetShot) { + await createShotMediaVersion({ + data, + shotId: targetShot.id, + imageAssetVersionId: version.id, + generationParams: { + operation: 'storyboard-image', + assetId: targetAsset.id, + sourceAssetVersionId: version.id, + provider: provider.name, + model: result.model, + appliedCharacterConsistencyProfiles: consistency.profileSnapshots, + }, + }) + } + + return { + provider: provider.name, + providerModel: result.model, + output: { + assetId: targetAsset.id, + assetVersionId: version.id, + version: version.version, + storageKey: stored.key, + ...(targetShot ? { shotId: targetShot.id } : {}), + }, + usage: result.usage, + } + } catch (error) { + await db.update(assets).set({ status: 'DRAFT', updatedAt: new Date() }).where(eq(assets.id, targetAsset.id)) + throw error + } +} + +async function processSpeech(data: GenerationJobData): Promise { + const input = parseInput(speechInputSchema, data.input) + const row = await shotContext(input.shotId) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + const provider = speechProvider(input.provider) + const result = await provider.generateSpeech({ + text: input.text, + safetyIdentifier: data.userId, + ...(input.voice ? { voice: input.voice } : {}), + ...(input.instructions ? { instructions: input.instructions } : {}), + ...(input.speed !== undefined ? { speed: input.speed } : {}), + }) + await ensureNotCancelled(data) + const stored = await storeGeneratedMedia({ data, result, category: 'shots/audio' }) + const version = await createShotMediaVersion({ + data, + shotId: row.shot.id, + audioStorageKey: stored.key, + subtitleText: input.text, + generationParams: { operation: 'tts', voice: input.voice, speed: input.speed, provider: provider.name, model: result.model }, + }) + return { + provider: provider.name, + providerModel: result.model, + output: { shotId: row.shot.id, shotVersionId: version.id, version: version.version, audioStorageKey: stored.key }, + usage: result.usage, + } +} + +async function processVideo(data: GenerationJobData): Promise { + const input = parseInput(videoInputSchema, data.input) + const row = await shotContext(input.shotId) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + const [currentShotVersion] = await db.select().from(shotVersions) + .where(and(eq(shotVersions.shotId, row.shot.id), eq(shotVersions.isCurrent, true))).limit(1) + const imageAssetVersionId = input.imageAssetVersionId ?? currentShotVersion?.imageAssetVersionId + if (!imageAssetVersionId) throw errors.badRequest('A source image asset version is required for video generation') + const [sourceImage] = await db.select({ + storageKey: assetVersions.storageKey, + mimeType: assetVersions.mimeType, + width: assetVersions.width, + height: assetVersions.height, + generationParams: assetVersions.generationParams, + }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .where(and(eq(assetVersions.id, imageAssetVersionId), eq(assets.projectId, row.project.id))).limit(1) + if (!sourceImage?.storageKey) throw errors.badRequest('The source image must be stored in this project') + + const durationSeconds = input.durationSeconds ?? row.shot.durationMs / 1000 + const provider = videoProvider(input.provider) + const providerSourceUrl = typeof sourceImage.generationParams?.providerSourceUrl === 'string' + ? sourceImage.generationParams.providerSourceUrl + : null + const result = await provider.generateVideo({ + prompt: input.prompt, + imageUrl: providerSourceUrl ?? await presignDownload(sourceImage.storageKey, 3600), + imageData: await getObjectBuffer(sourceImage.storageKey), + imageMimeType: sourceImage.mimeType ?? 'image/png', + ...(sourceImage.width ? { sourceWidth: sourceImage.width } : {}), + ...(sourceImage.height ? { sourceHeight: sourceImage.height } : {}), + durationSeconds, + params: input.params, + }) + await ensureNotCancelled(data) + const stored = await storeGeneratedMedia({ data, result, category: 'shots/video' }) + const version = await createShotMediaVersion({ + data, + shotId: row.shot.id, + imageAssetVersionId, + videoStorageKey: stored.key, + generationParams: { operation: 'video', prompt: input.prompt, durationSeconds, provider: provider.name, model: result.model, externalId: result.externalId }, + }) + return { + provider: provider.name, + providerModel: result.model, + output: { shotId: row.shot.id, shotVersionId: version.id, version: version.version, videoStorageKey: stored.key }, + usage: result.usage, + } +} + +async function processLipsync(data: GenerationJobData): Promise { + const input = parseInput(lipsyncInputSchema, data.input) + const row = await shotContext(input.shotId) + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + const [current] = await db.select().from(shotVersions) + .where(and(eq(shotVersions.shotId, row.shot.id), eq(shotVersions.isCurrent, true))).limit(1) + const videoStorageKey = input.videoStorageKey ?? current?.videoStorageKey + const audioStorageKey = input.audioStorageKey ?? current?.audioStorageKey + if (!videoStorageKey || !audioStorageKey) throw errors.badRequest('Stored video and audio are required for lip-sync generation') + const projectPrefix = `${data.workspaceId}/${row.project.id}/` + if (!videoStorageKey.startsWith(projectPrefix) || !audioStorageKey.startsWith(projectPrefix)) { + throw errors.forbidden('Lip-sync media must belong to the job project') + } + + const provider = videoProvider(input.provider) + const result = await provider.generateLipsync({ + videoUrl: await presignDownload(videoStorageKey, 3600), + audioUrl: await presignDownload(audioStorageKey, 3600), + params: input.params, + }) + await ensureNotCancelled(data) + const stored = await storeGeneratedMedia({ data, result, category: 'shots/lipsync' }) + const version = await createShotMediaVersion({ + data, + shotId: row.shot.id, + videoStorageKey: stored.key, + audioStorageKey, + generationParams: { operation: 'lipsync', provider: provider.name, model: result.model, externalId: result.externalId }, + }) + return { + provider: provider.name, + providerModel: result.model, + output: { shotId: row.shot.id, shotVersionId: version.id, version: version.version, videoStorageKey: stored.key }, + usage: result.usage, + } +} + +async function processRender(data: GenerationJobData): Promise { + const input = parseInput(renderInputSchema, data.input) + const [row] = await db.select({ render: renders, episode: episodes, project: projects }).from(renders) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(renders.id, input.renderId)).limit(1) + if (!row) throw errors.notFound('Render') + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + const settings = parseInput(episodeRenderSettingsSchema, row.render.settings) + const projectPrefix = `${data.workspaceId}/${row.project.id}/` + + await db.update(renders).set({ status: 'RENDERING', updatedAt: new Date(), qualityReport: null }) + .where(eq(renders.id, row.render.id)) + + try { + if (input.prerequisiteJobIds.length > 0) { + const prerequisites = await db.select({ + id: generationJobs.id, + type: generationJobs.type, + status: generationJobs.status, + errorMessage: generationJobs.errorMessage, + }).from(generationJobs).where(inArray(generationJobs.id, input.prerequisiteJobIds)) + const failed = prerequisites.filter((job) => job.status !== 'SUCCEEDED') + if (prerequisites.length !== input.prerequisiteJobIds.length || failed.length > 0) { + const failedSummary = failed.slice(0, 5).map((job) => `${job.type}: ${job.errorMessage ?? job.status}`).join('; ') + throw errors.conflict(`Production prerequisites failed${failedSummary ? `: ${failedSummary}` : ''}`) + } + } + + const shotRows = await db.select({ shot: shots, version: shotVersions, image: assetVersions }).from(shots) + .leftJoin(shotVersions, and(eq(shotVersions.shotId, shots.id), eq(shotVersions.isCurrent, true))) + .leftJoin(assetVersions, eq(assetVersions.id, shotVersions.imageAssetVersionId)) + .where(eq(shots.episodeId, row.episode.id)).orderBy(asc(shots.sortOrder)) + if (shotRows.length === 0) throw errors.badRequest('The episode has no shots to render') + + const clips = await Promise.all(shotRows.map(async ({ shot, version, image }, index) => { + if (!version) throw errors.badRequest(`Shot ${shot.shotNumber} has no current media version`) + const visualKey = version.videoStorageKey ?? image?.storageKey + if (!visualKey) throw errors.badRequest(`Shot ${shot.shotNumber} has no video or image source`) + if (!visualKey.startsWith(projectPrefix) || (version.audioStorageKey && !version.audioStorageKey.startsWith(projectPrefix))) { + throw errors.forbidden(`Shot ${shot.shotNumber} references media outside this project`) + } + const visual = await getObjectBuffer(visualKey) + const audio = version.audioStorageKey ? await getObjectBuffer(version.audioStorageKey) : undefined + const production = shotProductionSettingsSchema.parse(version.generationParams?.production ?? {}) + return { + durationMs: shot.durationMs, + subtitleText: version.subtitleText, + production, + ...(version.videoStorageKey + ? { video: { data: visual, extension: 'mp4' } } + : { image: { data: visual, extension: extensionForMimeType(image?.mimeType ?? 'image/png') } }), + ...(audio ? { audio: { data: audio, extension: 'mp3' } } : {}), + sortOrder: index, + } + })) + const sourceManifest = { + schemaVersion: 1, + capturedAt: new Date().toISOString(), + shots: shotRows.map(({ shot, version }) => { + if (!version) throw errors.badRequest(`Shot ${shot.shotNumber} has no current media version`) + return { + shotId: shot.id, + shotVersionId: version.id, + shotNumber: shot.shotNumber, + shotVersion: version.version, + sortOrder: shot.sortOrder, + durationMs: shot.durationMs, + subtitleText: version.subtitleText, + imageAssetVersionId: version.imageAssetVersionId, + } + }), + } satisfies RenderSourceManifest + + let backgroundMusic: { data: Buffer; extension: string } | undefined + if (settings.backgroundMusicStorageKey) { + if (!settings.backgroundMusicStorageKey.startsWith(projectPrefix)) throw errors.forbidden('Background music must belong to the job project') + backgroundMusic = { data: await getObjectBuffer(settings.backgroundMusicStorageKey), extension: 'mp3' } + } + + const composition = await composeEpisode({ + clips, + settings, + ...(backgroundMusic ? { backgroundMusic } : {}), + }) + await ensureNotCancelled(data) + const storageKey = generatedObjectKey(data.workspaceId, row.project.id, 'renders', 'mp4') + await putObject({ + key: storageKey, + body: composition.data, + contentType: 'video/mp4', + metadata: { projectId: row.project.id, episodeId: row.episode.id, renderId: row.render.id, jobId: data.databaseId }, + }) + const subtitleSrt = buildSubtitleDocument(clips, 'srt') + const subtitleVtt = buildSubtitleDocument(clips, 'vtt') + const subtitleSrtKey = subtitleSrt ? generatedObjectKey(data.workspaceId, row.project.id, 'renders-subtitles', 'srt') : null + const subtitleVttKey = subtitleVtt ? generatedObjectKey(data.workspaceId, row.project.id, 'renders-subtitles', 'vtt') : null + await Promise.all([ + ...(subtitleSrtKey ? [putObject({ + key: subtitleSrtKey, + body: subtitleSrt, + contentType: 'application/x-subrip; charset=utf-8', + metadata: { projectId: row.project.id, episodeId: row.episode.id, renderId: row.render.id, jobId: data.databaseId, format: 'srt' }, + })] : []), + ...(subtitleVttKey ? [putObject({ + key: subtitleVttKey, + body: subtitleVtt, + contentType: 'text/vtt; charset=utf-8', + metadata: { projectId: row.project.id, episodeId: row.episode.id, renderId: row.render.id, jobId: data.databaseId, format: 'vtt' }, + })] : []), + ]) + const subtitleFormats = [ + ...(subtitleSrtKey ? ['srt' as const] : []), + ...(subtitleVttKey ? ['vtt' as const] : []), + ] + const qualityReport = { + shotCount: shotRows.length, + missingAudioShotCount: shotRows.filter(({ version }) => !version?.audioStorageKey).length, + subtitlesBurned: composition.subtitlesMode === 'burned', + subtitlesMode: composition.subtitlesMode, + subtitleFormats, + backgroundMusicMixed: Boolean(backgroundMusic), + audioNormalized: settings.normalizeAudio, + editedShotCount: clips.filter((clip) => { + const production = clip.production! + return production.trimStartMs > 0 + || production.playbackRate !== 1 + || production.audioVolume !== 1 + || production.fit !== 'contain' + || production.transition !== 'cut' + }).length, + codec: 'h264/aac', + } + await db.transaction(async (tx) => { + await tx.update(renders).set({ + status: 'REVIEW', + storageKey, + mimeType: 'video/mp4', + byteSize: composition.data.length, + durationMs: composition.durationMs, + subtitleSrtKey, + subtitleVttKey, + sourceManifest, + qualityReport, + updatedAt: new Date(), + }).where(eq(renders.id, row.render.id)) + await tx.update(shots).set({ status: 'RENDERED', updatedAt: new Date() }) + .where(inArray(shots.id, shotRows.map(({ shot }) => shot.id))) + await tx.update(episodes).set({ status: 'REVIEW', updatedAt: new Date() }).where(eq(episodes.id, row.episode.id)) + }) + return { + provider: 'local', + providerModel: 'ffmpeg-h264-aac-v1', + output: { renderId: row.render.id, storageKey, durationMs: composition.durationMs, subtitleFormats, sourceShotCount: sourceManifest.shots.length, qualityReport }, + usage: [{ kind: 'RENDER_SECOND', quantity: composition.durationMs / 1000, credits: composition.durationMs / 1000 * 0.8 }], + } + } catch (error) { + await db.update(renders).set({ + status: 'FAILED', + qualityReport: { error: error instanceof Error ? error.message : 'Render failed' }, + updatedAt: new Date(), + }).where(eq(renders.id, row.render.id)) + throw error + } +} + +async function processDelivery(data: GenerationJobData, publishingAdapters: PublishingAdapterRegistry): Promise { + const input = parseInput(deliveryInputSchema, data.input) + const [row] = await db.select({ delivery: deliveries, render: renders, episode: episodes, project: projects, channelAccount: publishingChannelAccounts }).from(deliveries) + .innerJoin(renders, eq(renders.id, deliveries.renderId)) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .leftJoin(publishingChannelAccounts, eq(publishingChannelAccounts.id, deliveries.channelAccountId)) + .where(eq(deliveries.id, input.deliveryId)).limit(1) + if (!row) throw errors.notFound('Delivery') + assertScope(data, { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episode.id }) + if (row.render.status !== 'APPROVED' || !row.render.storageKey) throw errors.conflict('Only an approved stored render can be published') + + await db.update(deliveries).set({ status: 'PUBLISHING', errorMessage: null, updatedAt: new Date() }) + .where(eq(deliveries.id, row.delivery.id)) + try { + if (row.delivery.platform === 'DOWNLOAD') { + await ensureNotCancelled(data) + const publishedUrl = `/api/v1/deliveries/${row.delivery.id}/download` + await db.transaction(async (tx) => { + await tx.update(deliveries).set({ + status: 'PUBLISHED', + publishedUrl, + publishedAt: new Date(), + updatedAt: new Date(), + }).where(eq(deliveries.id, row.delivery.id)) + await tx.update(episodes).set({ status: 'PUBLISHED', updatedAt: new Date() }).where(eq(episodes.id, row.episode.id)) + }) + await publishRealtimeEvent({ + workspaceId: row.project.workspaceId, + type: 'delivery.updated', + resourceType: 'delivery', + resourceId: row.delivery.id, + payload: { id: row.delivery.id, platform: 'DOWNLOAD', status: 'PUBLISHED', publishedUrl }, + }) + return { + provider: 'local', + providerModel: 'download-delivery-v1', + output: { deliveryId: row.delivery.id, status: 'PUBLISHED', publishedUrl, renderId: row.render.id }, + } + } + + if (!externalPublishingPlatforms.includes(row.delivery.platform as (typeof externalPublishingPlatforms)[number])) { + throw errors.badRequest(`Publishing platform ${row.delivery.platform} is unsupported`) + } + const platform = row.delivery.platform as (typeof externalPublishingPlatforms)[number] + const adapter = publishingAdapters.get(platform) + const readiness = adapter?.readiness() + if (!adapter || !readiness || readiness.status !== 'CONFIGURED') { + throw errors.serviceUnavailable(`${platform} publishing adapter is not configured`, { + platform, + missingRequirements: readiness?.missingRequirements ?? ['PUBLISHING_ADAPTER'], + }) + } + if (!row.channelAccount || row.channelAccount.workspaceId !== row.project.workspaceId || row.channelAccount.platform !== platform) { + throw errors.conflict('Delivery channel account is invalid') + } + if (row.channelAccount.status !== 'CONNECTED' || !row.channelAccount.accessTokenCiphertext) { + throw errors.conflict('Publishing channel account is not connected') + } + const channelAccount = row.channelAccount + + await ensureNotCancelled(data) + const result = await adapter.publish({ + deliveryId: row.delivery.id, + sourceUrl: await presignDownload(row.render.storageKey, 30 * 60), + callbackUrl: publishingConnectorCallbackUrl(), + account: { + externalAccountId: channelAccount.externalAccountId, + accessToken: decryptCredential(channelAccount.accessTokenCiphertext!), + ...(channelAccount.refreshTokenCiphertext ? { refreshToken: decryptCredential(channelAccount.refreshTokenCiphertext) } : {}), + }, + destination: row.delivery.destination, + }) + await ensureNotCancelled(data) + const completedAt = new Date() + await db.transaction(async (tx) => { + await tx.update(deliveries).set({ + status: result.status, + externalId: result.externalId, + publishedUrl: result.publishedUrl ?? null, + publishedAt: result.status === 'PUBLISHED' ? completedAt : null, + errorMessage: null, + updatedAt: completedAt, + }).where(and(eq(deliveries.id, row.delivery.id), eq(deliveries.status, 'PUBLISHING'))) + if (result.credentials) { + await tx.update(publishingChannelAccounts).set({ + accessTokenCiphertext: encryptCredential(result.credentials.accessToken), + ...(result.credentials.refreshToken ? { refreshTokenCiphertext: encryptCredential(result.credentials.refreshToken) } : {}), + ...(result.credentials.tokenExpiresAt ? { tokenExpiresAt: new Date(result.credentials.tokenExpiresAt) } : {}), + ...(result.credentials.scopes ? { scopes: result.credentials.scopes } : {}), + status: 'CONNECTED', + lastVerifiedAt: completedAt, + errorCode: null, + errorMessage: null, + updatedAt: completedAt, + }).where(eq(publishingChannelAccounts.id, channelAccount.id)) + } + if (result.status === 'PUBLISHED') { + await tx.update(episodes).set({ status: 'PUBLISHED', updatedAt: completedAt }).where(eq(episodes.id, row.episode.id)) + } + }) + await publishRealtimeEvent({ + workspaceId: row.project.workspaceId, + type: 'delivery.updated', + resourceType: 'delivery', + resourceId: row.delivery.id, + payload: { id: row.delivery.id, platform, status: result.status, externalId: result.externalId, publishedUrl: result.publishedUrl }, + }) + return { + provider: 'publishing-connector', + providerModel: `${platform.toLowerCase()}-delivery-v1`, + output: { deliveryId: row.delivery.id, status: result.status, externalId: result.externalId, publishedUrl: result.publishedUrl, renderId: row.render.id }, + } + } catch (error) { + const [failed] = await db.update(deliveries).set({ + status: 'FAILED', + errorMessage: error instanceof Error ? error.message : 'Delivery failed', + updatedAt: new Date(), + }).where(and(eq(deliveries.id, row.delivery.id), eq(deliveries.status, 'PUBLISHING'))).returning({ id: deliveries.id }) + if (failed) { + await publishRealtimeEvent({ + workspaceId: row.project.workspaceId, + type: 'delivery.updated', + resourceType: 'delivery', + resourceId: row.delivery.id, + payload: { id: row.delivery.id, platform: row.delivery.platform, status: 'FAILED', errorMessage: error instanceof Error ? error.message : 'Delivery failed' }, + }) + } + throw error + } +} + +export async function processGenerationJob(data: GenerationJobData, options: { publishingAdapters?: PublishingAdapterRegistry } = {}): Promise { + if (data.type === 'PIPELINE_HEALTHCHECK') { + return { + provider: 'local', + providerModel: 'healthcheck-v1', + output: { + ok: true, + checkedAt: new Date().toISOString(), + echo: data.input, + }, + } + } + + if (data.type === 'SCRIPT_GENERATE') return processScript(data) + if (data.type === 'STORYBOARD_GENERATE') return processStoryboard(data) + if (data.type === 'ASSET_GENERATE') return processAsset(data) + if (data.type === 'TTS_GENERATE') return processSpeech(data) + if (data.type === 'VIDEO_GENERATE') return processVideo(data) + if (data.type === 'LIPSYNC_GENERATE') return processLipsync(data) + if (data.type === 'EPISODE_RENDER') return processRender(data) + if (data.type === 'DELIVERY_PUBLISH') return processDelivery(data, options.publishingAdapters ?? createPublishingAdapterRegistry()) + + throw new Error(`Processor for ${data.type} is not configured yet`) +} diff --git a/server/src/queue/production-plan.test.ts b/server/src/queue/production-plan.test.ts new file mode 100644 index 0000000..44b50a1 --- /dev/null +++ b/server/src/queue/production-plan.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, it } from 'vitest' +import { buildShotProductionChain, flattenProductionPlan, type ProductionPlanSettings, type ProductionShotState } from './production-plan.js' + +const settings: ProductionPlanSettings = { + mode: 'MISSING', + imageProvider: 'openai', + videoProvider: 'replicate', + imageWidth: 1536, + imageHeight: 1024, + voice: 'alloy', + speechSpeed: 1, + enableLipsync: true, + videoParams: {}, + lipsyncParams: {}, +} + +function shot(overrides: Partial = {}): ProductionShotState { + return { + id: '10000000-0000-4000-8000-000000000001', + title: '雨夜天台', + description: '角色推门进入雨夜天台', + durationMs: 3200, + subtitleText: '你终于来了。', + imageAssetVersionId: null, + imageStorageKey: null, + videoStorageKey: null, + audioStorageKey: null, + generationParams: {}, + ...overrides, + } +} + +describe('whole-episode production planner', () => { + it('builds a deterministic per-shot dependency chain', () => { + const chain = buildShotProductionChain(shot(), settings) + expect(chain?.type).toBe('LIPSYNC_GENERATE') + expect(chain?.children?.[0]?.type).toBe('TTS_GENERATE') + expect(chain?.children?.[0]?.children?.[0]?.type).toBe('VIDEO_GENERATE') + expect(chain?.children?.[0]?.children?.[0]?.children?.[0]?.type).toBe('ASSET_GENERATE') + expect(flattenProductionPlan([chain!]).map((job) => job.type)).toEqual([ + 'LIPSYNC_GENERATE', + 'TTS_GENERATE', + 'VIDEO_GENERATE', + 'ASSET_GENERATE', + ]) + }) + + it('only fills missing media and skips a completed lipsynced shot', () => { + expect(buildShotProductionChain(shot({ + imageStorageKey: 'workspace/project/image.png', + videoStorageKey: 'workspace/project/shots/lipsync/video.mp4', + audioStorageKey: 'workspace/project/audio.mp3', + }), settings)).toBeNull() + + const videoOnly = buildShotProductionChain(shot({ + subtitleText: '', + imageStorageKey: 'workspace/project/image.png', + }), settings) + expect(videoOnly?.type).toBe('VIDEO_GENERATE') + expect(videoOnly?.children).toBeUndefined() + }) + + it('regenerates every enabled stage when requested', () => { + const chain = buildShotProductionChain(shot({ + imageStorageKey: 'workspace/project/image.png', + videoStorageKey: 'workspace/project/shots/lipsync/video.mp4', + audioStorageKey: 'workspace/project/audio.mp3', + generationParams: { operation: 'lipsync' }, + }), { ...settings, mode: 'REGENERATE' }) + expect(flattenProductionPlan([chain!]).map((job) => job.type)).toEqual([ + 'LIPSYNC_GENERATE', + 'TTS_GENERATE', + 'VIDEO_GENERATE', + 'ASSET_GENERATE', + ]) + }) + + it('omits lip-sync while still producing picture, video and speech', () => { + const chain = buildShotProductionChain(shot(), { ...settings, enableLipsync: false }) + expect(flattenProductionPlan([chain!]).map((job) => job.type)).toEqual([ + 'TTS_GENERATE', + 'VIDEO_GENERATE', + 'ASSET_GENERATE', + ]) + }) +}) diff --git a/server/src/queue/production-plan.ts b/server/src/queue/production-plan.ts new file mode 100644 index 0000000..26f0fff --- /dev/null +++ b/server/src/queue/production-plan.ts @@ -0,0 +1,109 @@ +import type { JobKind } from './types.js' + +export interface ProductionPlanNode { + type: JobKind + input: Record + children?: ProductionPlanNode[] +} + +export interface ProductionShotState { + id: string + title: string + description: string + durationMs: number + subtitleText: string + imageAssetVersionId: string | null + imageStorageKey: string | null + videoStorageKey: string | null + audioStorageKey: string | null + generationParams: Record +} + +export interface ProductionPlanSettings { + mode: 'MISSING' | 'REGENERATE' + imageProvider: 'openai' | 'replicate' | 'agnes' | 'generic' + videoProvider: 'replicate' | 'agnes' | 'generic' + imageWidth: number + imageHeight: number + voice: string + speechSpeed: number + enableLipsync: boolean + videoParams: Record + lipsyncParams: Record +} + +function append(parent: ProductionPlanNode | null, next: ProductionPlanNode) { + if (parent) next.children = [parent] + return next +} + +function isLipsynced(shot: ProductionShotState) { + return shot.generationParams.operation === 'lipsync' + || Boolean(shot.videoStorageKey?.includes('/shots/lipsync/')) +} + +export function buildShotProductionChain(shot: ProductionShotState, settings: ProductionPlanSettings) { + const regenerate = settings.mode === 'REGENERATE' + const dialogue = shot.subtitleText.trim() + const needsImage = regenerate || (!shot.imageStorageKey && !shot.videoStorageKey) + const needsVideo = regenerate || !shot.videoStorageKey + const needsSpeech = Boolean(dialogue) && (regenerate || !shot.audioStorageKey) + const needsLipsync = settings.enableLipsync + && Boolean(dialogue) + && (regenerate || needsVideo || needsSpeech || !isLipsynced(shot)) + + let chain: ProductionPlanNode | null = null + if (needsImage) { + chain = append(chain, { + type: 'ASSET_GENERATE', + input: { + shotId: shot.id, + prompt: shot.description.trim() || shot.title, + width: settings.imageWidth, + height: settings.imageHeight, + provider: settings.imageProvider, + }, + }) + } + if (needsVideo) { + chain = append(chain, { + type: 'VIDEO_GENERATE', + input: { + shotId: shot.id, + prompt: shot.description.trim() || shot.title, + durationSeconds: shot.durationMs / 1000, + provider: settings.videoProvider, + params: settings.videoParams, + }, + }) + } + if (needsSpeech) { + chain = append(chain, { + type: 'TTS_GENERATE', + input: { + shotId: shot.id, + text: dialogue, + voice: settings.voice, + speed: settings.speechSpeed, + provider: 'openai', + }, + }) + } + if (needsLipsync) { + chain = append(chain, { + type: 'LIPSYNC_GENERATE', + input: { shotId: shot.id, provider: 'replicate', params: settings.lipsyncParams }, + }) + } + return chain +} + +export function flattenProductionPlan(nodes: ProductionPlanNode[]) { + const flattened: ProductionPlanNode[] = [] + const visit = (node: ProductionPlanNode) => { + flattened.push(node) + node.children?.forEach(visit) + } + nodes.forEach(visit) + return flattened +} diff --git a/server/src/queue/render-processor.integration.test.ts b/server/src/queue/render-processor.integration.test.ts new file mode 100644 index 0000000..f737f57 --- /dev/null +++ b/server/src/queue/render-processor.integration.test.ts @@ -0,0 +1,202 @@ +import { readFile } from 'node:fs/promises' +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { + assets, + assetVersions, + generationJobs, + renders, + shots, + shotVersions, + users, + workspaces, +} from '../db/schema.js' +import { deleteObject, getObjectBuffer, putObject } from '../storage/client.js' +import { processGenerationJob } from './processors.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('render processor artifacts', () => { + let app: FastifyInstance + let session: Session + let workspaceId = '' + let projectId = '' + let episodeId = '' + const objectKeys: string[] = [] + + async function request(method: string, url: string, payload?: unknown) { + const response = await app.inject({ + method, + url, + headers: { authorization: `Bearer ${session.accessToken}` }, + payload, + }) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + beforeAll(async () => { + app = await buildApp() + const nonce = crypto.randomUUID().slice(0, 8) + const registration = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `render-processor-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: 'Render processor account', + workspaceName: `Render processor workspace ${nonce}`, + }, + }) + expect(registration.statusCode, registration.body).toBe(201) + session = registration.json() + workspaceId = session.workspaces[0].id + + const project = await request('POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '字幕产物测试项目', + logline: '验证渲染版本清单与字幕侧车文件。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + const episode = await request('POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '字幕产物测试集', + synopsis: '', + targetDurationSeconds: 30, + }) + episodeId = episode.id + }) + + afterAll(async () => { + await Promise.allSettled(objectKeys.map((key) => deleteObject(key))) + if (workspaceId) await db.delete(workspaces).where(eq(workspaces.id, workspaceId)) + if (session?.user.id) await db.delete(users).where(eq(users.id, session.user.id)) + await app.close() + }) + + it('stores immutable source versions plus matching SRT and VTT objects', async () => { + const sourceImageKey = `${workspaceId}/${projectId}/generated/test/render-source.jpg` + objectKeys.push(sourceImageKey) + await putObject({ + key: sourceImageKey, + body: await readFile(new URL('../../../public/assets/scene-rooftop.jpg', import.meta.url)), + contentType: 'image/jpeg', + }) + + const [asset] = await db.insert(assets).values({ + projectId, + type: 'SHOT', + name: '渲染测试画面', + status: 'APPROVED', + createdById: session.user.id, + }).returning() + if (!asset) throw new Error('Failed to create render source asset') + const [assetVersion] = await db.insert(assetVersions).values({ + assetId: asset.id, + version: 1, + storageKey: sourceImageKey, + mimeType: 'image/jpeg', + width: 1280, + height: 720, + isCurrent: true, + createdById: session.user.id, + }).returning() + if (!assetVersion) throw new Error('Failed to create render source version') + + const [shot] = await db.insert(shots).values({ + episodeId, + shotNumber: 1, + sceneNumber: 1, + title: '字幕镜头', + description: '用于验证字幕侧车文件。', + shotType: '全景', + cameraMotion: '静止', + durationMs: 1_200, + sortOrder: 100, + status: 'APPROVED', + createdById: session.user.id, + }).returning() + if (!shot) throw new Error('Failed to create render source shot') + const [shotVersion] = await db.insert(shotVersions).values({ + shotId: shot.id, + version: 1, + imageAssetVersionId: assetVersion.id, + subtitleText: '不可变字幕版本', + isCurrent: true, + createdById: session.user.id, + }).returning() + if (!shotVersion) throw new Error('Failed to create render source shot version') + + const [render] = await db.insert(renders).values({ + episodeId, + version: 1, + width: 640, + height: 360, + fps: 24, + settings: { + width: 640, + height: 360, + fps: 24, + quality: 'draft', + burnSubtitles: true, + normalizeAudio: false, + }, + createdById: session.user.id, + }).returning() + if (!render) throw new Error('Failed to create test render') + const [job] = await db.insert(generationJobs).values({ + workspaceId, + projectId, + episodeId, + createdById: session.user.id, + type: 'EPISODE_RENDER', + status: 'RUNNING', + progress: 10, + idempotencyKey: `render-processor-${render.id}`, + input: { renderId: render.id }, + estimatedCredits: '1', + }).returning() + if (!job) throw new Error('Failed to create test render job') + + const result = await processGenerationJob({ + databaseId: job.id, + workspaceId, + projectId, + episodeId, + userId: session.user.id, + type: 'EPISODE_RENDER', + input: { renderId: render.id }, + }) + expect(result.output).toMatchObject({ + renderId: render.id, + subtitleFormats: ['srt', 'vtt'], + sourceShotCount: 1, + }) + + const [stored] = await db.select().from(renders).where(eq(renders.id, render.id)).limit(1) + expect(stored?.status).toBe('REVIEW') + expect(stored?.sourceManifest).toMatchObject({ + schemaVersion: 1, + shots: [{ shotId: shot.id, shotVersionId: shotVersion.id, subtitleText: '不可变字幕版本' }], + }) + expect(stored?.subtitleSrtKey).toBeTruthy() + expect(stored?.subtitleVttKey).toBeTruthy() + expect(stored?.storageKey).toBeTruthy() + objectKeys.push(...[stored?.subtitleSrtKey, stored?.subtitleVttKey, stored?.storageKey].filter((key): key is string => Boolean(key))) + + expect((await getObjectBuffer(stored!.subtitleSrtKey!)).toString('utf8')).toContain('00:00:00,000 --> 00:00:01,200\n不可变字幕版本') + expect((await getObjectBuffer(stored!.subtitleVttKey!)).toString('utf8')).toContain('WEBVTT\n\n00:00:00.000 --> 00:00:01.200\n不可变字幕版本') + + const persistedVersions = await db.select({ id: shotVersions.id }).from(shotVersions) + .where(inArray(shotVersions.id, stored!.sourceManifest!.shots.map((item) => item.shotVersionId))) + expect(persistedVersions).toEqual([{ id: shotVersion.id }]) + }, 30_000) +}) diff --git a/server/src/queue/types.ts b/server/src/queue/types.ts new file mode 100644 index 0000000..e480a62 --- /dev/null +++ b/server/src/queue/types.ts @@ -0,0 +1,34 @@ +export const GENERATION_QUEUE = 'frameflow-generation' + +export type JobKind = + | 'PIPELINE_HEALTHCHECK' + | 'SCRIPT_GENERATE' + | 'STORYBOARD_GENERATE' + | 'ASSET_GENERATE' + | 'TTS_GENERATE' + | 'VIDEO_GENERATE' + | 'LIPSYNC_GENERATE' + | 'EPISODE_RENDER' + | 'DELIVERY_PUBLISH' + +export interface GenerationJobData { + databaseId: string + workspaceId: string + projectId?: string + episodeId?: string + userId: string + type: JobKind + input: Record +} + +export interface GenerationJobResult { + provider?: string + providerModel?: string + output: Record + usage?: Array<{ + kind: 'TEXT_INPUT_TOKEN' | 'TEXT_OUTPUT_TOKEN' | 'IMAGE' | 'AUDIO_SECOND' | 'VIDEO_SECOND' | 'RENDER_SECOND' + quantity: number + credits: number + providerCostUsd?: number + }> +} diff --git a/server/src/routes/account-recovery.integration.test.ts b/server/src/routes/account-recovery.integration.test.ts new file mode 100644 index 0000000..bdd6611 --- /dev/null +++ b/server/src/routes/account-recovery.integration.test.ts @@ -0,0 +1,203 @@ +import type { FastifyInstance } from 'fastify' +import { and, eq, isNull } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { accountActionTokens, auditLogs, refreshTokens, users, workspaces } from '../db/schema.js' +import { hashToken } from '../lib/auth.js' + +interface Session { + accessToken: string + user: { id: string; email: string; emailVerified: boolean } + workspaces: Array<{ id: string }> +} + +function responseCookie(response: { headers: Record }) { + const header = response.headers['set-cookie'] + const value = Array.isArray(header) ? header[0] : String(header ?? '') + return value.split(';')[0] +} + +function actionToken(url: string, parameter: string) { + const token = new URL(url).searchParams.get(parameter) + if (!token) throw new Error(`Missing ${parameter} token`) + return token +} + +describe.sequential('email verification and password recovery', () => { + let app: FastifyInstance + let session: Session + let registrationCookie = '' + let secondaryCookie = '' + const initialPassword = 'RecoveryInitial2026!' + const nextPassword = 'RecoveryChanged2026!' + + async function inject(input: { method: string; url: string; payload?: unknown; cookie?: string }) { + return app.inject({ + method: input.method, + url: input.url, + headers: input.cookie ? { cookie: input.cookie } : {}, + payload: input.payload, + }) + } + + beforeAll(async () => { + app = await buildApp() + const nonce = crypto.randomUUID().slice(0, 8) + const response = await inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `recovery-${nonce}@frameflow.test`, + password: initialPassword, + displayName: 'Recovery Test', + workspaceName: `Recovery Workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + session = response.json() + registrationCookie = responseCookie(response) + }) + + afterAll(async () => { + if (session?.user.id) await db.delete(auditLogs).where(eq(auditLogs.resourceId, session.user.id)) + if (session?.workspaces[0]?.id) await db.delete(workspaces).where(eq(workspaces.id, session.workspaces[0].id)) + if (session?.user.id) await db.delete(users).where(eq(users.id, session.user.id)) + await app.close() + }) + + it('issues hashed single-use verification links without exposing unknown accounts', async () => { + expect(session.user.emailVerified).toBe(true) + await db.update(users).set({ emailVerifiedAt: null }).where(eq(users.id, session.user.id)) + + const unknown = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/request', + payload: { email: `unknown-${crypto.randomUUID()}@frameflow.test` }, + }) + expect(unknown.statusCode, unknown.body).toBe(202) + expect(unknown.json()).toEqual(expect.objectContaining({ accepted: true })) + expect(unknown.json().debugVerificationUrl).toBeUndefined() + + const first = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/request', + payload: { email: session.user.email.toUpperCase() }, + }) + const firstToken = actionToken(first.json().debugVerificationUrl, 'verify_email') + const [stored] = await db.select().from(accountActionTokens).where(eq(accountActionTokens.tokenHash, hashToken(firstToken))).limit(1) + expect(stored?.tokenHash).toBe(hashToken(firstToken)) + expect(stored?.tokenHash).not.toBe(firstToken) + + const second = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/request', + payload: { email: session.user.email }, + }) + const secondToken = actionToken(second.json().debugVerificationUrl, 'verify_email') + const stale = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/confirm', + payload: { token: firstToken }, + }) + expect(stale.statusCode, stale.body).toBe(400) + + const confirmed = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/confirm', + payload: { token: secondToken }, + }) + expect(confirmed.statusCode, confirmed.body).toBe(200) + expect(confirmed.json().user.emailVerified).toBe(true) + const [verified] = await db.select({ emailVerifiedAt: users.emailVerifiedAt }).from(users).where(eq(users.id, session.user.id)).limit(1) + expect(verified?.emailVerifiedAt).toBeInstanceOf(Date) + + const replayed = await inject({ + method: 'POST', + url: '/api/v1/auth/verify-email/confirm', + payload: { token: secondToken }, + }) + expect(replayed.statusCode, replayed.body).toBe(400) + }) + + it('resets the password once and revokes every existing refresh session', async () => { + const secondaryLogin = await inject({ + method: 'POST', + url: '/api/v1/auth/login', + payload: { email: session.user.email, password: initialPassword }, + }) + expect(secondaryLogin.statusCode, secondaryLogin.body).toBe(200) + secondaryCookie = responseCookie(secondaryLogin) + + const unknown = await inject({ + method: 'POST', + url: '/api/v1/auth/password/forgot', + payload: { email: `unknown-${crypto.randomUUID()}@frameflow.test` }, + }) + expect(unknown.statusCode, unknown.body).toBe(202) + expect(unknown.json().debugResetUrl).toBeUndefined() + + const first = await inject({ + method: 'POST', + url: '/api/v1/auth/password/forgot', + payload: { email: session.user.email }, + }) + const firstToken = actionToken(first.json().debugResetUrl, 'reset_password') + const second = await inject({ + method: 'POST', + url: '/api/v1/auth/password/forgot', + payload: { email: session.user.email }, + }) + const secondToken = actionToken(second.json().debugResetUrl, 'reset_password') + + const stale = await inject({ + method: 'POST', + url: '/api/v1/auth/password/reset', + payload: { token: firstToken, newPassword: nextPassword }, + }) + expect(stale.statusCode, stale.body).toBe(400) + + const reusedPassword = await inject({ + method: 'POST', + url: '/api/v1/auth/password/reset', + payload: { token: secondToken, newPassword: initialPassword }, + }) + expect(reusedPassword.statusCode, reusedPassword.body).toBe(409) + + const reset = await inject({ + method: 'POST', + url: '/api/v1/auth/password/reset', + payload: { token: secondToken, newPassword: nextPassword }, + }) + expect(reset.statusCode, reset.body).toBe(204) + const activeSessions = await db.select({ id: refreshTokens.id }).from(refreshTokens).where(and( + eq(refreshTokens.userId, session.user.id), + isNull(refreshTokens.revokedAt), + )) + expect(activeSessions).toHaveLength(0) + + for (const cookie of [registrationCookie, secondaryCookie]) { + const refresh = await inject({ method: 'POST', url: '/api/v1/auth/refresh', cookie }) + expect(refresh.statusCode, refresh.body).toBe(401) + } + const oldLogin = await inject({ + method: 'POST', + url: '/api/v1/auth/login', + payload: { email: session.user.email, password: initialPassword }, + }) + expect(oldLogin.statusCode, oldLogin.body).toBe(401) + const newLogin = await inject({ + method: 'POST', + url: '/api/v1/auth/login', + payload: { email: session.user.email, password: nextPassword }, + }) + expect(newLogin.statusCode, newLogin.body).toBe(200) + + const replayed = await inject({ + method: 'POST', + url: '/api/v1/auth/password/reset', + payload: { token: secondToken, newPassword: 'AnotherPassword2026!' }, + }) + expect(replayed.statusCode, replayed.body).toBe(400) + }) +}) diff --git a/server/src/routes/assets.integration.test.ts b/server/src/routes/assets.integration.test.ts new file mode 100644 index 0000000..a5fe7c3 --- /dev/null +++ b/server/src/routes/assets.integration.test.ts @@ -0,0 +1,219 @@ +import type { FastifyInstance } from 'fastify' +import { inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('asset management and media isolation', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + let assetId = '' + let assetVersionId = '' + let musicAssetId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: { authorization: `Bearer ${token}` }, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.statusCode === 204 ? null : response.json() + } + + async function register(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp() + owner = await register('asset-owner') + viewer = await register('asset-viewer') + workspaceId = owner.workspaces[0].id + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '资产治理测试项目', + logline: '验证资产筛选、生命周期和媒体隔离。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + }) + + afterAll(async () => { + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('edits, filters, archives, and restores project assets', async () => { + const character = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/assets`, { + type: 'CHARACTER', + name: '林遥测试角色', + description: '初始描述', + tags: ['人物'], + metadata: { importSource: 'character-bible' }, + }) + assetId = character.id + const music = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/assets`, { + type: 'MUSIC', + name: '雨夜配乐', + description: '氛围音乐', + tags: ['音乐'], + metadata: {}, + }) + musicAssetId = music.id + + const updated = await request(owner.accessToken, 'PATCH', `/api/v1/assets/${assetId}`, { + name: '林遥角色定稿', + description: '短发调查记者,深色风衣。', + tags: ['人物', '主角'], + status: 'APPROVED', + }) + expect(updated.name).toBe('林遥角色定稿') + expect(updated.tags).toEqual(['人物', '主角']) + + const approvedCharacters = await request(owner.accessToken, 'GET', `/api/v1/projects/${projectId}/assets?type=CHARACTER&status=APPROVED`) + expect(approvedCharacters).toHaveLength(1) + expect(approvedCharacters[0].asset.id).toBe(assetId) + + await request(owner.accessToken, 'PATCH', `/api/v1/assets/${assetId}`, { status: 'ARCHIVED' }) + const archived = await request(owner.accessToken, 'GET', `/api/v1/projects/${projectId}/assets?status=ARCHIVED`) + expect(archived.map((row: { asset: { id: string } }) => row.asset.id)).toContain(assetId) + + const restored = await request(owner.accessToken, 'PATCH', `/api/v1/assets/${assetId}`, { status: 'DRAFT' }) + expect(restored.status).toBe('DRAFT') + }) + + it('rejects asset media keys outside the owning project', async () => { + const foreignKey = `${viewer.workspaces[0].id}/foreign-project/uploads/foreign.png` + const rejected = await inject(owner.accessToken, 'POST', `/api/v1/assets/${assetId}/versions`, { + storageKey: foreignKey, + mimeType: 'image/png', + generationParams: { source: 'test' }, + }) + expect(rejected.statusCode, rejected.body).toBe(403) + expect(rejected.json().error.code).toBe('FORBIDDEN') + + const accepted = await request(owner.accessToken, 'POST', `/api/v1/assets/${assetId}/versions`, { + storageKey: `${workspaceId}/${projectId}/uploads/owned.png`, + thumbnailKey: `${workspaceId}/${projectId}/uploads/owned-thumb.png`, + mimeType: 'image/png', + generationParams: { source: 'test' }, + }) + expect(accepted.version).toBe(1) + expect(accepted.isCurrent).toBe(true) + assetVersionId = accepted.id + }) + + it('persists and validates a locked character consistency profile', async () => { + const otherCharacter = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/assets`, { + type: 'CHARACTER', + name: '其他测试角色', + description: '', + tags: [], + metadata: {}, + }) + const otherVersion = await request(owner.accessToken, 'POST', `/api/v1/assets/${otherCharacter.id}/versions`, { + storageKey: `${workspaceId}/${projectId}/uploads/other-character.png`, + mimeType: 'image/png', + generationParams: { source: 'test' }, + }) + + const wrongAsset = await inject(owner.accessToken, 'PUT', `/api/v1/assets/${assetId}/consistency-profile`, { + referenceAssetVersionIds: [otherVersion.id], + identityLocked: true, + }) + expect(wrongAsset.statusCode, wrongAsset.body).toBe(400) + + const missingReference = await inject(owner.accessToken, 'PUT', `/api/v1/assets/${assetId}/consistency-profile`, { + referenceAssetVersionIds: [], + identityLocked: true, + }) + expect(missingReference.statusCode, missingReference.body).toBe(400) + + const wrongType = await inject(owner.accessToken, 'PUT', `/api/v1/assets/${musicAssetId}/consistency-profile`, { + referenceAssetVersionIds: [], + identityLocked: false, + }) + expect(wrongType.statusCode, wrongType.body).toBe(400) + + const saved = await request(owner.accessToken, 'PUT', `/api/v1/assets/${assetId}/consistency-profile`, { + referenceAssetVersionIds: [assetVersionId], + identityPrompt: '短发调查记者,面部轮廓固定', + costumePrompt: '深色风衣与银色胸针', + stylePrompt: '写实冷色漫剧', + negativePrompt: '脸型漂移,服装变色', + consistencyStrength: 91, + identityLocked: true, + }) + expect(saved.consistencyProfile).toMatchObject({ + referenceAssetVersionIds: [assetVersionId], + consistencyStrength: 91, + identityLocked: true, + schemaVersion: 1, + }) + expect(saved.asset.metadata.importSource).toBe('character-bible') + + const detail = await request(owner.accessToken, 'GET', `/api/v1/assets/${assetId}`) + expect(detail.metadata.consistencyProfile.identityPrompt).toContain('调查记者') + expect(detail.metadata.importSource).toBe('character-bible') + + const bypass = await inject(owner.accessToken, 'PATCH', `/api/v1/assets/${assetId}`, { + metadata: { consistencyProfile: { identityLocked: false } }, + }) + expect(bypass.statusCode, bypass.body).toBe(400) + }) + + it('keeps asset management read-only for viewers', async () => { + const assets = await request(viewer.accessToken, 'GET', `/api/v1/projects/${projectId}/assets`) + expect(assets.length).toBeGreaterThanOrEqual(2) + + const forbidden = await inject(viewer.accessToken, 'PATCH', `/api/v1/assets/${assetId}`, { + name: '访客不应改名', + }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + expect(forbidden.json().error.code).toBe('FORBIDDEN') + + const profileForbidden = await inject(viewer.accessToken, 'PUT', `/api/v1/assets/${assetId}/consistency-profile`, { + referenceAssetVersionIds: [assetVersionId], + identityLocked: true, + }) + expect(profileForbidden.statusCode, profileForbidden.body).toBe(403) + }) +}) diff --git a/server/src/routes/assets.ts b/server/src/routes/assets.ts new file mode 100644 index 0000000..a5ef66b --- /dev/null +++ b/server/src/routes/assets.ts @@ -0,0 +1,213 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq, inArray, sql } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { assets, assetVersions, projects } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { + characterConsistencyProfileInputSchema, + createCharacterConsistencyProfile, +} from '../lib/character-consistency.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission } from '../lib/permissions.js' + +const projectParams = z.object({ projectId: z.uuid() }) +const assetParams = z.object({ assetId: z.uuid() }) +const assetVersionParams = z.object({ assetId: z.uuid(), versionId: z.uuid() }) +const listQuery = z.object({ + type: z.enum(['CHARACTER', 'SCENE', 'PROP', 'VOICE', 'MUSIC', 'SHOT']).optional(), + status: z.enum(['DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'ARCHIVED']).optional(), +}) +const createAssetSchema = z.object({ + type: z.enum(['CHARACTER', 'SCENE', 'PROP', 'VOICE', 'MUSIC', 'SHOT']), + name: z.string().trim().min(1).max(180), + description: z.string().max(5000).default(''), + tags: z.array(z.string().trim().min(1).max(60)).max(30).default([]), + metadata: z.record(z.string(), z.unknown()).default({}), +}) +const updateAssetSchema = createAssetSchema.omit({ type: true }).partial().extend({ + status: z.enum(['DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'ARCHIVED']).optional(), +}) +const assetVersionSchema = z.object({ + storageKey: z.string().max(1000).optional(), + thumbnailKey: z.string().max(1000).optional(), + mimeType: z.string().max(120).optional(), + byteSize: z.number().int().positive().optional(), + width: z.number().int().positive().optional(), + height: z.number().int().positive().optional(), + durationMs: z.number().int().positive().optional(), + prompt: z.string().max(20000).default(''), + negativePrompt: z.string().max(10000).default(''), + provider: z.string().max(80).optional(), + providerModel: z.string().max(160).optional(), + seed: z.string().max(80).optional(), + generationParams: z.record(z.string(), z.unknown()).default({}), +}) + +async function assetProject(assetId: string) { + const [row] = await db.select({ asset: assets, project: projects }).from(assets).innerJoin(projects, eq(projects.id, assets.projectId)).where(eq(assets.id, assetId)).limit(1) + if (!row) throw errors.notFound('Asset') + return row +} + +export async function assetRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/projects/:projectId/assets', async (request) => { + const { projectId } = parseWith(projectParams, request.params) + const query = parseWith(listQuery, request.query) + await requireProjectPermission(request, projectId, 'project:read') + const filters = [eq(assets.projectId, projectId)] + if (query.type) filters.push(eq(assets.type, query.type)) + if (query.status) filters.push(eq(assets.status, query.status)) + return db.select({ asset: assets, currentVersion: assetVersions }).from(assets).leftJoin(assetVersions, and( + eq(assetVersions.assetId, assets.id), + eq(assetVersions.isCurrent, true), + )).where(and(...filters)).orderBy(desc(assets.updatedAt)) + }) + + app.post('/projects/:projectId/assets', async (request, reply) => { + const { projectId } = parseWith(projectParams, request.params) + const input = parseWith(createAssetSchema, request.body) + const { project } = await requireProjectPermission(request, projectId, 'content:write') + if (Object.prototype.hasOwnProperty.call(input.metadata, 'consistencyProfile')) { + throw errors.badRequest('Use the consistency profile endpoint to manage character identity') + } + const [asset] = await db.insert(assets).values({ + projectId, + createdById: request.user.sub, + ...input, + }).returning() + if (!asset) throw new Error('Failed to create asset') + await audit({ request, workspaceId: project.workspaceId, action: 'asset.create', resourceType: 'asset', resourceId: asset.id, after: asset }) + return reply.code(201).send(asset) + }) + + app.get('/assets/:assetId', async (request) => { + const { assetId } = parseWith(assetParams, request.params) + const row = await assetProject(assetId) + await requireProjectPermission(request, row.project.id, 'project:read') + const versions = await db.select().from(assetVersions).where(eq(assetVersions.assetId, assetId)).orderBy(desc(assetVersions.version)) + return { ...row.asset, versions } + }) + + app.patch('/assets/:assetId', async (request) => { + const { assetId } = parseWith(assetParams, request.params) + const input = parseWith(updateAssetSchema, request.body) + const row = await assetProject(assetId) + await requireProjectPermission(request, row.project.id, 'content:write') + if (input.metadata && Object.prototype.hasOwnProperty.call(input.metadata, 'consistencyProfile')) { + throw errors.badRequest('Use the consistency profile endpoint to manage character identity') + } + const changes = { + ...input, + ...(input.metadata ? { metadata: { ...(row.asset.metadata ?? {}), ...input.metadata } } : {}), + updatedAt: new Date(), + } + const [updated] = await db.update(assets).set(changes).where(eq(assets.id, assetId)).returning() + if (!updated) throw errors.notFound('Asset') + await audit({ request, workspaceId: row.project.workspaceId, action: 'asset.update', resourceType: 'asset', resourceId: assetId, before: row.asset, after: updated }) + return updated + }) + + app.put('/assets/:assetId/consistency-profile', async (request) => { + const { assetId } = parseWith(assetParams, request.params) + const input = parseWith(characterConsistencyProfileInputSchema, request.body) + const row = await assetProject(assetId) + await requireProjectPermission(request, row.project.id, 'content:write') + if (row.asset.type !== 'CHARACTER') throw errors.badRequest('Consistency profiles are only available for character assets') + + const references = input.referenceAssetVersionIds.length > 0 + ? await db.select({ + id: assetVersions.id, + storageKey: assetVersions.storageKey, + mimeType: assetVersions.mimeType, + }).from(assetVersions).where(and( + eq(assetVersions.assetId, assetId), + inArray(assetVersions.id, input.referenceAssetVersionIds), + )) + : [] + if (references.length !== input.referenceAssetVersionIds.length) { + throw errors.badRequest('Every identity reference must belong to this character asset') + } + if (references.some((reference) => !reference.storageKey || !reference.mimeType?.startsWith('image/'))) { + throw errors.badRequest('Every identity reference must be a stored image version') + } + + const profile = createCharacterConsistencyProfile(input, request.user.sub) + const profilePatch = JSON.stringify({ consistencyProfile: profile }) + const [updated] = await db.update(assets).set({ + metadata: sql`${assets.metadata} || ${profilePatch}::jsonb`, + updatedAt: new Date(), + }).where(eq(assets.id, assetId)).returning() + if (!updated) throw errors.notFound('Asset') + await audit({ + request, + workspaceId: row.project.workspaceId, + action: 'asset.consistency_profile.update', + resourceType: 'asset', + resourceId: assetId, + before: { consistencyProfile: row.asset.metadata?.consistencyProfile ?? null }, + after: { consistencyProfile: profile }, + }) + return { asset: updated, consistencyProfile: profile } + }) + + app.post('/assets/:assetId/versions', async (request, reply) => { + const { assetId } = parseWith(assetParams, request.params) + const input = parseWith(assetVersionSchema, request.body) + const row = await assetProject(assetId) + await requireProjectPermission(request, row.project.id, 'content:write') + const projectPrefix = `${row.project.workspaceId}/${row.project.id}/` + for (const key of [input.storageKey, input.thumbnailKey]) { + if (key && !key.startsWith(projectPrefix)) throw errors.forbidden('Asset media must belong to this project') + } + + const created = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`asset:${assetId}`}))`) + const [latest] = await tx.select({ version: assetVersions.version }).from(assetVersions).where(eq(assetVersions.assetId, assetId)).orderBy(desc(assetVersions.version)).limit(1) + await tx.update(assetVersions).set({ isCurrent: false }).where(eq(assetVersions.assetId, assetId)) + const [version] = await tx.insert(assetVersions).values({ + assetId, + version: (latest?.version ?? 0) + 1, + ...input, + isCurrent: true, + createdById: request.user.sub, + }).returning() + return version + }) + if (!created) throw new Error('Failed to create asset version') + await audit({ request, workspaceId: row.project.workspaceId, action: 'asset.version.create', resourceType: 'asset_version', resourceId: created.id, after: { assetId, version: created.version } }) + return reply.code(201).send(created) + }) + + app.post('/assets/:assetId/versions/:versionId/activate', async (request) => { + const { assetId, versionId } = parseWith(assetVersionParams, request.params) + const row = await assetProject(assetId) + await requireProjectPermission(request, row.project.id, 'content:write') + + const result = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`asset:${assetId}`}))`) + const [version] = await tx.select().from(assetVersions).where(and( + eq(assetVersions.id, versionId), + eq(assetVersions.assetId, assetId), + )).limit(1) + if (!version) throw errors.notFound('Asset version') + if (version.isCurrent) return { version, changed: false } + await tx.update(assetVersions).set({ isCurrent: false }).where(eq(assetVersions.assetId, assetId)) + const [activated] = await tx.update(assetVersions).set({ isCurrent: true }).where(and( + eq(assetVersions.id, versionId), + eq(assetVersions.assetId, assetId), + )).returning() + if (!activated) throw errors.notFound('Asset version') + return { version: activated, changed: true } + }) + + if (result.changed) { + await audit({ request, workspaceId: row.project.workspaceId, action: 'asset.version.activate', resourceType: 'asset_version', resourceId: versionId, after: { assetId, version: result.version.version } }) + } + return result.version + }) +} diff --git a/server/src/routes/audit.integration.test.ts b/server/src/routes/audit.integration.test.ts new file mode 100644 index 0000000..4f16d41 --- /dev/null +++ b/server/src/routes/audit.integration.test.ts @@ -0,0 +1,129 @@ +import type { FastifyInstance } from 'fastify' +import { inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('workspace audit log access', () => { + let app: FastifyInstance + let owner: Session + let member: Session + let workspaceId = '' + let otherWorkspaceId = '' + let projectId = '' + const userIds: string[] = [] + const workspaceIds: string[] = [] + + async function inject(token: string | null, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: token ? { authorization: `Bearer ${token}` } : undefined, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + async function register(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + workspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp() + owner = await register('audit-owner') + member = await register('audit-member') + workspaceId = owner.workspaces[0].id + otherWorkspaceId = member.workspaces[0].id + + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: member.user.email, + role: 'VIEWER', + }) + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '审计日志测试项目', + logline: '审计查询测试', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + await request(owner.accessToken, 'PATCH', `/api/v1/projects/${projectId}`, { + status: 'ACTIVE', + logline: '更新后的审计查询测试', + }) + await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '审计测试分集', + synopsis: '', + targetDurationSeconds: 60, + }) + }) + + afterAll(async () => { + if (workspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, workspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('restricts audit history to workspace administrators', async () => { + const unauthenticated = await inject(null, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs`) + expect(unauthenticated.statusCode).toBe(401) + + const forbidden = await inject(member.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs`) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + await request(owner.accessToken, 'PATCH', `/api/v1/workspaces/${workspaceId}/members/${member.user.id}`, { role: 'ADMIN' }) + const adminPage = await request(member.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs?limit=10`) + expect(adminPage.items.length).toBeGreaterThan(0) + }) + + it('returns actor context and applies category and actor filters', async () => { + const projectPage = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs?category=project&actorId=${owner.user.id}`) + expect(projectPage.items.map((item: { action: string }) => item.action)).toEqual(expect.arrayContaining(['project.create', 'project.update'])) + expect(projectPage.items.every((item: { action: string; actor: { id: string } | null }) => item.action.startsWith('project.') && item.actor?.id === owner.user.id)).toBe(true) + + const updated = projectPage.items.find((item: { action: string }) => item.action === 'project.update') + expect(updated.before.logline).toBe('审计查询测试') + expect(updated.after.logline).toBe('更新后的审计查询测试') + }) + + it('paginates without duplicates and rejects cursors from another workspace', async () => { + const first = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs?limit=2`) + expect(first.items).toHaveLength(2) + expect(first.nextCursor).toBeTruthy() + + const second = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs?limit=2&cursor=${first.nextCursor}`) + expect(second.items.length).toBeGreaterThan(0) + expect(second.items.some((item: { id: string }) => first.items.some((firstItem: { id: string }) => firstItem.id === item.id))).toBe(false) + + const otherPage = await request(member.accessToken, 'GET', `/api/v1/workspaces/${otherWorkspaceId}/audit-logs?limit=1`) + const invalidCursor = await inject(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/audit-logs?cursor=${otherPage.items[0].id}`) + expect(invalidCursor.statusCode, invalidCursor.body).toBe(400) + }) +}) diff --git a/server/src/routes/audit.ts b/server/src/routes/audit.ts new file mode 100644 index 0000000..b335ab7 --- /dev/null +++ b/server/src/routes/audit.ts @@ -0,0 +1,68 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq, like, lt, or } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { auditLogs, users } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireWorkspacePermission } from '../lib/permissions.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const auditQuery = z.object({ + limit: z.coerce.number().int().min(1).max(100).default(50), + cursor: z.uuid().optional(), + action: z.string().trim().min(1).max(120).optional(), + category: z.enum(['auth', 'member', 'project', 'episode', 'script', 'asset', 'shot', 'shots', 'job', 'production_run', 'review', 'render', 'delivery', 'billing', 'upload', 'service']).optional(), + resourceType: z.string().trim().min(1).max(80).optional(), + actorId: z.uuid().optional(), +}) + +export async function auditRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/audit-logs', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const query = parseWith(auditQuery, request.query) + await requireWorkspacePermission(request, workspaceId, 'audit:read') + + const filters = [eq(auditLogs.workspaceId, workspaceId)] + if (query.action) filters.push(eq(auditLogs.action, query.action)) + if (query.category) filters.push(like(auditLogs.action, `${query.category}.%`)) + if (query.resourceType) filters.push(eq(auditLogs.resourceType, query.resourceType)) + if (query.actorId) filters.push(eq(auditLogs.actorId, query.actorId)) + + if (query.cursor) { + const [cursor] = await db.select({ id: auditLogs.id, createdAt: auditLogs.createdAt }).from(auditLogs).where(and( + eq(auditLogs.id, query.cursor), + eq(auditLogs.workspaceId, workspaceId), + )).limit(1) + if (!cursor) throw errors.badRequest('Audit cursor is invalid for this workspace') + const cursorFilter = or( + lt(auditLogs.createdAt, cursor.createdAt), + and(eq(auditLogs.createdAt, cursor.createdAt), lt(auditLogs.id, cursor.id)), + ) + if (cursorFilter) filters.push(cursorFilter) + } + + const rows = await db.select({ + log: auditLogs, + actor: { + id: users.id, + email: users.email, + displayName: users.displayName, + }, + }).from(auditLogs) + .leftJoin(users, eq(users.id, auditLogs.actorId)) + .where(and(...filters)) + .orderBy(desc(auditLogs.createdAt), desc(auditLogs.id)) + .limit(query.limit + 1) + + const hasMore = rows.length > query.limit + const page = rows.slice(0, query.limit) + return { + items: page.map(({ log, actor }) => ({ ...log, actor: actor?.id ? actor : null })), + nextCursor: hasMore ? page.at(-1)?.log.id ?? null : null, + } + }) +} diff --git a/server/src/routes/auth-security.integration.test.ts b/server/src/routes/auth-security.integration.test.ts new file mode 100644 index 0000000..89d0c63 --- /dev/null +++ b/server/src/routes/auth-security.integration.test.ts @@ -0,0 +1,214 @@ +import type { FastifyInstance } from 'fastify' +import { and, eq, isNull } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { auditLogs, refreshTokens, users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +interface AuthenticatedSession extends Session { + cookie: string +} + +function responseCookie(response: { headers: Record }) { + const header = response.headers['set-cookie'] + const value = Array.isArray(header) ? header[0] : String(header ?? '') + return value.split(';')[0] +} + +describe.sequential('account session security', () => { + let app: FastifyInstance + let primary: AuthenticatedSession + let secondary: AuthenticatedSession + let userId = '' + let workspaceId = '' + const initialPassword = 'Integration2026!' + const nextPassword = 'ChangedPassword2026!' + + async function inject(input: { + method: string + url: string + token?: string + cookie?: string + payload?: unknown + userAgent?: string + }) { + return app.inject({ + method: input.method, + url: input.url, + headers: { + ...(input.token ? { authorization: `Bearer ${input.token}` } : {}), + ...(input.cookie ? { cookie: input.cookie } : {}), + ...(input.userAgent ? { 'user-agent': input.userAgent } : {}), + }, + payload: input.payload, + }) + } + + async function login(password: string, userAgent: string): Promise { + const response = await inject({ + method: 'POST', + url: '/api/v1/auth/login', + payload: { email: primary.user.email, password }, + userAgent, + }) + expect(response.statusCode, response.body).toBe(200) + return { ...response.json(), cookie: responseCookie(response) } + } + + beforeAll(async () => { + app = await buildApp() + const nonce = crypto.randomUUID().slice(0, 8) + const response = await inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `security-${nonce}@frameflow.test`, + password: initialPassword, + displayName: 'Security Test', + workspaceName: `Security Workspace ${nonce}`, + }, + userAgent: 'FrameFlow Desktop QA', + }) + expect(response.statusCode, response.body).toBe(201) + primary = { ...response.json(), cookie: responseCookie(response) } + userId = primary.user.id + workspaceId = primary.workspaces[0].id + secondary = await login(initialPassword, 'FrameFlow Mobile QA') + }) + + afterAll(async () => { + if (userId) await db.delete(auditLogs).where(eq(auditLogs.actorId, userId)) + if (workspaceId) await db.delete(workspaces).where(eq(workspaces.id, workspaceId)) + if (userId) await db.delete(users).where(eq(users.id, userId)) + await app.close() + }) + + it('lists active devices and identifies the refresh cookie session', async () => { + const unauthorized = await inject({ method: 'GET', url: '/api/v1/auth/sessions' }) + expect(unauthorized.statusCode, unauthorized.body).toBe(401) + + const response = await inject({ + method: 'GET', + url: '/api/v1/auth/sessions', + token: secondary.accessToken, + cookie: secondary.cookie, + }) + expect(response.statusCode, response.body).toBe(200) + const sessions = response.json>() + expect(sessions).toHaveLength(2) + expect(sessions.filter((session) => session.current)).toHaveLength(1) + expect(sessions.find((session) => session.current)?.userAgent).toBe('FrameFlow Mobile QA') + expect(sessions.some((session) => session.userAgent === 'FrameFlow Desktop QA')).toBe(true) + expect(sessions.every((session) => session.tokenHash === undefined)).toBe(true) + }) + + it('revokes a selected remote session without affecting the current device', async () => { + const list = await inject({ + method: 'GET', + url: '/api/v1/auth/sessions', + token: secondary.accessToken, + cookie: secondary.cookie, + }) + const remote = list.json>().find((session) => !session.current) + expect(remote).toBeTruthy() + + const revoked = await inject({ + method: 'DELETE', + url: `/api/v1/auth/sessions/${remote!.id}`, + token: secondary.accessToken, + cookie: secondary.cookie, + }) + expect(revoked.statusCode, revoked.body).toBe(204) + + const after = await inject({ + method: 'GET', + url: '/api/v1/auth/sessions', + token: secondary.accessToken, + cookie: secondary.cookie, + }) + expect(after.json()).toHaveLength(1) + + const rejectedRefresh = await inject({ method: 'POST', url: '/api/v1/auth/refresh', cookie: primary.cookie }) + expect(rejectedRefresh.statusCode, rejectedRefresh.body).toBe(401) + }) + + it('revokes every other device while preserving the current refresh session', async () => { + const tertiary = await login(initialPassword, 'FrameFlow Tablet QA') + const response = await inject({ + method: 'DELETE', + url: '/api/v1/auth/sessions/others', + token: secondary.accessToken, + cookie: secondary.cookie, + }) + expect(response.statusCode, response.body).toBe(200) + expect(response.json().revoked).toBe(1) + + const active = await inject({ + method: 'GET', + url: '/api/v1/auth/sessions', + token: secondary.accessToken, + cookie: secondary.cookie, + }) + expect(active.json()).toEqual([expect.objectContaining({ current: true, userAgent: 'FrameFlow Mobile QA' })]) + + const rejectedRefresh = await inject({ method: 'POST', url: '/api/v1/auth/refresh', cookie: tertiary.cookie }) + expect(rejectedRefresh.statusCode, rejectedRefresh.body).toBe(401) + }) + + it('changes the password only after verification and invalidates all old sessions', async () => { + const remote = await login(initialPassword, 'FrameFlow Studio QA') + const wrong = await inject({ + method: 'PATCH', + url: '/api/v1/auth/password', + token: secondary.accessToken, + cookie: secondary.cookie, + payload: { currentPassword: 'WrongPassword2026!', newPassword: nextPassword }, + }) + expect(wrong.statusCode, wrong.body).toBe(401) + + const reused = await inject({ + method: 'PATCH', + url: '/api/v1/auth/password', + token: secondary.accessToken, + cookie: secondary.cookie, + payload: { currentPassword: initialPassword, newPassword: initialPassword }, + }) + expect(reused.statusCode, reused.body).toBe(409) + + const changed = await inject({ + method: 'PATCH', + url: '/api/v1/auth/password', + token: secondary.accessToken, + cookie: secondary.cookie, + payload: { currentPassword: initialPassword, newPassword: nextPassword }, + }) + expect(changed.statusCode, changed.body).toBe(204) + expect(String(changed.headers['set-cookie'])).toContain('ff_refresh=') + + const [activeCount] = await db.select({ id: refreshTokens.id }).from(refreshTokens).where(and( + eq(refreshTokens.userId, userId), + isNull(refreshTokens.revokedAt), + )).limit(1) + expect(activeCount).toBeUndefined() + + for (const cookie of [secondary.cookie, remote.cookie]) { + const rejectedRefresh = await inject({ method: 'POST', url: '/api/v1/auth/refresh', cookie }) + expect(rejectedRefresh.statusCode, rejectedRefresh.body).toBe(401) + } + + const oldLogin = await inject({ + method: 'POST', + url: '/api/v1/auth/login', + payload: { email: primary.user.email, password: initialPassword }, + }) + expect(oldLogin.statusCode, oldLogin.body).toBe(401) + const newLogin = await login(nextPassword, 'FrameFlow New Password QA') + expect(newLogin.accessToken).toBeTruthy() + }) +}) diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts new file mode 100644 index 0000000..791d26f --- /dev/null +++ b/server/src/routes/auth.ts @@ -0,0 +1,448 @@ +import argon2 from 'argon2' +import type { FastifyInstance, FastifyRequest } from 'fastify' +import { and, desc, eq, gt, isNull, ne } from 'drizzle-orm' +import { z } from 'zod' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { accountActionTokens, memberships, refreshTokens, users, workspaces } from '../db/schema.js' +import { + createRefreshSession, + hashToken, + REFRESH_COOKIE, + refreshCookieOptions, + requireAuth, + revokeRefreshSession, + rotateRefreshSession, + signAccessToken, +} from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { issueAccountToken, type AccountTokenType } from '../lib/account-tokens.js' +import { errors } from '../lib/errors.js' +import { parseWith, requestMeta } from '../lib/http.js' +import { accountActionUrl, sendAccountActionEmail } from '../lib/mailer.js' +import { slugify } from '../lib/slug.js' + +const registerSchema = z.object({ + email: z.email().max(320), + password: z.string().min(10).max(128), + displayName: z.string().trim().min(2).max(120), + workspaceName: z.string().trim().min(2).max(160), +}) + +const loginSchema = z.object({ + email: z.email().max(320), + password: z.string().min(1).max(128), +}) +const sessionParams = z.object({ sessionId: z.uuid() }) +const changePasswordSchema = z.object({ + currentPassword: z.string().min(1).max(128), + newPassword: z.string().min(10).max(128), +}) +const emailActionRequestSchema = z.object({ email: z.email().max(320) }) +const confirmTokenSchema = z.object({ token: z.string().min(32).max(256) }) +const resetPasswordSchema = z.object({ + token: z.string().min(32).max(256), + newPassword: z.string().min(10).max(128), +}) + +function publicUser(user: { id: string; email: string; displayName: string; avatarKey?: string | null; emailVerifiedAt?: Date | null }) { + return { + id: user.id, + email: user.email, + displayName: user.displayName, + avatarKey: user.avatarKey ?? null, + emailVerified: Boolean(user.emailVerifiedAt), + } +} + +async function deliverAccountAction(request: FastifyRequest, input: { + user: { id: string; email: string; displayName: string } + type: AccountTokenType +}) { + const issued = await issueAccountToken(input.user.id, input.type) + const url = accountActionUrl(input.type, issued.token) + let sent = false + try { + const delivery = await sendAccountActionEmail({ + type: input.type, + to: input.user.email, + displayName: input.user.displayName, + url, + }) + sent = delivery.sent + } catch (error) { + request.log.error({ err: error, userId: input.user.id, type: input.type }, 'Account email delivery failed') + } + return { + sent, + ...(config.NODE_ENV !== 'production' ? { debugUrl: url } : {}), + } +} + +export async function authRoutes(app: FastifyInstance) { + app.post('/register', { + config: { rateLimit: { max: 5, timeWindow: '1 minute' } }, + }, async (request, reply) => { + const input = parseWith(registerSchema, request.body) + const email = input.email.trim().toLowerCase() + const [existing] = await db.select({ id: users.id }).from(users).where(eq(users.email, email)).limit(1) + if (existing) throw errors.conflict('An account with this email already exists') + + const passwordHash = await argon2.hash(input.password, { type: argon2.argon2id }) + const workspaceSlug = `${slugify(input.workspaceName)}-${crypto.randomUUID().slice(0, 6)}` + + const result = await db.transaction(async (tx) => { + const [user] = await tx.insert(users).values({ + email, + displayName: input.displayName, + passwordHash, + emailVerifiedAt: config.EMAIL_VERIFICATION_REQUIRED ? null : new Date(), + }).returning() + if (!user) throw new Error('Failed to create user') + + const [workspace] = await tx.insert(workspaces).values({ + name: input.workspaceName, + slug: workspaceSlug, + ownerId: user.id, + }).returning() + if (!workspace) throw new Error('Failed to create workspace') + + await tx.insert(memberships).values({ workspaceId: workspace.id, userId: user.id, role: 'OWNER' }) + return { user, workspace } + }) + + request.user = { + sub: result.user.id, + email: result.user.email, + displayName: result.user.displayName, + tokenType: 'access', + } + await audit({ + request, + workspaceId: result.workspace.id, + action: 'auth.register', + resourceType: 'user', + resourceId: result.user.id, + after: { email: result.user.email, workspaceId: result.workspace.id }, + }) + + if (config.EMAIL_VERIFICATION_REQUIRED) { + const delivery = await deliverAccountAction(request, { user: result.user, type: 'EMAIL_VERIFICATION' }) + return reply.code(201).send({ + verificationRequired: true, + emailSent: delivery.sent, + user: publicUser(result.user), + ...(delivery.debugUrl ? { debugVerificationUrl: delivery.debugUrl } : {}), + }) + } + + const meta = requestMeta(request) + const refresh = await createRefreshSession({ + userId: result.user.id, + ipAddress: meta.ipAddress, + ...(meta.userAgent ? { userAgent: meta.userAgent } : {}), + }) + reply.setCookie(REFRESH_COOKIE, refresh.token, refreshCookieOptions()) + + return reply.code(201).send({ + accessToken: signAccessToken(app, result.user), + user: publicUser(result.user), + workspaces: [{ id: result.workspace.id, name: result.workspace.name, slug: result.workspace.slug, role: 'OWNER' }], + }) + }) + + app.post('/login', { + config: { rateLimit: { max: 10, timeWindow: '1 minute' } }, + }, async (request, reply) => { + const input = parseWith(loginSchema, request.body) + const email = input.email.trim().toLowerCase() + const [user] = await db.select().from(users).where(eq(users.email, email)).limit(1) + if (!user || user.disabledAt || !(await argon2.verify(user.passwordHash, input.password))) { + throw errors.unauthorized('Email or password is incorrect') + } + if (config.EMAIL_VERIFICATION_REQUIRED && !user.emailVerifiedAt) throw errors.emailVerificationRequired() + + const meta = requestMeta(request) + const refresh = await createRefreshSession({ + userId: user.id, + ipAddress: meta.ipAddress, + ...(meta.userAgent ? { userAgent: meta.userAgent } : {}), + }) + reply.setCookie(REFRESH_COOKIE, refresh.token, refreshCookieOptions()) + + const workspaceRows = await db.select({ + id: workspaces.id, + name: workspaces.name, + slug: workspaces.slug, + role: memberships.role, + }).from(memberships).innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId)).where(eq(memberships.userId, user.id)) + + return { + accessToken: signAccessToken(app, user), + user: publicUser(user), + workspaces: workspaceRows, + } + }) + + app.post('/refresh', async (request, reply) => { + const current = request.cookies[REFRESH_COOKIE] + if (!current) throw errors.unauthorized('Refresh cookie is missing') + const meta = requestMeta(request) + const rotated = await rotateRefreshSession(current, { + ipAddress: meta.ipAddress, + ...(meta.userAgent ? { userAgent: meta.userAgent } : {}), + }) + reply.setCookie(REFRESH_COOKIE, rotated.token, refreshCookieOptions()) + const workspaceRows = await db.select({ + id: workspaces.id, + name: workspaces.name, + slug: workspaces.slug, + role: memberships.role, + }).from(memberships).innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId)).where(eq(memberships.userId, rotated.user.id)) + return { accessToken: signAccessToken(app, rotated.user), user: publicUser(rotated.user), workspaces: workspaceRows } + }) + + app.post('/logout', async (request, reply) => { + await revokeRefreshSession(request.cookies[REFRESH_COOKIE]) + reply.clearCookie(REFRESH_COOKIE, { path: '/api/v1/auth' }) + return reply.code(204).send() + }) + + app.post('/verify-email/request', { + config: { rateLimit: { max: 5, timeWindow: '10 minutes' } }, + }, async (request, reply) => { + const input = parseWith(emailActionRequestSchema, request.body) + const email = input.email.trim().toLowerCase() + const [user] = await db.select({ + id: users.id, + email: users.email, + displayName: users.displayName, + emailVerifiedAt: users.emailVerifiedAt, + disabledAt: users.disabledAt, + }).from(users).where(eq(users.email, email)).limit(1) + let debugVerificationUrl: string | undefined + if (user && !user.disabledAt && !user.emailVerifiedAt) { + const delivery = await deliverAccountAction(request, { user, type: 'EMAIL_VERIFICATION' }) + debugVerificationUrl = delivery.debugUrl + } + return reply.code(202).send({ + accepted: true, + message: 'If the account can be verified, an email has been sent', + ...(debugVerificationUrl ? { debugVerificationUrl } : {}), + }) + }) + + app.post('/verify-email/confirm', { + config: { rateLimit: { max: 10, timeWindow: '10 minutes' } }, + }, async (request) => { + const input = parseWith(confirmTokenSchema, request.body) + const now = new Date() + const result = await db.transaction(async (tx) => { + const tokenHash = hashToken(input.token) + const [row] = await tx.select({ token: accountActionTokens, user: users }).from(accountActionTokens) + .innerJoin(users, eq(users.id, accountActionTokens.userId)) + .where(and( + eq(accountActionTokens.tokenHash, tokenHash), + eq(accountActionTokens.type, 'EMAIL_VERIFICATION'), + isNull(accountActionTokens.consumedAt), + gt(accountActionTokens.expiresAt, now), + )).limit(1) + if (!row || row.user.disabledAt) throw errors.badRequest('验证链接无效或已过期') + const [consumed] = await tx.update(accountActionTokens).set({ consumedAt: now }).where(and( + eq(accountActionTokens.id, row.token.id), + isNull(accountActionTokens.consumedAt), + )).returning({ id: accountActionTokens.id }) + if (!consumed) throw errors.badRequest('验证链接无效或已过期') + const [user] = await tx.update(users).set({ emailVerifiedAt: row.user.emailVerifiedAt ?? now, updatedAt: now }) + .where(eq(users.id, row.user.id)).returning() + if (!user) throw errors.notFound('User') + return user + }) + await audit({ + request, + action: 'auth.email.verify', + resourceType: 'user', + resourceId: result.id, + after: { emailVerified: true }, + }) + return { verified: true, user: publicUser(result) } + }) + + app.post('/password/forgot', { + config: { rateLimit: { max: 5, timeWindow: '10 minutes' } }, + }, async (request, reply) => { + const input = parseWith(emailActionRequestSchema, request.body) + const email = input.email.trim().toLowerCase() + const [user] = await db.select({ + id: users.id, + email: users.email, + displayName: users.displayName, + disabledAt: users.disabledAt, + }).from(users).where(eq(users.email, email)).limit(1) + let debugResetUrl: string | undefined + if (user && !user.disabledAt) { + const delivery = await deliverAccountAction(request, { user, type: 'PASSWORD_RESET' }) + debugResetUrl = delivery.debugUrl + } + return reply.code(202).send({ + accepted: true, + message: 'If the account exists, a password reset email has been sent', + ...(debugResetUrl ? { debugResetUrl } : {}), + }) + }) + + app.post('/password/reset', { + config: { rateLimit: { max: 10, timeWindow: '10 minutes' } }, + }, async (request, reply) => { + const input = parseWith(resetPasswordSchema, request.body) + const now = new Date() + const passwordHash = await argon2.hash(input.newPassword, { type: argon2.argon2id }) + const result = await db.transaction(async (tx) => { + const tokenHash = hashToken(input.token) + const [row] = await tx.select({ token: accountActionTokens, user: users }).from(accountActionTokens) + .innerJoin(users, eq(users.id, accountActionTokens.userId)) + .where(and( + eq(accountActionTokens.tokenHash, tokenHash), + eq(accountActionTokens.type, 'PASSWORD_RESET'), + isNull(accountActionTokens.consumedAt), + gt(accountActionTokens.expiresAt, now), + )).limit(1) + if (!row || row.user.disabledAt) throw errors.badRequest('密码重置链接无效或已过期') + if (await argon2.verify(row.user.passwordHash, input.newPassword)) throw errors.conflict('新密码不能与当前密码相同') + const [consumed] = await tx.update(accountActionTokens).set({ consumedAt: now }).where(and( + eq(accountActionTokens.id, row.token.id), + isNull(accountActionTokens.consumedAt), + )).returning({ id: accountActionTokens.id }) + if (!consumed) throw errors.badRequest('密码重置链接无效或已过期') + await tx.update(users).set({ passwordHash, updatedAt: now }).where(eq(users.id, row.user.id)) + const revoked = await tx.update(refreshTokens).set({ revokedAt: now }).where(and( + eq(refreshTokens.userId, row.user.id), + isNull(refreshTokens.revokedAt), + )).returning({ id: refreshTokens.id }) + return { user: row.user, revokedSessionCount: revoked.length } + }) + reply.clearCookie(REFRESH_COOKIE, { path: '/api/v1/auth' }) + await audit({ + request, + action: 'auth.password.reset', + resourceType: 'user', + resourceId: result.user.id, + after: { revokedSessionCount: result.revokedSessionCount }, + }) + return reply.code(204).send() + }) + + app.get('/sessions', { preHandler: requireAuth }, async (request) => { + const currentHash = request.cookies[REFRESH_COOKIE] ? hashToken(request.cookies[REFRESH_COOKIE]) : null + const sessions = await db.select({ + id: refreshTokens.id, + tokenHash: refreshTokens.tokenHash, + userAgent: refreshTokens.userAgent, + ipAddress: refreshTokens.ipAddress, + createdAt: refreshTokens.createdAt, + expiresAt: refreshTokens.expiresAt, + }).from(refreshTokens).where(and( + eq(refreshTokens.userId, request.user.sub), + isNull(refreshTokens.revokedAt), + gt(refreshTokens.expiresAt, new Date()), + )).orderBy(desc(refreshTokens.createdAt)) + + return sessions.map(({ tokenHash, ...session }) => ({ + ...session, + current: currentHash === tokenHash, + })) + }) + + app.delete('/sessions/others', { preHandler: requireAuth }, async (request) => { + const currentHash = request.cookies[REFRESH_COOKIE] ? hashToken(request.cookies[REFRESH_COOKIE]) : null + const filters = [ + eq(refreshTokens.userId, request.user.sub), + isNull(refreshTokens.revokedAt), + gt(refreshTokens.expiresAt, new Date()), + ] + if (currentHash) filters.push(ne(refreshTokens.tokenHash, currentHash)) + const revoked = await db.update(refreshTokens).set({ revokedAt: new Date() }).where(and(...filters)).returning({ id: refreshTokens.id }) + await audit({ + request, + action: 'auth.sessions.revoke_others', + resourceType: 'user', + resourceId: request.user.sub, + after: { revokedCount: revoked.length }, + }) + return { revoked: revoked.length } + }) + + app.delete('/sessions/:sessionId', { preHandler: requireAuth }, async (request, reply) => { + const { sessionId } = parseWith(sessionParams, request.params) + const [session] = await db.select().from(refreshTokens).where(and( + eq(refreshTokens.id, sessionId), + eq(refreshTokens.userId, request.user.sub), + )).limit(1) + if (!session) throw errors.notFound('Session') + if (!session.revokedAt) await db.update(refreshTokens).set({ revokedAt: new Date() }).where(eq(refreshTokens.id, session.id)) + + const current = request.cookies[REFRESH_COOKIE] + if (current && hashToken(current) === session.tokenHash) reply.clearCookie(REFRESH_COOKIE, { path: '/api/v1/auth' }) + await audit({ + request, + action: 'auth.session.revoke', + resourceType: 'refresh_session', + resourceId: session.id, + before: { revoked: Boolean(session.revokedAt) }, + after: { revoked: true }, + }) + return reply.code(204).send() + }) + + app.patch('/password', { + preHandler: requireAuth, + config: { rateLimit: { max: 5, timeWindow: '1 minute' } }, + }, async (request, reply) => { + const input = parseWith(changePasswordSchema, request.body) + const [user] = await db.select().from(users).where(eq(users.id, request.user.sub)).limit(1) + if (!user || user.disabledAt) throw errors.unauthorized('Account is unavailable') + if (!(await argon2.verify(user.passwordHash, input.currentPassword))) throw errors.unauthorized('Current password is incorrect') + if (await argon2.verify(user.passwordHash, input.newPassword)) throw errors.conflict('New password must be different from the current password') + + const passwordHash = await argon2.hash(input.newPassword, { type: argon2.argon2id }) + const revokedAt = new Date() + const revokedCount = await db.transaction(async (tx) => { + await tx.update(users).set({ passwordHash, updatedAt: revokedAt }).where(eq(users.id, user.id)) + const revoked = await tx.update(refreshTokens).set({ revokedAt }).where(and( + eq(refreshTokens.userId, user.id), + isNull(refreshTokens.revokedAt), + )).returning({ id: refreshTokens.id }) + return revoked.length + }) + reply.clearCookie(REFRESH_COOKIE, { path: '/api/v1/auth' }) + await audit({ + request, + action: 'auth.password.change', + resourceType: 'user', + resourceId: user.id, + after: { revokedSessionCount: revokedCount }, + }) + return reply.code(204).send() + }) + + app.get('/me', { preHandler: requireAuth }, async (request) => { + const [user] = await db.select({ + id: users.id, + email: users.email, + displayName: users.displayName, + avatarKey: users.avatarKey, + emailVerifiedAt: users.emailVerifiedAt, + }).from(users).where(and(eq(users.id, request.user.sub))).limit(1) + if (!user) throw errors.notFound('User') + + const workspaceRows = await db.select({ + id: workspaces.id, + name: workspaces.name, + slug: workspaces.slug, + plan: workspaces.plan, + role: memberships.role, + }).from(memberships).innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId)).where(eq(memberships.userId, user.id)) + + return { user: publicUser(user), workspaces: workspaceRows } + }) +} diff --git a/server/src/routes/billing.integration.test.ts b/server/src/routes/billing.integration.test.ts new file mode 100644 index 0000000..ba316b1 --- /dev/null +++ b/server/src/routes/billing.integration.test.ts @@ -0,0 +1,355 @@ +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import type Stripe from 'stripe' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { + billingSubscriptions, + billingWebhookEvents, + users, + workspaces, +} from '../db/schema.js' +import type { + BillingProviderReadiness, + StripeBillingProvider, +} from '../lib/stripe-billing.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +function subscription(input: { + id?: string + customerId?: string + workspaceId: string + priceId?: string + status?: Stripe.Subscription.Status + periodEnd?: number + cancelAtPeriodEnd?: boolean +}) { + return { + id: input.id ?? 'sub_frameflow', + object: 'subscription', + customer: input.customerId ?? 'cus_frameflow', + metadata: { frameflowWorkspaceId: input.workspaceId }, + status: input.status ?? 'active', + cancel_at_period_end: input.cancelAtPeriodEnd ?? false, + items: { + data: [{ + price: { id: input.priceId ?? 'price_studio' }, + current_period_end: input.periodEnd ?? 1_800_000_000, + }], + }, + } as unknown as Stripe.Subscription +} + +function stripeEvent(input: { + id: string + type: Stripe.Event.Type + object: object + created: number +}) { + return { + id: input.id, + object: 'event', + api_version: null, + created: input.created, + data: { object: input.object }, + livemode: false, + pending_webhooks: 1, + request: null, + type: input.type, + } as unknown as Stripe.Event +} + +class FakeStripeBillingProvider implements StripeBillingProvider { + readonly name = 'stripe' as const + configured = true + customerCalls: Array> = [] + checkoutCalls: Array> = [] + portalCalls: Array> = [] + retrieveCalls: string[] = [] + subscriptions = new Map() + + readiness(): BillingProviderReadiness { + const missingRequirements = this.configured ? [] : ['STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'] + return { + provider: 'stripe', + status: this.configured ? 'CONFIGURED' : 'NOT_CONFIGURED', + portalConfigured: this.configured, + webhookConfigured: this.configured, + missingRequirements, + plans: { + PRO: { checkoutAvailable: this.configured, missingRequirements }, + STUDIO: { checkoutAvailable: this.configured, missingRequirements }, + }, + } + } + + planForPriceId(priceId: string) { + if (priceId === 'price_pro') return 'PRO' as const + if (priceId === 'price_studio') return 'STUDIO' as const + return null + } + + async createCustomer(input: { + workspaceId: string + workspaceName: string + email: string + displayName: string + }) { + this.customerCalls.push(input) + return { id: 'cus_frameflow' } + } + + async createCheckoutSession(input: { + workspaceId: string + customerId: string + plan: 'PRO' | 'STUDIO' + idempotencyKey: string + }) { + this.checkoutCalls.push(input) + return { id: `cs_${this.checkoutCalls.length}`, url: 'https://checkout.stripe.test/session' } + } + + async createPortalSession(input: { customerId: string }) { + this.portalCalls.push(input) + return { id: 'bps_frameflow', url: 'https://billing.stripe.test/portal' } + } + + constructWebhookEvent(payload: Buffer, signature: string) { + if (signature !== 'valid-signature') throw new Error('invalid signature') + return JSON.parse(payload.toString('utf8')) as Stripe.Event + } + + async retrieveSubscription(subscriptionId: string) { + this.retrieveCalls.push(subscriptionId) + const row = this.subscriptions.get(subscriptionId) + if (!row) throw new Error(`Missing fake subscription ${subscriptionId}`) + return row + } +} + +describe.sequential('Stripe workspace billing', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + const eventIds: string[] = [] + const provider = new FakeStripeBillingProvider() + + async function inject(token: string | null, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: token ? { authorization: `Bearer ${token}` } : undefined, + payload, + }) + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + async function sendWebhook(event: Stripe.Event, signature = 'valid-signature') { + eventIds.push(event.id) + return app.inject({ + method: 'POST', + url: '/api/v1/billing/webhooks/stripe', + headers: { + 'content-type': 'application/json', + 'stripe-signature': signature, + }, + payload: JSON.stringify(event), + }) + } + + beforeAll(async () => { + app = await buildApp({ billingProvider: provider }) + owner = await registerAccount('billing-owner') + viewer = await registerAccount('billing-viewer') + workspaceId = owner.workspaces[0].id + const memberResponse = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + expect(memberResponse.statusCode, memberResponse.body).toBe(201) + }) + + afterAll(async () => { + if (eventIds.length) await db.delete(billingWebhookEvents).where(inArray(billingWebhookEvents.eventId, eventIds)) + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('reports provider and plan availability without exposing Stripe identifiers', async () => { + const response = await inject(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/billing/summary`) + expect(response.statusCode, response.body).toBe(200) + const summary = response.json() + expect(summary.canManage).toBe(true) + expect(summary.provider).toMatchObject({ name: 'stripe', status: 'CONFIGURED', configured: true }) + expect(summary.plans).toEqual(expect.arrayContaining([ + expect.objectContaining({ id: 'PRO', monthlyCreditLimit: 10_000, checkoutAvailable: true }), + expect.objectContaining({ id: 'STUDIO', monthlyCreditLimit: 50_000, checkoutAvailable: true }), + expect.objectContaining({ id: 'ENTERPRISE', checkoutAvailable: false }), + ])) + expect(summary.subscription).toBeNull() + expect(response.body).not.toContain('price_studio') + }) + + it('requires billing management permission and reports missing provider configuration', async () => { + const forbidden = await inject(viewer.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/checkout`, { + plan: 'STUDIO', + requestId: crypto.randomUUID(), + }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + provider.configured = false + const unavailable = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/checkout`, { + plan: 'STUDIO', + requestId: crypto.randomUUID(), + }) + expect(unavailable.statusCode, unavailable.body).toBe(503) + expect(unavailable.json().error.details.missingRequirements).toContain('STRIPE_SECRET_KEY') + provider.configured = true + }) + + it('creates one customer, reuses it, and sends stable Checkout idempotency keys', async () => { + const firstRequestId = crypto.randomUUID() + const first = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/checkout`, { + plan: 'STUDIO', + requestId: firstRequestId, + }) + expect(first.statusCode, first.body).toBe(200) + expect(first.json().url).toBe('https://checkout.stripe.test/session') + + const second = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/checkout`, { + plan: 'PRO', + requestId: crypto.randomUUID(), + }) + expect(second.statusCode, second.body).toBe(200) + expect(provider.customerCalls).toHaveLength(1) + expect(provider.customerCalls[0]).toMatchObject({ workspaceId, email: owner.user.email }) + expect(provider.checkoutCalls).toHaveLength(2) + expect(provider.checkoutCalls[0]).toMatchObject({ + workspaceId, + customerId: 'cus_frameflow', + plan: 'STUDIO', + idempotencyKey: `frameflow-checkout:${workspaceId}:${firstRequestId}`, + }) + }) + + it('verifies, deduplicates, and applies subscription webhooks atomically', async () => { + const invalidEvent = stripeEvent({ + id: 'evt_invalid_signature', + type: 'checkout.session.completed', + created: 1_799_999_900, + object: { mode: 'subscription', subscription: 'sub_frameflow' }, + }) + const invalid = await sendWebhook(invalidEvent, 'invalid-signature') + expect(invalid.statusCode, invalid.body).toBe(400) + + provider.subscriptions.set('sub_frameflow', subscription({ workspaceId })) + const event = stripeEvent({ + id: 'evt_checkout_completed', + type: 'checkout.session.completed', + created: 1_800_000_000, + object: { mode: 'subscription', subscription: 'sub_frameflow' }, + }) + const applied = await sendWebhook(event) + expect(applied.statusCode, applied.body).toBe(200) + expect(applied.json()).toEqual({ received: true, duplicate: false }) + + const duplicate = await sendWebhook(event) + expect(duplicate.statusCode, duplicate.body).toBe(200) + expect(duplicate.json()).toEqual({ received: true, duplicate: true }) + expect(provider.retrieveCalls.filter((id) => id === 'sub_frameflow')).toHaveLength(1) + + const [workspace] = await db.select().from(workspaces).where(eq(workspaces.id, workspaceId)).limit(1) + const [billing] = await db.select().from(billingSubscriptions).where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1) + expect(workspace).toMatchObject({ plan: 'STUDIO', monthlyCreditLimit: 50_000 }) + expect(billing).toMatchObject({ + customerId: 'cus_frameflow', + subscriptionId: 'sub_frameflow', + priceId: 'price_studio', + plan: 'STUDIO', + status: 'active', + cancelAtPeriodEnd: false, + }) + }) + + it('routes active subscribers to the portal and blocks a second subscription', async () => { + const duplicateCheckout = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/checkout`, { + plan: 'PRO', + requestId: crypto.randomUUID(), + }) + expect(duplicateCheckout.statusCode, duplicateCheckout.body).toBe(409) + + const portal = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/billing/portal`) + expect(portal.statusCode, portal.body).toBe(200) + expect(portal.json().url).toBe('https://billing.stripe.test/portal') + expect(provider.portalCalls).toEqual([{ customerId: 'cus_frameflow' }]) + }) + + it('downgrades canceled subscriptions and ignores older deliveries', async () => { + const cancelled = subscription({ + workspaceId, + status: 'canceled', + cancelAtPeriodEnd: true, + periodEnd: 1_800_100_000, + }) + const deletedEvent = stripeEvent({ + id: 'evt_subscription_deleted', + type: 'customer.subscription.deleted', + created: 1_800_000_200, + object: cancelled, + }) + const deleted = await sendWebhook(deletedEvent) + expect(deleted.statusCode, deleted.body).toBe(200) + + provider.subscriptions.set('sub_frameflow', subscription({ workspaceId, status: 'active' })) + const staleEvent = stripeEvent({ + id: 'evt_subscription_stale', + type: 'customer.subscription.updated', + created: 1_800_000_100, + object: subscription({ workspaceId, status: 'active' }), + }) + const stale = await sendWebhook(staleEvent) + expect(stale.statusCode, stale.body).toBe(200) + + const [workspace] = await db.select().from(workspaces).where(eq(workspaces.id, workspaceId)).limit(1) + const [billing] = await db.select().from(billingSubscriptions).where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1) + expect(workspace).toMatchObject({ plan: 'PRO', monthlyCreditLimit: 10_000 }) + expect(billing).toMatchObject({ status: 'canceled', plan: 'STUDIO', cancelAtPeriodEnd: true }) + + const summaryResponse = await inject(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/billing/summary`) + expect(summaryResponse.statusCode, summaryResponse.body).toBe(200) + expect(summaryResponse.json().subscription).toMatchObject({ + status: 'canceled', + plan: 'STUDIO', + hasSubscription: true, + cancelAtPeriodEnd: true, + }) + }) +}) diff --git a/server/src/routes/billing.ts b/server/src/routes/billing.ts new file mode 100644 index 0000000..e2081cc --- /dev/null +++ b/server/src/routes/billing.ts @@ -0,0 +1,320 @@ +import type { FastifyInstance } from 'fastify' +import { and, eq, or, sql } from 'drizzle-orm' +import type Stripe from 'stripe' +import { z } from 'zod' +import { db } from '../db/client.js' +import { + billingSubscriptions, + billingWebhookEvents, + users, + workspaces, +} from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { workspaceBillingSummary } from '../lib/billing.js' +import { + DEFAULT_BILLING_PLAN, + planCreditLimit, + type PurchasableBillingPlan, +} from '../lib/billing-plans.js' +import { AppError, errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { can, requireWorkspacePermission } from '../lib/permissions.js' +import { + createStripeBillingProvider, + type StripeBillingProvider, +} from '../lib/stripe-billing.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const checkoutBody = z.object({ + plan: z.enum(['PRO', 'STUDIO']), + requestId: z.uuid(), +}) +const terminalSubscriptionStatuses = new Set(['canceled', 'incomplete_expired']) +const entitledSubscriptionStatuses = new Set(['active', 'trialing', 'past_due']) + +interface BillingRouteOptions { + billingProvider?: StripeBillingProvider +} + +function stripeObjectId(value: string | { id: string } | null) { + return typeof value === 'string' ? value : value?.id ?? null +} + +function subscriptionSnapshot(provider: StripeBillingProvider, subscription: Stripe.Subscription) { + const item = subscription.items.data.find((candidate) => provider.planForPriceId(candidate.price.id)) + ?? subscription.items.data[0] + const priceId = item?.price.id ?? null + return { + customerId: stripeObjectId(subscription.customer), + subscriptionId: subscription.id, + priceId, + plan: priceId ? provider.planForPriceId(priceId) : null, + status: subscription.status, + currentPeriodEnd: item?.current_period_end ? new Date(item.current_period_end * 1000) : null, + cancelAtPeriodEnd: subscription.cancel_at_period_end, + } +} + +function metadataWorkspaceId(subscription: Stripe.Subscription) { + const parsed = z.uuid().safeParse(subscription.metadata.frameflowWorkspaceId) + return parsed.success ? parsed.data : null +} + +async function ensureBillingCustomer(provider: StripeBillingProvider, workspaceId: string) { + return db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`billing-customer:${workspaceId}`}))`) + const [existing] = await tx.select().from(billingSubscriptions) + .where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1) + if (existing) return existing + + const [workspace] = await tx.select({ + id: workspaces.id, + name: workspaces.name, + ownerEmail: users.email, + ownerDisplayName: users.displayName, + }).from(workspaces) + .innerJoin(users, eq(users.id, workspaces.ownerId)) + .where(eq(workspaces.id, workspaceId)).limit(1) + if (!workspace) throw errors.notFound('Workspace') + + const customer = await provider.createCustomer({ + workspaceId, + workspaceName: workspace.name, + email: workspace.ownerEmail, + displayName: workspace.ownerDisplayName, + }) + const [created] = await tx.insert(billingSubscriptions).values({ + workspaceId, + provider: provider.name, + customerId: customer.id, + }).returning() + if (!created) throw new Error('Failed to persist billing customer') + return created + }) +} + +async function existingWebhookEvent(eventId: string) { + const [existing] = await db.select({ eventId: billingWebhookEvents.eventId }) + .from(billingWebhookEvents).where(eq(billingWebhookEvents.eventId, eventId)).limit(1) + return Boolean(existing) +} + +async function subscriptionFromEvent(provider: StripeBillingProvider, event: Stripe.Event) { + if (event.type === 'checkout.session.completed') { + const session = event.data.object as Stripe.Checkout.Session + if (session.mode !== 'subscription') return null + const subscriptionId = stripeObjectId(session.subscription) + return subscriptionId ? provider.retrieveSubscription(subscriptionId) : null + } + if (event.type === 'customer.subscription.created' + || event.type === 'customer.subscription.updated' + || event.type === 'customer.subscription.deleted') { + const eventSubscription = event.data.object as Stripe.Subscription + if (event.type === 'customer.subscription.deleted') return eventSubscription + return provider.retrieveSubscription(eventSubscription.id) + } + return null +} + +export async function processStripeWebhookEvent(provider: StripeBillingProvider, event: Stripe.Event) { + if (await existingWebhookEvent(event.id)) return { duplicate: true, workspaceId: null, subscription: null } + const subscription = await subscriptionFromEvent(provider, event) + const snapshot = subscription ? subscriptionSnapshot(provider, subscription) : null + const eventCreatedAt = new Date(event.created * 1000) + + return db.transaction(async (tx) => { + const [inserted] = await tx.insert(billingWebhookEvents).values({ + eventId: event.id, + provider: provider.name, + eventType: event.type, + livemode: event.livemode, + providerCreatedAt: eventCreatedAt, + }).onConflictDoNothing().returning({ eventId: billingWebhookEvents.eventId }) + if (!inserted) return { duplicate: true, workspaceId: null, subscription: null } + if (!subscription || !snapshot?.customerId) { + return { duplicate: false, workspaceId: null, subscription: null } + } + + const metadataId = metadataWorkspaceId(subscription) + let [account] = await tx.select().from(billingSubscriptions).where(or( + eq(billingSubscriptions.customerId, snapshot.customerId), + eq(billingSubscriptions.subscriptionId, snapshot.subscriptionId), + )).limit(1) + if (!account && metadataId) { + ;[account] = await tx.select().from(billingSubscriptions) + .where(eq(billingSubscriptions.workspaceId, metadataId)).limit(1) + } + + let workspaceId = account?.workspaceId ?? metadataId + if (!workspaceId) return { duplicate: false, workspaceId: null, subscription: null } + const [workspace] = await tx.select({ id: workspaces.id }).from(workspaces) + .where(eq(workspaces.id, workspaceId)).limit(1) + if (!workspace) return { duplicate: false, workspaceId: null, subscription: null } + + if (account && account.customerId !== snapshot.customerId) { + throw errors.conflict('Stripe customer does not match the workspace billing account') + } + if (account?.lastEventCreatedAt && account.lastEventCreatedAt > eventCreatedAt) { + await tx.update(billingWebhookEvents).set({ workspaceId }).where(eq(billingWebhookEvents.eventId, event.id)) + return { duplicate: false, workspaceId, subscription: null } + } + + const subscriptionValues = { + provider: provider.name, + customerId: snapshot.customerId, + subscriptionId: snapshot.subscriptionId, + priceId: snapshot.priceId, + plan: snapshot.plan, + status: snapshot.status, + currentPeriodEnd: snapshot.currentPeriodEnd, + cancelAtPeriodEnd: snapshot.cancelAtPeriodEnd, + lastEventCreatedAt: eventCreatedAt, + updatedAt: new Date(), + } + if (account) { + await tx.update(billingSubscriptions).set(subscriptionValues) + .where(eq(billingSubscriptions.id, account.id)) + } else { + const [created] = await tx.insert(billingSubscriptions).values({ + workspaceId, + ...subscriptionValues, + }).returning() + if (!created) throw new Error('Failed to persist Stripe subscription') + account = created + } + + let appliedPlan: string | null = null + if (snapshot.plan && entitledSubscriptionStatuses.has(snapshot.status)) { + appliedPlan = snapshot.plan + await tx.update(workspaces).set({ + plan: snapshot.plan, + monthlyCreditLimit: planCreditLimit(snapshot.plan), + updatedAt: new Date(), + }).where(eq(workspaces.id, workspaceId)) + } else if (!entitledSubscriptionStatuses.has(snapshot.status)) { + appliedPlan = DEFAULT_BILLING_PLAN + await tx.update(workspaces).set({ + plan: DEFAULT_BILLING_PLAN, + monthlyCreditLimit: planCreditLimit(DEFAULT_BILLING_PLAN), + updatedAt: new Date(), + }).where(eq(workspaces.id, workspaceId)) + } + + await tx.update(billingWebhookEvents).set({ workspaceId }) + .where(eq(billingWebhookEvents.eventId, event.id)) + return { + duplicate: false, + workspaceId, + subscription: { + id: snapshot.subscriptionId, + status: snapshot.status, + plan: snapshot.plan, + appliedPlan, + }, + } + }) +} + +export async function billingRoutes(app: FastifyInstance, options: BillingRouteOptions) { + const provider = options.billingProvider ?? createStripeBillingProvider() + + app.get('/workspaces/:workspaceId/billing/summary', { preHandler: requireAuth }, async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const membership = await requireWorkspacePermission(request, workspaceId, 'billing:read') + const summary = await workspaceBillingSummary(workspaceId, { + providerReadiness: provider.readiness(), + canManage: can(membership.role, 'billing:manage'), + }) + if (!summary) throw errors.notFound('Workspace') + return summary + }) + + app.post('/workspaces/:workspaceId/billing/checkout', { preHandler: requireAuth }, async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(checkoutBody, request.body) + await requireWorkspacePermission(request, workspaceId, 'billing:manage') + const planReadiness = provider.readiness().plans[input.plan] + if (!planReadiness.checkoutAvailable) { + throw errors.serviceUnavailable(`${input.plan} checkout is not configured`, { + missingRequirements: planReadiness.missingRequirements, + }) + } + + const [existing] = await db.select().from(billingSubscriptions) + .where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1) + if (existing?.subscriptionId && !terminalSubscriptionStatuses.has(existing.status)) { + throw errors.conflict('当前工作室已有 Stripe 订阅,请通过客户门户管理') + } + const account = existing ?? await ensureBillingCustomer(provider, workspaceId) + const session = await provider.createCheckoutSession({ + workspaceId, + customerId: account.customerId, + plan: input.plan, + idempotencyKey: `frameflow-checkout:${workspaceId}:${input.requestId}`, + }) + await audit({ + request, + workspaceId, + action: 'billing.checkout.create', + resourceType: 'billing_subscription', + after: { plan: input.plan, checkoutSessionId: session.id }, + }) + return { url: session.url } + }) + + app.post('/workspaces/:workspaceId/billing/portal', { preHandler: requireAuth }, async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'billing:manage') + if (!provider.readiness().portalConfigured) { + throw errors.serviceUnavailable('Stripe customer portal is not configured', { + missingRequirements: ['STRIPE_SECRET_KEY'], + }) + } + const [account] = await db.select().from(billingSubscriptions) + .where(eq(billingSubscriptions.workspaceId, workspaceId)).limit(1) + if (!account) throw errors.conflict('当前工作室还没有 Stripe 账单账户') + const session = await provider.createPortalSession({ customerId: account.customerId }) + await audit({ + request, + workspaceId, + action: 'billing.portal.create', + resourceType: 'billing_subscription', + after: { portalSessionId: session.id }, + }) + return { url: session.url } + }) + + app.post('/billing/webhooks/stripe', { + bodyLimit: 1024 * 1024, + config: { rawBody: true, rateLimit: { max: 300, timeWindow: '1 minute' } }, + }, async (request) => { + if (!provider.readiness().webhookConfigured) { + throw errors.serviceUnavailable('Stripe webhooks are not configured', { + missingRequirements: ['STRIPE_SECRET_KEY', 'STRIPE_WEBHOOK_SECRET'], + }) + } + const signature = request.headers['stripe-signature'] + if (typeof signature !== 'string' || !Buffer.isBuffer(request.rawBody)) { + throw errors.badRequest('Stripe signature and raw request body are required') + } + let event: Stripe.Event + try { + event = provider.constructWebhookEvent(request.rawBody, signature) + } catch (error) { + if (error instanceof AppError) throw error + throw errors.badRequest('Stripe webhook signature is invalid') + } + const result = await processStripeWebhookEvent(provider, event) + if (!result.duplicate && result.workspaceId) { + await audit({ + request, + workspaceId: result.workspaceId, + action: 'billing.webhook.process', + resourceType: 'billing_subscription', + after: { eventId: event.id, eventType: event.type, subscription: result.subscription }, + }) + } + return { received: true, duplicate: result.duplicate } + }) +} diff --git a/server/src/routes/episodes.ts b/server/src/routes/episodes.ts new file mode 100644 index 0000000..9e82793 --- /dev/null +++ b/server/src/routes/episodes.ts @@ -0,0 +1,142 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq, sql } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { episodes, projects, scriptVersions, shots } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission } from '../lib/permissions.js' + +const projectParams = z.object({ projectId: z.uuid() }) +const episodeParams = z.object({ episodeId: z.uuid() }) +const scriptVersionParams = z.object({ episodeId: z.uuid(), versionId: z.uuid() }) +const createEpisodeSchema = z.object({ + episodeNumber: z.number().int().positive(), + title: z.string().trim().min(1).max(200), + synopsis: z.string().max(4000).default(''), + targetDurationSeconds: z.number().int().min(15).max(3600).default(180), +}) +const updateEpisodeSchema = createEpisodeSchema.omit({ episodeNumber: true }).partial().extend({ + status: z.enum(['OUTLINE', 'SCRIPTING', 'STORYBOARDING', 'PRODUCTION', 'REVIEW', 'PUBLISHED']).optional(), +}) +const scriptSchema = z.object({ + title: z.string().trim().min(1).max(200), + content: z.record(z.string(), z.unknown()), + plainText: z.string().max(500000), + changeSummary: z.string().max(1000).default('手动保存'), +}) + +async function episodeProject(episodeId: string) { + const [row] = await db.select({ episode: episodes, project: projects }).from(episodes).innerJoin(projects, eq(projects.id, episodes.projectId)).where(eq(episodes.id, episodeId)).limit(1) + if (!row) throw errors.notFound('Episode') + return row +} + +export async function episodeRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/projects/:projectId/episodes', async (request) => { + const { projectId } = parseWith(projectParams, request.params) + await requireProjectPermission(request, projectId, 'project:read') + return db.select().from(episodes).where(eq(episodes.projectId, projectId)).orderBy(episodes.episodeNumber) + }) + + app.post('/projects/:projectId/episodes', async (request, reply) => { + const { projectId } = parseWith(projectParams, request.params) + const input = parseWith(createEpisodeSchema, request.body) + const { project } = await requireProjectPermission(request, projectId, 'content:write') + const [episode] = await db.insert(episodes).values({ + projectId, + createdById: request.user.sub, + ...input, + status: 'OUTLINE', + }).returning() + if (!episode) throw new Error('Failed to create episode') + await audit({ request, workspaceId: project.workspaceId, action: 'episode.create', resourceType: 'episode', resourceId: episode.id, after: episode }) + return reply.code(201).send(episode) + }) + + app.get('/episodes/:episodeId', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + const [currentScript] = await db.select().from(scriptVersions).where(and(eq(scriptVersions.episodeId, episodeId), eq(scriptVersions.isCurrent, true))).limit(1) + const shotRows = await db.select().from(shots).where(eq(shots.episodeId, episodeId)).orderBy(shots.sortOrder) + return { ...row.episode, currentScript: currentScript ?? null, shots: shotRows } + }) + + app.patch('/episodes/:episodeId', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(updateEpisodeSchema, request.body) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'content:write') + const [updated] = await db.update(episodes).set({ ...input, updatedAt: new Date() }).where(eq(episodes.id, episodeId)).returning() + if (!updated) throw errors.notFound('Episode') + await audit({ request, workspaceId: row.project.workspaceId, action: 'episode.update', resourceType: 'episode', resourceId: episodeId, before: row.episode, after: updated }) + return updated + }) + + app.get('/episodes/:episodeId/scripts', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + return db.select().from(scriptVersions).where(eq(scriptVersions.episodeId, episodeId)).orderBy(desc(scriptVersions.version)) + }) + + app.post('/episodes/:episodeId/scripts', async (request, reply) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(scriptSchema, request.body) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'content:write') + + const created = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`script:${episodeId}`}))`) + const [latest] = await tx.select({ version: scriptVersions.version }).from(scriptVersions).where(eq(scriptVersions.episodeId, episodeId)).orderBy(desc(scriptVersions.version)).limit(1) + await tx.update(scriptVersions).set({ isCurrent: false }).where(eq(scriptVersions.episodeId, episodeId)) + const [version] = await tx.insert(scriptVersions).values({ + episodeId, + version: (latest?.version ?? 0) + 1, + title: input.title, + content: input.content, + plainText: input.plainText, + changeSummary: input.changeSummary, + isCurrent: true, + createdById: request.user.sub, + }).returning() + return version + }) + if (!created) throw new Error('Failed to create script version') + await audit({ request, workspaceId: row.project.workspaceId, action: 'script.version.create', resourceType: 'script_version', resourceId: created.id, after: { episodeId, version: created.version } }) + return reply.code(201).send(created) + }) + + app.post('/episodes/:episodeId/scripts/:versionId/activate', async (request) => { + const { episodeId, versionId } = parseWith(scriptVersionParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'content:write') + + const result = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`script:${episodeId}`}))`) + const [version] = await tx.select().from(scriptVersions).where(and( + eq(scriptVersions.id, versionId), + eq(scriptVersions.episodeId, episodeId), + )).limit(1) + if (!version) throw errors.notFound('Script version') + if (version.isCurrent) return { version, changed: false } + await tx.update(scriptVersions).set({ isCurrent: false }).where(eq(scriptVersions.episodeId, episodeId)) + const [activated] = await tx.update(scriptVersions).set({ isCurrent: true }).where(and( + eq(scriptVersions.id, versionId), + eq(scriptVersions.episodeId, episodeId), + )).returning() + if (!activated) throw errors.notFound('Script version') + return { version: activated, changed: true } + }) + + if (result.changed) { + await audit({ request, workspaceId: row.project.workspaceId, action: 'script.version.activate', resourceType: 'script_version', resourceId: versionId, after: { episodeId, version: result.version.version } }) + } + return result.version + }) +} diff --git a/server/src/routes/jobs.integration.test.ts b/server/src/routes/jobs.integration.test.ts new file mode 100644 index 0000000..ae128c0 --- /dev/null +++ b/server/src/routes/jobs.integration.test.ts @@ -0,0 +1,138 @@ +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { generationJobs, users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('generation job lifecycle', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: { authorization: `Bearer ${token}` }, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + async function persistJob(status: 'QUEUED' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED') { + const [job] = await db.insert(generationJobs).values({ + workspaceId, + projectId, + createdById: owner.user.id, + type: 'PIPELINE_HEALTHCHECK', + status, + progress: status === 'SUCCEEDED' ? 100 : 0, + idempotencyKey: `job-lifecycle-${crypto.randomUUID()}`, + input: { probe: 'job-lifecycle-test' }, + attempts: status === 'FAILED' ? 3 : 0, + maxAttempts: 3, + estimatedCredits: '0', + completedAt: ['SUCCEEDED', 'FAILED', 'CANCELLED'].includes(status) ? new Date() : null, + }).returning() + if (!job) throw new Error('Failed to create test job') + return job + } + + beforeAll(async () => { + app = await buildApp() + owner = await registerAccount('job-owner') + viewer = await registerAccount('job-viewer') + workspaceId = owner.workspaces[0].id + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '任务生命周期测试项目', + logline: '验证取消、重试和任务权限。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + }) + + afterAll(async () => { + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('cancels a queued task while preserving its record', async () => { + const job = await persistJob('QUEUED') + const cancelled = await request(owner.accessToken, 'DELETE', `/api/v1/jobs/${job.id}`) + expect(cancelled.status).toBe('CANCELLED') + expect(cancelled.completedAt).toBeTruthy() + + const [persisted] = await db.select().from(generationJobs).where(eq(generationJobs.id, job.id)).limit(1) + expect(persisted?.status).toBe('CANCELLED') + }) + + it('retries a failed task as a new record and keeps the source immutable', async () => { + const failed = await persistJob('FAILED') + const response = await inject(owner.accessToken, 'POST', `/api/v1/jobs/${failed.id}/retry`) + expect(response.statusCode, response.body).toBe(202) + const result = response.json() + expect(result.sourceJobId).toBe(failed.id) + expect(result.job.id).not.toBe(failed.id) + expect(result.job.input.retryOfJobId).toBe(failed.id) + expect(result.job.input.probe).toBe('job-lifecycle-test') + + const [source] = await db.select().from(generationJobs).where(eq(generationJobs.id, failed.id)).limit(1) + expect(source?.status).toBe('FAILED') + }) + + it('rejects invalid state transitions and read-only members', async () => { + const succeeded = await persistJob('SUCCEEDED') + const cancelSucceeded = await inject(owner.accessToken, 'DELETE', `/api/v1/jobs/${succeeded.id}`) + expect(cancelSucceeded.statusCode, cancelSucceeded.body).toBe(409) + const retrySucceeded = await inject(owner.accessToken, 'POST', `/api/v1/jobs/${succeeded.id}/retry`) + expect(retrySucceeded.statusCode, retrySucceeded.body).toBe(409) + + const failed = await persistJob('FAILED') + const forbiddenRetry = await inject(viewer.accessToken, 'POST', `/api/v1/jobs/${failed.id}/retry`) + expect(forbiddenRetry.statusCode, forbiddenRetry.body).toBe(403) + const queued = await persistJob('QUEUED') + const forbiddenCancel = await inject(viewer.accessToken, 'DELETE', `/api/v1/jobs/${queued.id}`) + expect(forbiddenCancel.statusCode, forbiddenCancel.body).toBe(403) + }) +}) diff --git a/server/src/routes/jobs.ts b/server/src/routes/jobs.ts new file mode 100644 index 0000000..7bddd78 --- /dev/null +++ b/server/src/routes/jobs.ts @@ -0,0 +1,142 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { deliveries, generationJobs } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission, requireWorkspacePermission, type Permission } from '../lib/permissions.js' +import { publishRealtimeEvent } from '../lib/realtime.js' +import { enqueueGeneration, generationQueue } from '../queue/client.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const projectParams = z.object({ projectId: z.uuid() }) +const jobParams = z.object({ jobId: z.uuid() }) +const listQuery = z.object({ + status: z.enum(['QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED']).optional(), + type: z.enum(['PIPELINE_HEALTHCHECK', 'SCRIPT_GENERATE', 'STORYBOARD_GENERATE', 'ASSET_GENERATE', 'TTS_GENERATE', 'VIDEO_GENERATE', 'LIPSYNC_GENERATE', 'EPISODE_RENDER', 'DELIVERY_PUBLISH']).optional(), +}) +const createJobSchema = z.object({ + type: z.enum(['PIPELINE_HEALTHCHECK', 'SCRIPT_GENERATE', 'STORYBOARD_GENERATE', 'ASSET_GENERATE', 'TTS_GENERATE', 'VIDEO_GENERATE', 'LIPSYNC_GENERATE', 'EPISODE_RENDER', 'DELIVERY_PUBLISH']), + episodeId: z.uuid().optional(), + idempotencyKey: z.string().trim().min(8).max(180).optional(), + input: z.record(z.string(), z.unknown()).default({}), + maxAttempts: z.number().int().min(1).max(8).default(3), +}) + +function jobPermission(type: z.infer['type']): Permission { + if (type === 'EPISODE_RENDER') return 'render:create' + if (type === 'DELIVERY_PUBLISH') return 'publish:create' + return 'content:write' +} + +export async function jobRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/jobs', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const query = parseWith(listQuery, request.query) + await requireWorkspacePermission(request, workspaceId, 'project:read') + const filters = [eq(generationJobs.workspaceId, workspaceId)] + if (query.status) filters.push(eq(generationJobs.status, query.status)) + if (query.type) filters.push(eq(generationJobs.type, query.type)) + return db.select().from(generationJobs).where(and(...filters)).orderBy(desc(generationJobs.createdAt)).limit(200) + }) + + app.post('/projects/:projectId/jobs', async (request, reply) => { + const { projectId } = parseWith(projectParams, request.params) + const input = parseWith(createJobSchema, request.body) + const { project } = await requireProjectPermission(request, projectId, jobPermission(input.type)) + const result = await enqueueGeneration({ + workspaceId: project.workspaceId, + projectId, + userId: request.user.sub, + type: input.type, + idempotencyKey: input.idempotencyKey ?? `${input.type.toLowerCase()}-${crypto.randomUUID()}`, + payload: input.input, + maxAttempts: input.maxAttempts, + ...(input.episodeId ? { episodeId: input.episodeId } : {}), + }) + await audit({ request, workspaceId: project.workspaceId, action: 'job.enqueue', resourceType: 'generation_job', resourceId: result.job.id, after: { type: input.type, deduplicated: result.deduplicated } }) + return reply.code(result.deduplicated ? 200 : 202).send(result) + }) + + app.get('/jobs/:jobId', async (request) => { + const { jobId } = parseWith(jobParams, request.params) + const [job] = await db.select().from(generationJobs).where(eq(generationJobs.id, jobId)).limit(1) + if (!job) throw errors.notFound('Job') + await requireWorkspacePermission(request, job.workspaceId, 'project:read') + return job + }) + + app.delete('/jobs/:jobId', async (request, reply) => { + const { jobId } = parseWith(jobParams, request.params) + const [job] = await db.select().from(generationJobs).where(eq(generationJobs.id, jobId)).limit(1) + if (!job) throw errors.notFound('Job') + await requireWorkspacePermission(request, job.workspaceId, jobPermission(job.type)) + if (job.productionRunId) throw errors.conflict('This task belongs to a production run; cancel the production run instead') + if (!['QUEUED', 'RUNNING'].includes(job.status)) throw errors.conflict(`Job in ${job.status} state cannot be cancelled`) + const queueJob = await generationQueue.getJob(jobId) + if (job.type === 'DELIVERY_PUBLISH' && (job.status === 'RUNNING' || (queueJob && await queueJob.isActive()))) { + throw errors.conflict('A delivery already being published cannot be cancelled') + } + if (queueJob && !(await queueJob.isActive())) await queueJob.remove() + const updated = await db.transaction(async (tx) => { + const [cancelled] = await tx.update(generationJobs).set({ status: 'CANCELLED', completedAt: new Date(), updatedAt: new Date() }).where(eq(generationJobs.id, jobId)).returning() + if (job.type === 'DELIVERY_PUBLISH') { + const deliveryId = z.uuid().safeParse(job.input.deliveryId) + if (deliveryId.success) { + await tx.update(deliveries).set({ + status: 'CANCELLED', + jobId, + errorMessage: null, + updatedAt: new Date(), + }).where(and(eq(deliveries.id, deliveryId.data), eq(deliveries.status, 'QUEUED'))) + } + } + return cancelled + }) + await audit({ request, workspaceId: job.workspaceId, action: 'job.cancel', resourceType: 'generation_job', resourceId: jobId, before: { status: job.status }, after: { status: 'CANCELLED' } }) + await publishRealtimeEvent({ + workspaceId: job.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: jobId, + payload: { id: jobId, type: job.type, status: 'CANCELLED', progress: job.progress }, + }) + return reply.code(200).send(updated) + }) + + app.post('/jobs/:jobId/retry', async (request, reply) => { + const { jobId } = parseWith(jobParams, request.params) + const [job] = await db.select().from(generationJobs).where(eq(generationJobs.id, jobId)).limit(1) + if (!job) throw errors.notFound('Job') + await requireWorkspacePermission(request, job.workspaceId, jobPermission(job.type)) + if (job.productionRunId) throw errors.conflict('This task belongs to a production run; start a new production run instead') + if (!['FAILED', 'CANCELLED'].includes(job.status)) throw errors.conflict(`Job in ${job.status} state cannot be retried`) + + const result = await enqueueGeneration({ + workspaceId: job.workspaceId, + userId: request.user.sub, + type: job.type, + idempotencyKey: `retry-${job.id}-${crypto.randomUUID()}`, + payload: { ...job.input, retryOfJobId: job.id }, + maxAttempts: job.maxAttempts, + ...(job.projectId ? { projectId: job.projectId } : {}), + ...(job.episodeId ? { episodeId: job.episodeId } : {}), + }) + + await audit({ + request, + workspaceId: job.workspaceId, + action: 'job.retry', + resourceType: 'generation_job', + resourceId: result.job.id, + before: { sourceJobId: job.id, sourceStatus: job.status }, + after: { type: job.type, status: result.job.status }, + }) + return reply.code(202).send({ ...result, sourceJobId: job.id }) + }) +} diff --git a/server/src/routes/notifications.integration.test.ts b/server/src/routes/notifications.integration.test.ts new file mode 100644 index 0000000..2e96187 --- /dev/null +++ b/server/src/routes/notifications.integration.test.ts @@ -0,0 +1,153 @@ +import type { FastifyInstance } from 'fastify' +import { inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { users, workspaces } from '../db/schema.js' +import { createNotification } from '../lib/notifications.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('persistent notifications and realtime events', () => { + let app: FastifyInstance + let owner: Session + let outsider: Session + let workspaceId = '' + let origin = '' + const userIds: string[] = [] + const workspaceIds: string[] = [] + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + workspaceIds.push(session.workspaces[0].id) + return session + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await app.inject({ + method, + url, + headers: { authorization: `Bearer ${token}` }, + payload, + }) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + beforeAll(async () => { + app = await buildApp() + owner = await registerAccount('notification-owner') + outsider = await registerAccount('notification-outsider') + workspaceId = owner.workspaces[0].id + origin = await app.listen({ host: '127.0.0.1', port: 0 }) + }) + + afterAll(async () => { + if (workspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, workspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('persists user-scoped notifications, deduplicates retries, and tracks read state', async () => { + const input = { + workspaceId, + userId: owner.user.id, + kind: 'JOB_FAILED', + tone: 'ERROR' as const, + title: '视频生成失败', + body: '上游模型暂时不可用', + page: 'jobs', + resourceType: 'generation_job', + resourceId: crypto.randomUUID(), + dedupeKey: `notification-test-${crypto.randomUUID()}`, + } + const created = await createNotification(input) + const duplicate = await createNotification(input) + expect(created?.id).toBeTruthy() + expect(duplicate).toBeNull() + + const listed = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/notifications`) + expect(listed.unreadCount).toBe(1) + expect(listed.items.find((item: { id: string }) => item.id === created?.id)).toMatchObject({ + title: '视频生成失败', + readAt: null, + }) + + const outsiderResponse = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${workspaceId}/notifications`, + headers: { authorization: `Bearer ${outsider.accessToken}` }, + }) + expect(outsiderResponse.statusCode, outsiderResponse.body).toBe(403) + + const read = await request(owner.accessToken, 'PATCH', `/api/v1/notifications/${created?.id}`, { read: true }) + expect(read.readAt).toBeTruthy() + const afterRead = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/notifications?unreadOnly=true`) + expect(afterRead.unreadCount).toBe(0) + expect(afterRead.items).toHaveLength(0) + }) + + it('streams authenticated workspace events and supports read-all', async () => { + const controller = new AbortController() + const response = await fetch(`${origin}/api/v1/workspaces/${workspaceId}/events`, { + headers: { authorization: `Bearer ${owner.accessToken}` }, + signal: controller.signal, + }) + expect(response.status).toBe(200) + expect(response.headers.get('content-type')).toContain('text/event-stream') + const reader = response.body?.getReader() + if (!reader) throw new Error('SSE response body is unavailable') + const decoder = new TextDecoder() + let buffer = '' + let readySeen = false + while (!readySeen) { + const chunk = await reader.read() + if (chunk.done) throw new Error('SSE stream closed before ready event') + buffer += decoder.decode(chunk.value, { stream: true }) + readySeen = buffer.includes('event: realtime.ready') + } + + const created = await createNotification({ + workspaceId, + userId: owner.user.id, + kind: 'REVIEW_ASSIGNED', + tone: 'WARNING', + title: '审核任务已指派给你', + page: 'reviews', + resourceType: 'review_request', + resourceId: crypto.randomUUID(), + dedupeKey: `notification-stream-${crypto.randomUUID()}`, + }) + let notificationSeen = false + while (!notificationSeen) { + const chunk = await reader.read() + if (chunk.done) throw new Error('SSE stream closed before notification event') + buffer += decoder.decode(chunk.value, { stream: true }) + notificationSeen = buffer.includes('event: notification.created') && buffer.includes(created!.id) + } + controller.abort() + await reader.cancel().catch(() => undefined) + + const result = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/notifications/read-all`) + expect(result.updatedCount).toBeGreaterThanOrEqual(1) + const listed = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/notifications`) + expect(listed.unreadCount).toBe(0) + }) +}) diff --git a/server/src/routes/notifications.ts b/server/src/routes/notifications.ts new file mode 100644 index 0000000..0a65911 --- /dev/null +++ b/server/src/routes/notifications.ts @@ -0,0 +1,146 @@ +import type { FastifyInstance } from 'fastify' +import type { OutgoingHttpHeaders } from 'node:http' +import { and, count, desc, eq, isNull, lt } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { notifications } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireWorkspacePermission } from '../lib/permissions.js' +import { publishRealtimeEvent, RealtimeHub, type RealtimeEvent } from '../lib/realtime.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const notificationParams = z.object({ notificationId: z.uuid() }) +const listQuery = z.object({ + limit: z.coerce.number().int().min(1).max(100).default(30), + before: z.iso.datetime({ offset: true }).optional(), + unreadOnly: z.enum(['true', 'false']).transform((value) => value === 'true').default(false), +}) +const readBody = z.object({ read: z.boolean() }) + +function sseFrame(event: RealtimeEvent) { + return `id: ${event.id}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n` +} + +export async function notificationRoutes(app: FastifyInstance) { + const hub = new RealtimeHub((error) => app.log.error({ err: error }, 'Realtime subscriber error')) + app.addHook('preClose', async () => hub.close()) + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/notifications', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const query = parseWith(listQuery, request.query) + await requireWorkspacePermission(request, workspaceId, 'project:read') + const filters = [ + eq(notifications.workspaceId, workspaceId), + eq(notifications.userId, request.user.sub), + ] + if (query.before) filters.push(lt(notifications.createdAt, new Date(query.before))) + if (query.unreadOnly) filters.push(isNull(notifications.readAt)) + const [items, [unread]] = await Promise.all([ + db.select().from(notifications).where(and(...filters)).orderBy(desc(notifications.createdAt)).limit(query.limit + 1), + db.select({ count: count() }).from(notifications).where(and( + eq(notifications.workspaceId, workspaceId), + eq(notifications.userId, request.user.sub), + isNull(notifications.readAt), + )), + ]) + const hasMore = items.length > query.limit + const visible = items.slice(0, query.limit) + return { + items: visible, + unreadCount: Number(unread?.count ?? 0), + nextCursor: hasMore ? visible.at(-1)?.createdAt.toISOString() ?? null : null, + } + }) + + app.patch('/notifications/:notificationId', async (request) => { + const { notificationId } = parseWith(notificationParams, request.params) + const input = parseWith(readBody, request.body) + const [existing] = await db.select().from(notifications).where(and( + eq(notifications.id, notificationId), + eq(notifications.userId, request.user.sub), + )).limit(1) + if (!existing) throw errors.notFound('Notification') + await requireWorkspacePermission(request, existing.workspaceId, 'project:read') + const [updated] = await db.update(notifications).set({ + readAt: input.read ? new Date() : null, + updatedAt: new Date(), + }).where(and(eq(notifications.id, notificationId), eq(notifications.userId, request.user.sub))).returning() + if (!updated) throw errors.notFound('Notification') + await publishRealtimeEvent({ + workspaceId: updated.workspaceId, + userId: updated.userId, + type: 'notification.updated', + resourceType: 'notification', + resourceId: updated.id, + payload: { notification: updated }, + }) + return updated + }) + + app.post('/workspaces/:workspaceId/notifications/read-all', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'project:read') + const updated = await db.update(notifications).set({ readAt: new Date(), updatedAt: new Date() }).where(and( + eq(notifications.workspaceId, workspaceId), + eq(notifications.userId, request.user.sub), + isNull(notifications.readAt), + )).returning({ id: notifications.id }) + await publishRealtimeEvent({ + workspaceId, + userId: request.user.sub, + type: 'notification.read-all', + payload: { notificationIds: updated.map((item) => item.id) }, + }) + return { updatedCount: updated.length, readAt: new Date().toISOString() } + }) + + app.get('/workspaces/:workspaceId/events', async (request, reply) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'project:read') + reply + .code(200) + .header('content-type', 'text/event-stream; charset=utf-8') + .header('cache-control', 'no-cache, no-transform') + .header('connection', 'keep-alive') + .header('x-accel-buffering', 'no') + reply.hijack() + reply.raw.writeHead(200, reply.getHeaders() as OutgoingHttpHeaders) + + let closed = false + const send = (event: RealtimeEvent) => { + if (!closed && !reply.raw.destroyed) reply.raw.write(sseFrame(event)) + } + const removeClient = await hub.addClient({ + workspaceId, + userId: request.user.sub, + send, + close: () => { + if (!reply.raw.destroyed) reply.raw.end() + }, + }) + send({ + id: crypto.randomUUID(), + workspaceId, + userId: request.user.sub, + type: 'realtime.ready', + occurredAt: new Date().toISOString(), + payload: {}, + }) + const heartbeat = setInterval(() => { + if (!closed && !reply.raw.destroyed) reply.raw.write(`: heartbeat ${Date.now()}\n\n`) + }, 20_000) + heartbeat.unref() + + const cleanup = () => { + if (closed) return + closed = true + clearInterval(heartbeat) + removeClient() + } + request.raw.once('close', cleanup) + reply.raw.once('close', cleanup) + }) +} diff --git a/server/src/routes/production-runs.integration.test.ts b/server/src/routes/production-runs.integration.test.ts new file mode 100644 index 0000000..caf1ea2 --- /dev/null +++ b/server/src/routes/production-runs.integration.test.ts @@ -0,0 +1,155 @@ +import type { FastifyInstance } from 'fastify' +import { inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { generationJobs, shotVersions, users, workspaces } from '../db/schema.js' +import { generationQueue } from '../queue/client.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('whole-episode production runs', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + let episodeId = '' + let runId = '' + let rootJobId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ method, url, headers: { authorization: `Bearer ${token}` }, payload }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp() + owner = await registerAccount('production-owner') + viewer = await registerAccount('production-viewer') + workspaceId = owner.workspaces[0].id + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '整集生产测试项目', + logline: '验证批次编排、权限、列表和取消。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + const episode = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '整集生产测试集', + synopsis: '', + targetDurationSeconds: 30, + }) + episodeId = episode.id + const shot = await request(owner.accessToken, 'POST', `/api/v1/episodes/${episodeId}/shots`, { + shotNumber: 1, + sceneNumber: 1, + title: '已有成片镜头', + description: '该镜头已有可用视频,因此批次只需要创建根渲染任务。', + shotType: '中景', + cameraMotion: '静止', + durationMs: 3000, + characterAssetIds: [], + sortOrder: 100, + }) + await db.insert(shotVersions).values({ + shotId: shot.id, + version: 1, + videoStorageKey: `${workspaceId}/${projectId}/generated/shots/lipsync/existing.mp4`, + subtitleText: '', + generationParams: { operation: 'lipsync' }, + isCurrent: true, + createdById: owner.user.id, + }) + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + }) + + afterAll(async () => { + if (rootJobId) { + const queued = await generationQueue.getJob(rootJobId) + if (queued && !(await queued.isActive())) await queued.remove({ removeChildren: true }).catch(() => {}) + } + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('creates one persisted run and reserves the entire graph before enqueueing', async () => { + const response = await inject(owner.accessToken, 'POST', `/api/v1/episodes/${episodeId}/production-runs`, { + mode: 'MISSING', + imageProvider: 'openai', + enableLipsync: true, + }) + expect(response.statusCode, response.body).toBe(202) + const created = response.json() + runId = created.id + expect(created.totalJobs).toBe(1) + expect(created.render.version).toBe(1) + expect(created.jobs).toHaveLength(1) + expect(created.jobs[0].type).toBe('EPISODE_RENDER') + expect(created.jobs[0].productionRunId).toBe(runId) + rootJobId = created.jobs[0].id + + const persisted = await db.select().from(generationJobs).where(inArray(generationJobs.id, [rootJobId])) + expect(persisted[0]?.estimatedCredits).toBe('2.4000') + }) + + it('lists run progress for readers and prevents graph-breaking job actions', async () => { + const rows = await request(viewer.accessToken, 'GET', `/api/v1/episodes/${episodeId}/production-runs`) + expect(rows[0].id).toBe(runId) + expect(rows[0].summary.completedJobs).toBeGreaterThanOrEqual(0) + + const cancelJob = await inject(owner.accessToken, 'DELETE', `/api/v1/jobs/${rootJobId}`) + expect(cancelJob.statusCode, cancelJob.body).toBe(409) + expect(cancelJob.json().error.message).toContain('production run') + + const duplicate = await inject(owner.accessToken, 'POST', `/api/v1/episodes/${episodeId}/production-runs`, {}) + expect(duplicate.statusCode, duplicate.body).toBe(409) + }) + + it('enforces edit permission and cancels a run as a unit', async () => { + const forbidden = await inject(viewer.accessToken, 'DELETE', `/api/v1/production-runs/${runId}`) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + const cancelled = await request(owner.accessToken, 'DELETE', `/api/v1/production-runs/${runId}`) + expect(cancelled.status).toBe('CANCELLED') + + const detail = await request(viewer.accessToken, 'GET', `/api/v1/production-runs/${runId}`) + expect(detail.status).toBe('CANCELLED') + expect(detail.jobs.every((job: { status: string }) => ['CANCELLED', 'FAILED', 'SUCCEEDED'].includes(job.status))).toBe(true) + }) +}) diff --git a/server/src/routes/production.integration.test.ts b/server/src/routes/production.integration.test.ts new file mode 100644 index 0000000..8b19a5f --- /dev/null +++ b/server/src/routes/production.integration.test.ts @@ -0,0 +1,356 @@ +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { deliveries, generationJobs, renders, users, workspaces } from '../db/schema.js' +import { generationQueue } from '../queue/client.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('render delivery workflow', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + let episodeId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + const queueJobIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: { authorization: `Bearer ${token}` }, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + async function persistRender(version: number, withSubtitles = false) { + const [render] = await db.insert(renders).values({ + episodeId, + version, + status: 'APPROVED', + storageKey: `${workspaceId}/${projectId}/generated/renders/test-v${version}.mp4`, + mimeType: 'video/mp4', + byteSize: 1_024_000 * version, + durationMs: 12_000, + width: 1920, + height: 1080, + fps: 24, + settings: { quality: 'balanced' }, + ...(withSubtitles ? { + subtitleSrtKey: `${workspaceId}/${projectId}/generated/renders-subtitles/test-v${version}.srt`, + subtitleVttKey: `${workspaceId}/${projectId}/generated/renders-subtitles/test-v${version}.vtt`, + sourceManifest: { + schemaVersion: 1, + capturedAt: new Date().toISOString(), + shots: [ + { + shotId: crypto.randomUUID(), + shotVersionId: crypto.randomUUID(), + shotNumber: 1, + shotVersion: 2, + sortOrder: 100, + durationMs: 5_000, + subtitleText: '第一句', + imageAssetVersionId: null, + }, + { + shotId: crypto.randomUUID(), + shotVersionId: crypto.randomUUID(), + shotNumber: 2, + shotVersion: 1, + sortOrder: 200, + durationMs: 7_000, + subtitleText: '第二句', + imageAssetVersionId: null, + }, + ], + }, + } : {}), + createdById: owner.user.id, + }).returning() + if (!render) throw new Error('Failed to create test render') + return render + } + + beforeAll(async () => { + app = await buildApp() + owner = await registerAccount('delivery-owner') + viewer = await registerAccount('delivery-viewer') + workspaceId = owner.workspaces[0].id + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '交付闭环测试项目', + logline: '验证成片交付、下载和失败重试。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + const episode = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '交付测试集', + synopsis: '', + targetDurationSeconds: 60, + }) + episodeId = episode.id + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + }) + + afterAll(async () => { + for (const jobId of queueJobIds) { + for (let attempt = 0; attempt < 100; attempt += 1) { + const job = await generationQueue.getJob(jobId) + if (!job) break + if (await job.isActive()) { + await new Promise((resolve) => setTimeout(resolve, 25)) + continue + } + await job.remove() + break + } + } + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('lists episode deliveries with render version context', async () => { + const render = await persistRender(1) + const [delivery] = await db.insert(deliveries).values({ + renderId: render.id, + platform: 'DOWNLOAD', + status: 'QUEUED', + createdById: owner.user.id, + }).returning() + if (!delivery) throw new Error('Failed to create test delivery') + + const rows = await request(owner.accessToken, 'GET', `/api/v1/episodes/${episodeId}/deliveries`) + const listed = rows.find((item: { id: string }) => item.id === delivery.id) + expect(listed.status).toBe('QUEUED') + expect(listed.render.id).toBe(render.id) + expect(listed.render.version).toBe(1) + expect(listed.render.width).toBe(1920) + + const viewerRows = await request(viewer.accessToken, 'GET', `/api/v1/episodes/${episodeId}/deliveries`) + expect(viewerRows.some((item: { id: string }) => item.id === delivery.id)).toBe(true) + }) + + it('returns a short-lived signed download URL only for published delivery', async () => { + const render = await persistRender(2) + const [published, failed] = await db.insert(deliveries).values([ + { + renderId: render.id, + platform: 'DOWNLOAD', + status: 'PUBLISHED', + publishedUrl: '/api/v1/deliveries/test/download', + publishedAt: new Date(), + createdById: owner.user.id, + }, + { + renderId: render.id, + platform: 'ARCHIVE_TEST', + status: 'FAILED', + errorMessage: 'Test failure', + createdById: owner.user.id, + }, + ]).returning() + if (!published || !failed) throw new Error('Failed to create delivery states') + + const detail = await request(viewer.accessToken, 'GET', `/api/v1/deliveries/${published.id}`) + expect(detail.status).toBe('PUBLISHED') + expect(detail.render.version).toBe(2) + expect(detail.downloadExpiresIn).toBe(300) + expect(detail.downloadUrl).toContain('X-Amz-Signature=') + + const failedDetail = await request(owner.accessToken, 'GET', `/api/v1/deliveries/${failed.id}`) + expect(failedDetail.downloadUrl).toBeNull() + expect(failedDetail.downloadExpiresIn).toBeNull() + }) + + it('returns signed immutable SRT and VTT sidecars without exposing storage internals', async () => { + const render = await persistRender(7, true) + const detail = await request(viewer.accessToken, 'GET', `/api/v1/renders/${render.id}`) + expect(detail.subtitleFormats).toEqual(['srt', 'vtt']) + expect(detail.sourceShotCount).toBe(2) + expect(detail).not.toHaveProperty('subtitleSrtKey') + expect(detail).not.toHaveProperty('subtitleVttKey') + expect(detail).not.toHaveProperty('sourceManifest') + + for (const format of ['srt', 'vtt']) { + const subtitle = await request(viewer.accessToken, 'GET', `/api/v1/renders/${render.id}/subtitles/${format}`) + expect(subtitle.format).toBe(format) + expect(subtitle.filename).toBe(`EP01-交付测试集-v7.${format}`) + expect(subtitle.downloadExpiresIn).toBe(300) + const signedUrl = new URL(subtitle.downloadUrl) + expect(signedUrl.searchParams.get('X-Amz-Signature')).toBeTruthy() + expect(signedUrl.searchParams.get('response-content-disposition')).toContain('attachment;') + expect(signedUrl.searchParams.get('response-content-disposition')).toContain(`.${format}`) + } + + const invalid = await inject(owner.accessToken, 'GET', `/api/v1/renders/${render.id}/subtitles/ass`) + expect(invalid.statusCode, invalid.body).toBe(400) + + const renderWithoutSubtitles = await persistRender(8) + const missing = await inject(owner.accessToken, 'GET', `/api/v1/renders/${renderWithoutSubtitles.id}/subtitles/srt`) + expect(missing.statusCode, missing.body).toBe(404) + }) + + it('prevents duplicate active or published downloads for one render', async () => { + const render = await persistRender(3) + await db.insert(deliveries).values({ + renderId: render.id, + platform: 'DOWNLOAD', + status: 'PUBLISHED', + publishedAt: new Date(), + createdById: owner.user.id, + }) + + const duplicate = await inject(owner.accessToken, 'POST', `/api/v1/renders/${render.id}/deliveries`, { platform: 'DOWNLOAD' }) + expect(duplicate.statusCode, duplicate.body).toBe(409) + expect(duplicate.json().error.message).toContain('already exists') + + const forbidden = await inject(viewer.accessToken, 'POST', `/api/v1/renders/${render.id}/deliveries`, { platform: 'DOWNLOAD' }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + }) + + it('retries a failed delivery and rejects invalid or read-only retries', async () => { + const render = await persistRender(4) + const [failed] = await db.insert(deliveries).values({ + renderId: render.id, + platform: 'DOWNLOAD', + status: 'FAILED', + errorMessage: 'Temporary queue failure', + createdById: owner.user.id, + }).returning() + if (!failed) throw new Error('Failed to create retry delivery') + + const forbidden = await inject(viewer.accessToken, 'POST', `/api/v1/deliveries/${failed.id}/retry`) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + const retried = await inject(owner.accessToken, 'POST', `/api/v1/deliveries/${failed.id}/retry`) + expect(retried.statusCode, retried.body).toBe(202) + const result = retried.json() + queueJobIds.push(result.job.id) + expect(result.delivery.id).toBe(failed.id) + expect(result.delivery.status).toBe('QUEUED') + expect(result.delivery.jobId).toBe(result.job.id) + expect(result.delivery.errorMessage).toBeNull() + expect(result.job.type).toBe('DELIVERY_PUBLISH') + expect(result.job.input.deliveryId).toBe(failed.id) + + const repeated = await inject(owner.accessToken, 'POST', `/api/v1/deliveries/${failed.id}/retry`) + expect(repeated.statusCode, repeated.body).toBe(409) + }) + + it('schedules, cancels and retries a queued delivery', async () => { + const render = await persistRender(5) + const scheduledAt = new Date(Date.now() + 30 * 60_000).toISOString() + const createdResponse = await inject(owner.accessToken, 'POST', `/api/v1/renders/${render.id}/deliveries`, { + platform: 'DOWNLOAD', + scheduledAt, + }) + expect(createdResponse.statusCode, createdResponse.body).toBe(202) + const created = createdResponse.json() + queueJobIds.push(created.job.id) + expect(created.delivery.status).toBe('QUEUED') + expect(created.delivery.jobId).toBe(created.job.id) + expect(new Date(created.delivery.scheduledAt).toISOString()).toBe(scheduledAt) + + const delayedJob = await generationQueue.getJob(created.job.id) + expect(delayedJob).toBeTruthy() + expect(await delayedJob?.getState()).toBe('delayed') + expect(delayedJob?.delay).toBeGreaterThan(25 * 60_000) + + const forbidden = await inject(viewer.accessToken, 'DELETE', `/api/v1/deliveries/${created.delivery.id}`) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + const cancelled = await request(owner.accessToken, 'DELETE', `/api/v1/deliveries/${created.delivery.id}`) + expect(cancelled.status).toBe('CANCELLED') + expect(cancelled.jobId).toBe(created.job.id) + expect(cancelled.errorMessage).toBeNull() + expect(await generationQueue.getJob(created.job.id)).toBeUndefined() + + const [cancelledJob] = await db.select().from(generationJobs).where(eq(generationJobs.id, created.job.id)).limit(1) + expect(cancelledJob?.status).toBe('CANCELLED') + const repeatedCancel = await inject(owner.accessToken, 'DELETE', `/api/v1/deliveries/${created.delivery.id}`) + expect(repeatedCancel.statusCode, repeatedCancel.body).toBe(409) + + const retriedResponse = await inject(owner.accessToken, 'POST', `/api/v1/deliveries/${created.delivery.id}/retry`) + expect(retriedResponse.statusCode, retriedResponse.body).toBe(202) + const retried = retriedResponse.json() + queueJobIds.push(retried.job.id) + expect(retried.delivery.status).toBe('QUEUED') + expect(retried.delivery.jobId).toBe(retried.job.id) + expect(retried.delivery.jobId).not.toBe(created.job.id) + expect(retried.delivery.scheduledAt).toBeNull() + }) + + it('keeps delivery state in sync when cancellation starts from the task center', async () => { + const render = await persistRender(6) + const [delivery] = await db.insert(deliveries).values({ + renderId: render.id, + platform: 'DOWNLOAD', + status: 'QUEUED', + createdById: owner.user.id, + }).returning() + if (!delivery) throw new Error('Failed to create cancelled delivery') + + const [job] = await db.insert(generationJobs).values({ + workspaceId, + projectId, + episodeId, + createdById: owner.user.id, + type: 'DELIVERY_PUBLISH', + status: 'QUEUED', + idempotencyKey: `delivery-cancel-${crypto.randomUUID()}`, + input: { deliveryId: delivery.id }, + estimatedCredits: '0', + }).returning() + if (!job) throw new Error('Failed to create cancelled delivery job') + await db.update(deliveries).set({ jobId: job.id }).where(eq(deliveries.id, delivery.id)) + + const cancelled = await request(owner.accessToken, 'DELETE', `/api/v1/jobs/${job.id}`) + expect(cancelled.status).toBe('CANCELLED') + + const detail = await request(owner.accessToken, 'GET', `/api/v1/deliveries/${delivery.id}`) + expect(detail.status).toBe('CANCELLED') + expect(detail.jobId).toBe(job.id) + expect(detail.errorMessage).toBeNull() + expect(detail.downloadUrl).toBeNull() + }) +}) diff --git a/server/src/routes/production.ts b/server/src/routes/production.ts new file mode 100644 index 0000000..5aaffc6 --- /dev/null +++ b/server/src/routes/production.ts @@ -0,0 +1,805 @@ +import type { FastifyInstance } from 'fastify' +import type { FlowJob } from 'bullmq' +import { and, asc, desc, eq, gte, inArray, isNull, lt, ne, sql } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { + assetVersions, + deliveries, + episodes, + generationJobs, + publishingChannelAccounts, + productionRuns, + projects, + renders, + shots, + shotVersions, + usageLedger, + workspaces, +} from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { billingPeriod, estimateJobCredits } from '../lib/billing.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission } from '../lib/permissions.js' +import { episodeRenderSettingsSchema } from '../media/ffmpeg.js' +import { assertJobProviderConfigured } from '../providers/readiness.js' +import { enqueueGeneration, generationFlowProducer, generationQueue } from '../queue/client.js' +import { + buildShotProductionChain, + flattenProductionPlan, + type ProductionPlanNode, + type ProductionPlanSettings, +} from '../queue/production-plan.js' +import { GENERATION_QUEUE, type GenerationJobData, type JobKind } from '../queue/types.js' +import { presignDownload } from '../storage/client.js' +import { createPublishingAdapterRegistry } from '../publishing/connector.js' +import { externalPublishingPlatforms, type PublishingAdapterRegistry } from '../publishing/types.js' + +const episodeParams = z.object({ episodeId: z.uuid() }) +const renderParams = z.object({ renderId: z.uuid() }) +const renderSubtitleParams = z.object({ renderId: z.uuid(), format: z.enum(['srt', 'vtt']) }) +const deliveryParams = z.object({ deliveryId: z.uuid() }) +const productionRunParams = z.object({ runId: z.uuid() }) +const defaultRenderSettings = { + width: 1920, + height: 1080, + fps: 24 as const, + quality: 'balanced' as const, + burnSubtitles: true, + normalizeAudio: true, + musicVolume: 0.18, + subtitleStyle: { + fontSize: 24, + textColor: '#FFFFFF', + outlineColor: '#000000', + outlineWidth: 2, + bottomMargin: 48, + bold: true, + }, +} +const createRenderSchema = z.object({ + settings: episodeRenderSettingsSchema.default(defaultRenderSettings), + idempotencyKey: z.string().trim().min(8).max(180).optional(), +}) +const createProductionRunSchema = z.object({ + mode: z.enum(['MISSING', 'REGENERATE']).default('MISSING'), + imageProvider: z.enum(['openai', 'replicate', 'agnes', 'generic']).default('openai'), + videoProvider: z.enum(['replicate', 'agnes', 'generic']).default('replicate'), + imageWidth: z.number().int().min(256).max(4096).default(1536), + imageHeight: z.number().int().min(256).max(4096).default(1024), + voice: z.string().trim().min(1).max(80).default('alloy'), + speechSpeed: z.number().min(0.25).max(4).default(1), + enableLipsync: z.boolean().default(true), + videoParams: z.record(z.string(), z.unknown()).default({}), + lipsyncParams: z.record(z.string(), z.unknown()).default({}), + renderSettings: episodeRenderSettingsSchema.default(defaultRenderSettings), +}) +const createDeliverySchema = z.object({ + platform: z.enum(['DOWNLOAD', ...externalPublishingPlatforms]).default('DOWNLOAD'), + channelAccountId: z.uuid().optional(), + destination: z.record(z.string(), z.unknown()).default({}), + scheduledAt: z.iso.datetime({ offset: true }).optional(), +}).superRefine((input, context) => { + if (input.platform === 'DOWNLOAD' && input.channelAccountId) { + context.addIssue({ code: 'custom', path: ['channelAccountId'], message: 'Download delivery does not use a channel account' }) + } + if (input.platform !== 'DOWNLOAD' && !input.channelAccountId) { + context.addIssue({ code: 'custom', path: ['channelAccountId'], message: 'External publishing requires a channel account' }) + } +}) + +interface ProductionRouteOptions { + publishingAdapters?: PublishingAdapterRegistry +} + +async function episodeProject(episodeId: string) { + const [row] = await db.select({ episode: episodes, project: projects }).from(episodes) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(episodes.id, episodeId)).limit(1) + if (!row) throw errors.notFound('Episode') + return row +} + +async function renderProject(renderId: string) { + const [row] = await db.select({ render: renders, episode: episodes, project: projects }).from(renders) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(renders.id, renderId)).limit(1) + if (!row) throw errors.notFound('Render') + return row +} + +async function deliveryProject(deliveryId: string) { + const [row] = await db.select({ delivery: deliveries, render: renders, episode: episodes, project: projects, channelAccount: publishingChannelAccounts }).from(deliveries) + .innerJoin(renders, eq(renders.id, deliveries.renderId)) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .leftJoin(publishingChannelAccounts, eq(publishingChannelAccounts.id, deliveries.channelAccountId)) + .where(eq(deliveries.id, deliveryId)).limit(1) + if (!row) throw errors.notFound('Delivery') + return row +} + +function publicChannelAccount(account: typeof publishingChannelAccounts.$inferSelect | null) { + if (!account) return null + return { + id: account.id, + platform: account.platform, + externalAccountId: account.externalAccountId, + displayName: account.displayName, + avatarUrl: account.avatarUrl, + status: account.status, + } +} + +function renderResponse(render: typeof renders.$inferSelect) { + const { subtitleSrtKey, subtitleVttKey, sourceManifest, ...publicFields } = render + return { + ...publicFields, + subtitleFormats: [ + ...(subtitleSrtKey ? ['srt' as const] : []), + ...(subtitleVttKey ? ['vtt' as const] : []), + ], + sourceShotCount: sourceManifest?.shots.length ?? null, + } +} + +interface PersistedPlanNode extends ProductionPlanNode { + id: string + children?: PersistedPlanNode[] +} + +function assignPlanIds(node: ProductionPlanNode): PersistedPlanNode { + const { children, ...job } = node + return { + ...job, + id: crypto.randomUUID(), + ...(children ? { children: children.map(assignPlanIds) } : {}), + } +} + +function flattenPersistedPlan(nodes: PersistedPlanNode[]) { + const rows: PersistedPlanNode[] = [] + const visit = (node: PersistedPlanNode) => { + rows.push(node) + node.children?.forEach(visit) + } + nodes.forEach(visit) + return rows +} + +function flowNode(input: { + node: PersistedPlanNode + workspaceId: string + projectId: string + episodeId: string + userId: string + child?: boolean +}): FlowJob { + const data: GenerationJobData = { + databaseId: input.node.id, + workspaceId: input.workspaceId, + projectId: input.projectId, + episodeId: input.episodeId, + userId: input.userId, + type: input.node.type, + input: input.node.input, + } + return { + name: input.node.type, + queueName: GENERATION_QUEUE, + data, + opts: { + jobId: input.node.id, + attempts: input.node.type === 'EPISODE_RENDER' ? 2 : 3, + backoff: { type: 'exponential', delay: 3000 }, + removeOnComplete: { age: 24 * 60 * 60, count: 1000 }, + removeOnFail: { age: 7 * 24 * 60 * 60, count: 5000 }, + ...(input.child ? { ignoreDependencyOnFailure: true } : {}), + }, + ...(input.node.children?.length ? { + children: input.node.children.map((child) => flowNode({ ...input, node: child, child: true })), + } : {}), + } +} + +function summarizeRunJobs(runJobs: Array) { + const terminal = runJobs.filter((job) => ['SUCCEEDED', 'FAILED', 'CANCELLED'].includes(job.status)) + const activeJobTypes = [...new Set(runJobs.filter((job) => job.status === 'RUNNING').map((job) => job.type))] + const failedJob = runJobs.find((job) => job.status === 'FAILED') + return { + completedJobs: terminal.length, + succeededJobs: runJobs.filter((job) => job.status === 'SUCCEEDED').length, + failedJobs: runJobs.filter((job) => job.status === 'FAILED').length, + cancelledJobs: runJobs.filter((job) => job.status === 'CANCELLED').length, + progress: runJobs.length ? Math.round(runJobs.reduce((total, job) => total + job.progress, 0) / runJobs.length) : 0, + activeJobTypes, + failedStep: failedJob ? { type: failedJob.type, message: failedJob.errorMessage } : null, + } +} + +async function hydrateProductionRuns(rows: Array<{ run: typeof productionRuns.$inferSelect, render: typeof renders.$inferSelect }>) { + if (rows.length === 0) return [] + const runJobs = await db.select().from(generationJobs) + .where(inArray(generationJobs.productionRunId, rows.map(({ run }) => run.id))) + .orderBy(asc(generationJobs.createdAt)) + return rows.map(({ run, render }) => { + const jobs = runJobs.filter((job) => job.productionRunId === run.id) + return { ...run, render: renderResponse(render), summary: summarizeRunJobs(jobs), jobs } + }) +} + +export async function productionRoutes(app: FastifyInstance, options: ProductionRouteOptions = {}) { + const publishingAdapters = options.publishingAdapters ?? createPublishingAdapterRegistry() + app.addHook('preHandler', requireAuth) + + app.get('/episodes/:episodeId/production-runs', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + const runRows = await db.select({ run: productionRuns, render: renders }).from(productionRuns) + .innerJoin(renders, eq(renders.id, productionRuns.renderId)) + .where(eq(productionRuns.episodeId, episodeId)) + .orderBy(desc(productionRuns.createdAt)).limit(20) + return hydrateProductionRuns(runRows) + }) + + app.get('/production-runs/:runId', async (request) => { + const { runId } = parseWith(productionRunParams, request.params) + const [row] = await db.select({ run: productionRuns, render: renders, episode: episodes, project: projects }).from(productionRuns) + .innerJoin(renders, eq(renders.id, productionRuns.renderId)) + .innerJoin(episodes, eq(episodes.id, productionRuns.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(productionRuns.id, runId)).limit(1) + if (!row) throw errors.notFound('Production run') + await requireProjectPermission(request, row.project.id, 'project:read') + const [hydrated] = await hydrateProductionRuns([{ run: row.run, render: row.render }]) + return hydrated + }) + + app.post('/episodes/:episodeId/production-runs', async (request, reply) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(createProductionRunSchema, request.body) + const context = await episodeProject(episodeId) + await requireProjectPermission(request, context.project.id, 'render:create') + if (input.renderSettings.backgroundMusicStorageKey) { + const prefix = `${context.project.workspaceId}/${context.project.id}/` + if (!input.renderSettings.backgroundMusicStorageKey.startsWith(prefix)) throw errors.forbidden('Background music must belong to this project') + } + + const shotRows = await db.select({ shot: shots, version: shotVersions, image: assetVersions }).from(shots) + .leftJoin(shotVersions, and(eq(shotVersions.shotId, shots.id), eq(shotVersions.isCurrent, true))) + .leftJoin(assetVersions, eq(assetVersions.id, shotVersions.imageAssetVersionId)) + .where(eq(shots.episodeId, episodeId)).orderBy(asc(shots.sortOrder)) + if (shotRows.length === 0) throw errors.badRequest('The episode has no shots to produce') + + const planSettings: ProductionPlanSettings = { + mode: input.mode, + imageProvider: input.imageProvider, + videoProvider: input.videoProvider, + imageWidth: input.imageWidth, + imageHeight: input.imageHeight, + voice: input.voice, + speechSpeed: input.speechSpeed, + enableLipsync: input.enableLipsync, + videoParams: input.videoParams, + lipsyncParams: input.lipsyncParams, + } + const plannedChains = shotRows.map(({ shot, version, image }) => buildShotProductionChain({ + id: shot.id, + title: shot.title, + description: shot.description, + durationMs: shot.durationMs, + subtitleText: version?.subtitleText ?? '', + imageAssetVersionId: version?.imageAssetVersionId ?? null, + imageStorageKey: image?.storageKey ?? null, + videoStorageKey: version?.videoStorageKey ?? null, + audioStorageKey: version?.audioStorageKey ?? null, + generationParams: version?.generationParams ?? {}, + }, planSettings)).filter((node): node is ProductionPlanNode => Boolean(node)) + const plannedJobs = flattenProductionPlan(plannedChains) + plannedJobs.forEach((job) => assertJobProviderConfigured(job.type, job.input)) + + const assignedChains = plannedChains.map(assignPlanIds) + const assignedJobs = flattenPersistedPlan(assignedChains) + const runId = crypto.randomUUID() + const renderId = crypto.randomUUID() + const rootJobId = crypto.randomUUID() + const prerequisiteJobIds = assignedJobs.map((job) => job.id) + const rootNode: PersistedPlanNode = { + id: rootJobId, + type: 'EPISODE_RENDER', + input: { renderId, prerequisiteJobIds }, + children: assignedChains, + } + const estimatedCredits = await Promise.all(assignedJobs.map((job) => estimateJobCredits(job.type, job.input))) + const renderCredits = Math.max(1, shotRows.reduce((total, { shot }) => total + shot.durationMs, 0) / 1000) * 0.8 + const totalEstimatedCredits = estimatedCredits.reduce((total, credits) => total + credits, renderCredits) + const now = new Date() + + const persisted = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`production:${episodeId}`}))`) + const [active] = await tx.select({ id: productionRuns.id }).from(productionRuns).where(and( + eq(productionRuns.episodeId, episodeId), + inArray(productionRuns.status, ['QUEUED', 'RUNNING']), + )).limit(1) + if (active) throw errors.conflict('An active production run already exists for this episode') + + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`billing:${context.project.workspaceId}`}))`) + const [workspace] = await tx.select({ monthlyCreditLimit: workspaces.monthlyCreditLimit }).from(workspaces) + .where(eq(workspaces.id, context.project.workspaceId)).limit(1) + if (!workspace) throw errors.notFound('Workspace') + const { start, end } = billingPeriod(now) + const [[usage], [reservation]] = await Promise.all([ + tx.select({ credits: sql`coalesce(sum(${usageLedger.credits}), 0)` }).from(usageLedger).where(and( + eq(usageLedger.workspaceId, context.project.workspaceId), + gte(usageLedger.occurredAt, start), + lt(usageLedger.occurredAt, end), + )), + tx.select({ credits: sql`coalesce(sum(${generationJobs.estimatedCredits}), 0)` }).from(generationJobs).where(and( + eq(generationJobs.workspaceId, context.project.workspaceId), + inArray(generationJobs.status, ['QUEUED', 'RUNNING']), + )), + ]) + const usedCredits = Number(usage?.credits ?? 0) + const reservedCredits = Number(reservation?.credits ?? 0) + const remainingCredits = Math.max(0, workspace.monthlyCreditLimit - usedCredits - reservedCredits) + if (totalEstimatedCredits > remainingCredits) { + throw errors.creditLimitExceeded({ + monthlyCreditLimit: workspace.monthlyCreditLimit, + usedCredits, + reservedCredits, + remainingCredits, + estimatedCredits: totalEstimatedCredits, + }) + } + + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`render:${episodeId}`}))`) + const [latest] = await tx.select({ version: renders.version }).from(renders) + .where(eq(renders.episodeId, episodeId)).orderBy(desc(renders.version)).limit(1) + const renderVersion = (latest?.version ?? 0) + 1 + const [render] = await tx.insert(renders).values({ + id: renderId, + episodeId, + version: renderVersion, + width: input.renderSettings.width, + height: input.renderSettings.height, + fps: input.renderSettings.fps, + settings: input.renderSettings, + createdById: request.user.sub, + }).returning() + const [run] = await tx.insert(productionRuns).values({ + id: runId, + episodeId, + renderId, + settings: input, + totalJobs: assignedJobs.length + 1, + createdById: request.user.sub, + }).returning() + if (!render || !run) throw new Error('Failed to persist production run') + + const values = [ + { node: rootNode, credits: renderCredits, maxAttempts: 2 }, + ...assignedJobs.map((node, index) => ({ node, credits: estimatedCredits[index]!, maxAttempts: 3 })), + ].map(({ node, credits, maxAttempts }) => ({ + id: node.id, + workspaceId: context.project.workspaceId, + projectId: context.project.id, + episodeId, + productionRunId: runId, + createdById: request.user.sub, + type: node.type, + idempotencyKey: `production-${runId}-${node.id}`, + input: node.input, + maxAttempts, + estimatedCredits: credits.toString(), + })) + const jobs = await tx.insert(generationJobs).values(values).returning() + await tx.update(episodes).set({ status: 'PRODUCTION', updatedAt: now }).where(eq(episodes.id, episodeId)) + return { run, render, jobs } + }) + + try { + await generationFlowProducer.add(flowNode({ + node: rootNode, + workspaceId: context.project.workspaceId, + projectId: context.project.id, + episodeId, + userId: request.user.sub, + })) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to enqueue production flow' + await db.transaction(async (tx) => { + await tx.update(generationJobs).set({ status: 'FAILED', errorCode: 'QUEUE_UNAVAILABLE', errorMessage: message, completedAt: new Date(), updatedAt: new Date() }) + .where(eq(generationJobs.productionRunId, runId)) + await tx.update(productionRuns).set({ status: 'FAILED', completedAt: new Date(), updatedAt: new Date() }).where(eq(productionRuns.id, runId)) + await tx.update(renders).set({ status: 'FAILED', qualityReport: { error: message }, updatedAt: new Date() }).where(eq(renders.id, renderId)) + }) + throw error + } + + await audit({ + request, + workspaceId: context.project.workspaceId, + action: 'production_run.create', + resourceType: 'production_run', + resourceId: runId, + after: { renderId, totalJobs: persisted.jobs.length, estimatedCredits: totalEstimatedCredits, mode: input.mode }, + }) + const [hydrated] = await hydrateProductionRuns([{ run: persisted.run, render: persisted.render }]) + return reply.code(202).send(hydrated) + }) + + app.delete('/production-runs/:runId', async (request, reply) => { + const { runId } = parseWith(productionRunParams, request.params) + const [row] = await db.select({ run: productionRuns, render: renders, episode: episodes, project: projects }).from(productionRuns) + .innerJoin(renders, eq(renders.id, productionRuns.renderId)) + .innerJoin(episodes, eq(episodes.id, productionRuns.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(productionRuns.id, runId)).limit(1) + if (!row) throw errors.notFound('Production run') + await requireProjectPermission(request, row.project.id, 'render:create') + if (!['QUEUED', 'RUNNING'].includes(row.run.status)) throw errors.conflict(`Production run in ${row.run.status} state cannot be cancelled`) + + const runJobs = await db.select().from(generationJobs).where(eq(generationJobs.productionRunId, runId)) + const rootJob = runJobs.find((job) => job.type === 'EPISODE_RENDER') + const completedAt = new Date() + const [cancelled] = await db.transaction(async (tx) => { + const [updated] = await tx.update(productionRuns).set({ status: 'CANCELLED', completedAt, updatedAt: completedAt }) + .where(and(eq(productionRuns.id, runId), inArray(productionRuns.status, ['QUEUED', 'RUNNING']))).returning() + if (!updated) throw errors.conflict('Production run is no longer active') + await tx.update(generationJobs).set({ status: 'CANCELLED', completedAt, updatedAt: completedAt }) + .where(and(eq(generationJobs.productionRunId, runId), inArray(generationJobs.status, ['QUEUED', 'RUNNING']))) + await tx.update(renders).set({ status: 'FAILED', qualityReport: { error: 'Production run cancelled' }, updatedAt: completedAt }) + .where(and(eq(renders.id, row.render.id), inArray(renders.status, ['QUEUED', 'RENDERING']))) + return [updated] + }) + if (rootJob) { + try { + const queuedRoot = await generationQueue.getJob(rootJob.id) + if (queuedRoot && !(await queuedRoot.isActive())) await queuedRoot.remove({ removeChildren: true }) + } catch (error) { + request.log.warn({ err: error, runId }, 'Production flow remains in Redis until active work observes cancellation') + } + } + await audit({ request, workspaceId: row.project.workspaceId, action: 'production_run.cancel', resourceType: 'production_run', resourceId: runId, before: { status: row.run.status }, after: { status: 'CANCELLED' } }) + return reply.code(200).send(cancelled) + }) + + app.get('/episodes/:episodeId/renders', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + const rows = await db.select().from(renders).where(eq(renders.episodeId, episodeId)).orderBy(desc(renders.version)) + return rows.map(renderResponse) + }) + + app.get('/episodes/:episodeId/deliveries', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + const rows = await db.select({ delivery: deliveries, render: renders, channelAccount: publishingChannelAccounts }).from(deliveries) + .innerJoin(renders, eq(renders.id, deliveries.renderId)) + .leftJoin(publishingChannelAccounts, eq(publishingChannelAccounts.id, deliveries.channelAccountId)) + .where(eq(renders.episodeId, episodeId)) + .orderBy(desc(deliveries.createdAt)) + return rows.map(({ delivery, render, channelAccount }) => ({ ...delivery, render: renderResponse(render), channelAccount: publicChannelAccount(channelAccount) })) + }) + + app.post('/episodes/:episodeId/renders', async (request, reply) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(createRenderSchema, request.body) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'render:create') + if (input.settings.backgroundMusicStorageKey) { + const prefix = `${row.project.workspaceId}/${row.project.id}/` + if (!input.settings.backgroundMusicStorageKey.startsWith(prefix)) throw errors.forbidden('Background music must belong to this project') + } + + const render = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`render:${episodeId}`}))`) + const [latest] = await tx.select({ version: renders.version }).from(renders) + .where(eq(renders.episodeId, episodeId)).orderBy(desc(renders.version)).limit(1) + const [created] = await tx.insert(renders).values({ + episodeId, + version: (latest?.version ?? 0) + 1, + width: input.settings.width, + height: input.settings.height, + fps: input.settings.fps, + settings: input.settings, + createdById: request.user.sub, + }).returning() + return created + }) + if (!render) throw new Error('Failed to create render') + + try { + const queued = await enqueueGeneration({ + workspaceId: row.project.workspaceId, + projectId: row.project.id, + episodeId, + userId: request.user.sub, + type: 'EPISODE_RENDER', + idempotencyKey: input.idempotencyKey ?? `render-${render.id}`, + payload: { renderId: render.id }, + maxAttempts: 2, + }) + await audit({ request, workspaceId: row.project.workspaceId, action: 'render.create', resourceType: 'render', resourceId: render.id, after: { version: render.version, jobId: queued.job.id } }) + return reply.code(202).send({ render: renderResponse(render), job: queued.job }) + } catch (error) { + await db.update(renders).set({ status: 'FAILED', qualityReport: { error: 'Failed to enqueue render' }, updatedAt: new Date() }).where(eq(renders.id, render.id)) + throw error + } + }) + + app.get('/renders/:renderId', async (request) => { + const { renderId } = parseWith(renderParams, request.params) + const row = await renderProject(renderId) + await requireProjectPermission(request, row.project.id, 'project:read') + return { + ...renderResponse(row.render), + downloadUrl: row.render.storageKey ? await presignDownload(row.render.storageKey) : null, + downloadExpiresIn: row.render.storageKey ? 900 : null, + } + }) + + app.get('/renders/:renderId/subtitles/:format', async (request) => { + const { renderId, format } = parseWith(renderSubtitleParams, request.params) + const row = await renderProject(renderId) + await requireProjectPermission(request, row.project.id, 'project:read') + const storageKey = format === 'srt' ? row.render.subtitleSrtKey : row.render.subtitleVttKey + if (!storageKey) throw errors.notFound(`Render ${format.toUpperCase()} subtitle`) + const projectPrefix = `${row.project.workspaceId}/${row.project.id}/` + if (!storageKey.startsWith(projectPrefix)) throw errors.forbidden('Render subtitle must belong to this project') + const filename = `EP${String(row.episode.episodeNumber).padStart(2, '0')}-${row.episode.title}-v${row.render.version}.${format}` + return { + format, + filename, + downloadUrl: await presignDownload(storageKey, 300, filename), + downloadExpiresIn: 300, + } + }) + + app.get('/renders/:renderId/deliveries', async (request) => { + const { renderId } = parseWith(renderParams, request.params) + const row = await renderProject(renderId) + await requireProjectPermission(request, row.project.id, 'project:read') + const rows = await db.select({ delivery: deliveries, channelAccount: publishingChannelAccounts }).from(deliveries) + .leftJoin(publishingChannelAccounts, eq(publishingChannelAccounts.id, deliveries.channelAccountId)) + .where(eq(deliveries.renderId, renderId)).orderBy(desc(deliveries.createdAt)) + return rows.map(({ delivery, channelAccount }) => ({ ...delivery, channelAccount: publicChannelAccount(channelAccount) })) + }) + + app.post('/renders/:renderId/deliveries', async (request, reply) => { + const { renderId } = parseWith(renderParams, request.params) + const input = parseWith(createDeliverySchema, request.body) + const row = await renderProject(renderId) + await requireProjectPermission(request, row.project.id, 'publish:create') + if (row.render.status !== 'APPROVED' || !row.render.storageKey) throw errors.conflict('Render must be approved before delivery') + const scheduledAt = input.scheduledAt ? new Date(input.scheduledAt) : null + if (scheduledAt && scheduledAt.getTime() < Date.now() - 60_000) throw errors.badRequest('scheduledAt cannot be in the past') + let channelAccount: typeof publishingChannelAccounts.$inferSelect | null = null + if (input.platform !== 'DOWNLOAD') { + const [account] = await db.select().from(publishingChannelAccounts).where(and( + eq(publishingChannelAccounts.id, input.channelAccountId!), + eq(publishingChannelAccounts.workspaceId, row.project.workspaceId), + eq(publishingChannelAccounts.platform, input.platform), + )).limit(1) + if (!account) throw errors.notFound('Publishing channel account') + if (account.status !== 'CONNECTED' || !account.accessTokenCiphertext) throw errors.conflict('Publishing channel account is not connected') + const readiness = publishingAdapters.get(input.platform)?.readiness() + if (!readiness || readiness.status !== 'CONFIGURED') { + throw errors.serviceUnavailable(`${input.platform} publishing adapter is not configured`, { + platform: input.platform, + missingRequirements: readiness?.missingRequirements ?? ['PUBLISHING_ADAPTER'], + }) + } + channelAccount = account + } + + const delivery = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`delivery:${renderId}:${input.platform}:${channelAccount?.id ?? 'download'}`}))`) + const [existing] = await tx.select({ id: deliveries.id, status: deliveries.status }).from(deliveries).where(and( + eq(deliveries.renderId, renderId), + eq(deliveries.platform, input.platform), + channelAccount ? eq(deliveries.channelAccountId, channelAccount.id) : isNull(deliveries.channelAccountId), + inArray(deliveries.status, ['QUEUED', 'PUBLISHING', 'PUBLISHED']), + )).limit(1) + if (existing) throw errors.conflict(`A ${input.platform} delivery already exists in ${existing.status} state`) + + const [created] = await tx.insert(deliveries).values({ + renderId, + channelAccountId: channelAccount?.id, + platform: input.platform, + status: 'QUEUED', + destination: input.destination, + scheduledAt, + createdById: request.user.sub, + }).returning() + return created + }) + if (!delivery) throw new Error('Failed to create delivery') + let queued: Awaited> + try { + queued = await enqueueGeneration({ + workspaceId: row.project.workspaceId, + projectId: row.project.id, + episodeId: row.episode.id, + userId: request.user.sub, + type: 'DELIVERY_PUBLISH', + idempotencyKey: `delivery-${delivery.id}`, + payload: { deliveryId: delivery.id }, + maxAttempts: 3, + ...(scheduledAt ? { delayMs: Math.max(0, scheduledAt.getTime() - Date.now()) } : {}), + }) + } catch (error) { + await db.update(deliveries).set({ status: 'FAILED', errorMessage: 'Failed to enqueue delivery', updatedAt: new Date() }).where(eq(deliveries.id, delivery.id)) + throw error + } + const [linkedDelivery] = await db.update(deliveries).set({ + jobId: queued.job.id, + updatedAt: new Date(), + }).where(eq(deliveries.id, delivery.id)).returning() + await audit({ request, workspaceId: row.project.workspaceId, action: 'delivery.create', resourceType: 'delivery', resourceId: delivery.id, after: { platform: delivery.platform, channelAccountId: delivery.channelAccountId, jobId: queued.job.id } }) + return reply.code(202).send({ delivery: { ...(linkedDelivery ?? delivery), channelAccount: publicChannelAccount(channelAccount) }, job: queued.job }) + }) + + app.get('/deliveries/:deliveryId', async (request) => { + const { deliveryId } = parseWith(deliveryParams, request.params) + const row = await deliveryProject(deliveryId) + await requireProjectPermission(request, row.project.id, 'project:read') + const downloadable = row.delivery.platform === 'DOWNLOAD' && row.delivery.status === 'PUBLISHED' && Boolean(row.render.storageKey) + return { + ...row.delivery, + render: renderResponse(row.render), + channelAccount: publicChannelAccount(row.channelAccount), + downloadUrl: downloadable ? await presignDownload(row.render.storageKey!, 300) : null, + downloadExpiresIn: downloadable ? 300 : null, + } + }) + + app.delete('/deliveries/:deliveryId', async (request) => { + const { deliveryId } = parseWith(deliveryParams, request.params) + const row = await deliveryProject(deliveryId) + await requireProjectPermission(request, row.project.id, 'publish:create') + if (row.delivery.status !== 'QUEUED') throw errors.conflict(`Delivery in ${row.delivery.status} state cannot be cancelled`) + if (!row.delivery.jobId) throw errors.conflict('Delivery task reference is missing') + + const [job] = await db.select().from(generationJobs).where(eq(generationJobs.id, row.delivery.jobId)).limit(1) + if (!job || job.type !== 'DELIVERY_PUBLISH' || job.input.deliveryId !== deliveryId) { + throw errors.conflict('Delivery task reference is invalid') + } + if (job.status !== 'QUEUED') throw errors.conflict('Delivery has already started publishing') + + const queueJob = await generationQueue.getJob(job.id) + if (queueJob && await queueJob.isActive()) throw errors.conflict('Delivery has already started publishing') + + const cancelledAt = new Date() + const cancelled = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`delivery:${row.render.id}:${row.delivery.platform}`}))`) + const [current] = await tx.select().from(deliveries).where(eq(deliveries.id, deliveryId)).limit(1) + if (!current) throw errors.notFound('Delivery') + if (current.status !== 'QUEUED' || current.jobId !== job.id) { + throw errors.conflict(`Delivery in ${current.status} state cannot be cancelled`) + } + const [cancelledJob] = await tx.update(generationJobs).set({ + status: 'CANCELLED', + completedAt: cancelledAt, + updatedAt: cancelledAt, + }).where(and(eq(generationJobs.id, job.id), eq(generationJobs.status, 'QUEUED'))).returning() + if (!cancelledJob) throw errors.conflict('Delivery has already started publishing') + const [cancelledDelivery] = await tx.update(deliveries).set({ + status: 'CANCELLED', + errorMessage: null, + updatedAt: cancelledAt, + }).where(and(eq(deliveries.id, deliveryId), eq(deliveries.status, 'QUEUED'))).returning() + if (!cancelledDelivery) throw errors.conflict('Delivery has already started publishing') + return cancelledDelivery + }) + if (queueJob) await queueJob.remove().catch(() => undefined) + + await audit({ + request, + workspaceId: row.project.workspaceId, + action: 'delivery.cancel', + resourceType: 'delivery', + resourceId: deliveryId, + before: { status: row.delivery.status, jobId: job.id, scheduledAt: row.delivery.scheduledAt }, + after: { status: 'CANCELLED' }, + }) + return cancelled + }) + + app.post('/deliveries/:deliveryId/retry', async (request, reply) => { + const { deliveryId } = parseWith(deliveryParams, request.params) + const row = await deliveryProject(deliveryId) + await requireProjectPermission(request, row.project.id, 'publish:create') + if (row.delivery.platform !== 'DOWNLOAD') { + if (!row.channelAccount || row.channelAccount.status !== 'CONNECTED' || !row.channelAccount.accessTokenCiphertext) { + throw errors.conflict('Publishing channel account is not connected') + } + const platform = row.delivery.platform as (typeof externalPublishingPlatforms)[number] + const readiness = publishingAdapters.get(platform)?.readiness() + if (!readiness || readiness.status !== 'CONFIGURED') { + throw errors.serviceUnavailable(`${platform} publishing adapter is not configured`, { + platform, + missingRequirements: readiness?.missingRequirements ?? ['PUBLISHING_ADAPTER'], + }) + } + } + + const delivery = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`delivery:${row.render.id}:${row.delivery.platform}`}))`) + const [current] = await tx.select().from(deliveries).where(eq(deliveries.id, deliveryId)).limit(1) + if (!current) throw errors.notFound('Delivery') + if (!['FAILED', 'CANCELLED'].includes(current.status)) throw errors.conflict(`Delivery in ${current.status} state cannot be retried`) + if (row.render.status !== 'APPROVED' || !row.render.storageKey) throw errors.conflict('Render must remain approved before retrying delivery') + + const [conflicting] = await tx.select({ id: deliveries.id, status: deliveries.status }).from(deliveries).where(and( + eq(deliveries.renderId, current.renderId), + eq(deliveries.platform, current.platform), + ne(deliveries.id, current.id), + inArray(deliveries.status, ['QUEUED', 'PUBLISHING', 'PUBLISHED']), + )).limit(1) + if (conflicting) throw errors.conflict(`Another ${current.platform} delivery already exists in ${conflicting.status} state`) + + const [updated] = await tx.update(deliveries).set({ + status: 'QUEUED', + errorMessage: null, + externalId: null, + publishedUrl: null, + publishedAt: null, + scheduledAt: null, + jobId: null, + updatedAt: new Date(), + }).where(eq(deliveries.id, deliveryId)).returning() + return updated + }) + if (!delivery) throw new Error('Failed to retry delivery') + + let queued: Awaited> + try { + queued = await enqueueGeneration({ + workspaceId: row.project.workspaceId, + projectId: row.project.id, + episodeId: row.episode.id, + userId: request.user.sub, + type: 'DELIVERY_PUBLISH', + idempotencyKey: `delivery-retry-${delivery.id}-${crypto.randomUUID()}`, + payload: { deliveryId: delivery.id }, + maxAttempts: 3, + }) + } catch (error) { + await db.update(deliveries).set({ + status: 'FAILED', + errorMessage: 'Failed to enqueue delivery retry', + updatedAt: new Date(), + }).where(eq(deliveries.id, delivery.id)) + throw error + } + const [linkedDelivery] = await db.update(deliveries).set({ + jobId: queued.job.id, + updatedAt: new Date(), + }).where(eq(deliveries.id, delivery.id)).returning() + await audit({ + request, + workspaceId: row.project.workspaceId, + action: 'delivery.retry', + resourceType: 'delivery', + resourceId: delivery.id, + before: { status: row.delivery.status, errorMessage: row.delivery.errorMessage }, + after: { status: 'QUEUED', jobId: queued.job.id }, + }) + return reply.code(202).send({ delivery: linkedDelivery ?? delivery, job: queued.job }) + }) + + app.get('/deliveries/:deliveryId/download', async (request, reply) => { + const { deliveryId } = parseWith(deliveryParams, request.params) + const row = await deliveryProject(deliveryId) + await requireProjectPermission(request, row.project.id, 'project:read') + if (row.delivery.status !== 'PUBLISHED' || !row.render.storageKey) throw errors.conflict('Delivery is not available') + return reply.redirect(await presignDownload(row.render.storageKey, 300)) + }) +} diff --git a/server/src/routes/project-management.integration.test.ts b/server/src/routes/project-management.integration.test.ts new file mode 100644 index 0000000..e8e0c0b --- /dev/null +++ b/server/src/routes/project-management.integration.test.ts @@ -0,0 +1,147 @@ +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { episodes, projects, users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('project and episode management', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + let episodeId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ method, url, headers: { authorization: `Bearer ${token}` }, payload }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.statusCode === 204 ? null : response.json() + } + + async function register(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp() + owner = await register('project-owner') + viewer = await register('project-viewer') + workspaceId = owner.workspaces[0].id + + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '项目管理测试', + logline: '初始故事梗概', + genre: '都市悬疑', + visualBible: {}, + }) + projectId = project.id + const episode = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 3, + title: '初始分集', + synopsis: '初始分集梗概', + targetDurationSeconds: 90, + }) + episodeId = episode.id + await request(owner.accessToken, 'POST', `/api/v1/episodes/${episodeId}/scripts`, { + title: '初始分集', + content: { source: 'test' }, + plainText: '需要在资料更新后保留的剧本。', + changeSummary: '初始版本', + }) + }) + + afterAll(async () => { + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('updates project and episode metadata without replacing production history', async () => { + const updatedProject = await request(owner.accessToken, 'PATCH', `/api/v1/projects/${projectId}`, { + name: '更新后的项目名称', + logline: '更新后的故事梗概', + genre: '近未来悬疑', + status: 'ACTIVE', + visualBible: { styleDescription: '低饱和雨夜,写实国漫' }, + }) + expect(updatedProject).toMatchObject({ + name: '更新后的项目名称', + logline: '更新后的故事梗概', + genre: '近未来悬疑', + status: 'ACTIVE', + visualBible: { styleDescription: '低饱和雨夜,写实国漫' }, + }) + + const updatedEpisode = await request(owner.accessToken, 'PATCH', `/api/v1/episodes/${episodeId}`, { + title: '更新后的分集', + synopsis: '更新后的分集梗概', + targetDurationSeconds: 150, + }) + expect(updatedEpisode).toMatchObject({ + episodeNumber: 3, + title: '更新后的分集', + synopsis: '更新后的分集梗概', + targetDurationSeconds: 150, + }) + + const detail = await request(owner.accessToken, 'GET', `/api/v1/episodes/${episodeId}`) + expect(detail.currentScript.plainText).toBe('需要在资料更新后保留的剧本。') + expect(detail.episodeNumber).toBe(3) + }) + + it('keeps project and episode mutations unavailable to read-only members', async () => { + const projectUpdate = await inject(viewer.accessToken, 'PATCH', `/api/v1/projects/${projectId}`, { name: '越权修改' }) + expect(projectUpdate.statusCode, projectUpdate.body).toBe(403) + + const episodeUpdate = await inject(viewer.accessToken, 'PATCH', `/api/v1/episodes/${episodeId}`, { title: '越权修改' }) + expect(episodeUpdate.statusCode, episodeUpdate.body).toBe(403) + + const archive = await inject(viewer.accessToken, 'DELETE', `/api/v1/projects/${projectId}`) + expect(archive.statusCode, archive.body).toBe(403) + }) + + it('soft-archives a project while preserving its episodes and excludes it from active lists', async () => { + const archived = await request(owner.accessToken, 'DELETE', `/api/v1/projects/${projectId}`) + expect(archived.status).toBe('ARCHIVED') + + const activeProjects = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/projects`) + expect(activeProjects.some((project: { id: string }) => project.id === projectId)).toBe(false) + + const [persistedProject] = await db.select().from(projects).where(eq(projects.id, projectId)).limit(1) + const [persistedEpisode] = await db.select().from(episodes).where(eq(episodes.id, episodeId)).limit(1) + expect(persistedProject?.status).toBe('ARCHIVED') + expect(persistedEpisode?.title).toBe('更新后的分集') + }) +}) diff --git a/server/src/routes/projects.ts b/server/src/routes/projects.ts new file mode 100644 index 0000000..62ffd82 --- /dev/null +++ b/server/src/routes/projects.ts @@ -0,0 +1,82 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq, ne } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { episodes, projects } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission, requireWorkspacePermission } from '../lib/permissions.js' +import { slugify } from '../lib/slug.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const projectParams = z.object({ projectId: z.uuid() }) +const createProjectSchema = z.object({ + name: z.string().trim().min(2).max(180), + logline: z.string().max(2000).default(''), + genre: z.string().trim().min(1).max(80).default('都市悬疑'), + visualBible: z.record(z.string(), z.unknown()).default({}), +}) +const updateProjectSchema = createProjectSchema.partial().extend({ + status: z.enum(['DRAFT', 'ACTIVE', 'ARCHIVED']).optional(), +}) + +export async function projectRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/projects', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'project:read') + return db.select().from(projects).where(and(eq(projects.workspaceId, workspaceId), ne(projects.status, 'ARCHIVED'))).orderBy(desc(projects.updatedAt)) + }) + + app.post('/workspaces/:workspaceId/projects', async (request, reply) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(createProjectSchema, request.body) + await requireWorkspacePermission(request, workspaceId, 'project:write') + + const [project] = await db.insert(projects).values({ + workspaceId, + createdById: request.user.sub, + name: input.name, + slug: `${slugify(input.name)}-${crypto.randomUUID().slice(0, 6)}`, + logline: input.logline, + genre: input.genre, + visualBible: input.visualBible, + status: 'DRAFT', + }).returning() + if (!project) throw new Error('Failed to create project') + await audit({ request, workspaceId, action: 'project.create', resourceType: 'project', resourceId: project.id, after: project }) + return reply.code(201).send(project) + }) + + app.get('/projects/:projectId', async (request) => { + const { projectId } = parseWith(projectParams, request.params) + const { project } = await requireProjectPermission(request, projectId, 'project:read') + const [fullProject] = await db.select().from(projects).where(eq(projects.id, project.id)).limit(1) + if (!fullProject) throw errors.notFound('Project') + const episodeRows = await db.select().from(episodes).where(eq(episodes.projectId, projectId)).orderBy(episodes.episodeNumber) + return { ...fullProject, episodes: episodeRows } + }) + + app.patch('/projects/:projectId', async (request) => { + const { projectId } = parseWith(projectParams, request.params) + const input = parseWith(updateProjectSchema, request.body) + const { project } = await requireProjectPermission(request, projectId, 'project:write') + const [before] = await db.select().from(projects).where(eq(projects.id, projectId)).limit(1) + if (!before) throw errors.notFound('Project') + const [updated] = await db.update(projects).set({ ...input, updatedAt: new Date() }).where(eq(projects.id, projectId)).returning() + if (!updated) throw errors.notFound('Project') + await audit({ request, workspaceId: project.workspaceId, action: 'project.update', resourceType: 'project', resourceId: projectId, before, after: updated }) + return updated + }) + + app.delete('/projects/:projectId', async (request, reply) => { + const { projectId } = parseWith(projectParams, request.params) + const { project } = await requireProjectPermission(request, projectId, 'project:write') + const [updated] = await db.update(projects).set({ status: 'ARCHIVED', updatedAt: new Date() }).where(eq(projects.id, projectId)).returning() + await audit({ request, workspaceId: project.workspaceId, action: 'project.archive', resourceType: 'project', resourceId: projectId, after: { status: 'ARCHIVED' } }) + return reply.code(200).send(updated) + }) +} diff --git a/server/src/routes/publishing.integration.test.ts b/server/src/routes/publishing.integration.test.ts new file mode 100644 index 0000000..cc0456c --- /dev/null +++ b/server/src/routes/publishing.integration.test.ts @@ -0,0 +1,301 @@ +import type { FastifyInstance } from 'fastify' +import { eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { + deliveries, + publishingChannelAccounts, + publishingOauthStates, + publishingWebhookEvents, + renders, + users, + workspaces, +} from '../db/schema.js' +import { connectorWebhookSignature } from '../publishing/connector.js' +import type { + PublishingAccountCredentials, + PublishingAdapter, + PublishingAdapterRegistry, + PublishingAuthorizationResult, + PublishingResult, +} from '../publishing/types.js' +import { generationQueue } from '../queue/client.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +class FakePublishingAdapter implements PublishingAdapter { + readonly platform = 'DOUYIN' as const + authorizationState = '' + revokedAccounts: string[] = [] + + readiness() { + return { status: 'CONFIGURED' as const, missingRequirements: [] } + } + + async createAuthorization(input: { state: string }): Promise { + this.authorizationState = input.state + return { + authorizationUrl: `https://open.douyin.test/oauth?state=${encodeURIComponent(input.state)}`, + codeVerifier: 'pkce-verifier-with-at-least-32-characters', + } + } + + async exchangeAuthorization(input: { code: string; codeVerifier?: string }): Promise { + expect(input.code).toBe('authorization-code-one') + expect(input.codeVerifier).toBe('pkce-verifier-with-at-least-32-characters') + return { + externalAccountId: 'douyin-creator-1001', + displayName: '漫剧创作者', + avatarUrl: 'https://images.example.cn/avatar.png', + accessToken: 'plain-access-token-must-not-leak', + refreshToken: 'plain-refresh-token-must-not-leak', + tokenExpiresAt: new Date(Date.now() + 3600_000).toISOString(), + scopes: ['video.create', 'video.data'], + } + } + + async publish(): Promise { + return { status: 'PUBLISHING', externalId: 'provider-video-1' } + } + + async revoke(input: { externalAccountId: string }) { + this.revokedAccounts.push(input.externalAccountId) + } +} + +describe.sequential('publishing channels and provider callbacks', () => { + let app: FastifyInstance + let owner: Session + let viewer: Session + let workspaceId = '' + let projectId = '' + let episodeId = '' + let renderId = '' + let channelAccountId = '' + const webhookSecret = 'publishing-webhook-secret-with-32-characters' + const adapter = new FakePublishingAdapter() + const adapters: PublishingAdapterRegistry = new Map([['DOUYIN', adapter]]) + const userIds: string[] = [] + const workspaceIds: string[] = [] + const queueJobIds: string[] = [] + + async function inject(token: string | null, method: string, url: string, payload?: unknown, headers: Record = {}) { + return app.inject({ + method, + url, + headers: { ...(token ? { authorization: `Bearer ${token}` } : {}), ...headers }, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + workspaceIds.push(session.workspaces[0]!.id) + return session + } + + beforeAll(async () => { + app = await buildApp({ publishingAdapters: adapters, publishingWebhookSecret: webhookSecret }) + owner = await registerAccount('publishing-owner') + viewer = await registerAccount('publishing-viewer') + workspaceId = owner.workspaces[0]!.id + const project = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '平台发布测试项目', + logline: '验证渠道账号和发布回执。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + const episode = await request(owner.accessToken, 'POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '渠道发布测试集', + synopsis: '', + targetDurationSeconds: 30, + }) + episodeId = episode.id + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: viewer.user.email, + role: 'VIEWER', + }) + const [render] = await db.insert(renders).values({ + episodeId, + version: 1, + status: 'APPROVED', + storageKey: `${workspaceId}/${projectId}/generated/renders/publishing.mp4`, + mimeType: 'video/mp4', + byteSize: 2048, + durationMs: 5000, + width: 1080, + height: 1920, + fps: 24, + settings: {}, + createdById: owner.user.id, + }).returning() + renderId = render!.id + }) + + afterAll(async () => { + for (const jobId of queueJobIds) { + const job = await generationQueue.getJob(jobId) + if (job && !(await job.isActive())) await job.remove().catch(() => undefined) + } + if (workspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, workspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('authorizes channel binding once and never exposes plaintext credentials', async () => { + const listed = await request(viewer.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/publishing/channels`) + expect(listed.canManage).toBe(false) + expect(listed.platforms.find((platform: { id: string }) => platform.id === 'DOUYIN').readiness.status).toBe('CONFIGURED') + + const forbidden = await inject(viewer.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/publishing/oauth/start`, { platform: 'DOUYIN' }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + + const started = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/publishing/oauth/start`, { + platform: 'DOUYIN', + returnPath: '/?page=publish', + }) + expect(started.authorizationUrl).toContain('https://open.douyin.test/oauth') + expect(adapter.authorizationState).toHaveLength(43) + const [oauthState] = await db.select().from(publishingOauthStates) + .where(eq(publishingOauthStates.workspaceId, workspaceId)).limit(1) + expect(oauthState?.stateHash).not.toBe(adapter.authorizationState) + expect(oauthState?.codeVerifierCiphertext).not.toContain('pkce-verifier') + + const callback = await inject(null, 'GET', `/api/v1/publishing/oauth/callback/douyin?state=${encodeURIComponent(adapter.authorizationState)}&code=authorization-code-one`) + expect(callback.statusCode, callback.body).toBe(302) + expect(callback.headers.location).toContain('publishing=connected') + + const [account] = await db.select().from(publishingChannelAccounts) + .where(eq(publishingChannelAccounts.workspaceId, workspaceId)).limit(1) + expect(account?.accessTokenCiphertext).not.toContain('plain-access-token') + expect(account?.refreshTokenCiphertext).not.toContain('plain-refresh-token') + channelAccountId = account!.id + + const channels = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/publishing/channels`) + const publicAccount = channels.platforms.find((platform: { id: string }) => platform.id === 'DOUYIN').accounts[0] + expect(publicAccount).toMatchObject({ id: channelAccountId, displayName: '漫剧创作者', status: 'CONNECTED' }) + expect(JSON.stringify(publicAccount)).not.toContain('Ciphertext') + expect(JSON.stringify(publicAccount)).not.toContain('plain-access-token') + + const replay = await inject(null, 'GET', `/api/v1/publishing/oauth/callback/douyin?state=${encodeURIComponent(adapter.authorizationState)}&code=authorization-code-one`) + expect(replay.statusCode, replay.body).toBe(400) + }) + + it('requires a matching connected channel and supports isolated scheduled delivery', async () => { + const missingAccount = await inject(owner.accessToken, 'POST', `/api/v1/renders/${renderId}/deliveries`, { platform: 'DOUYIN' }) + expect(missingAccount.statusCode, missingAccount.body).toBe(400) + + const createdResponse = await inject(owner.accessToken, 'POST', `/api/v1/renders/${renderId}/deliveries`, { + platform: 'DOUYIN', + channelAccountId, + destination: { title: '渠道发布测试集', visibility: 'PUBLIC' }, + scheduledAt: new Date(Date.now() + 30 * 60_000).toISOString(), + }) + expect(createdResponse.statusCode, createdResponse.body).toBe(202) + const created = createdResponse.json() + queueJobIds.push(created.job.id) + expect(created.delivery.channelAccount).toMatchObject({ id: channelAccountId, platform: 'DOUYIN' }) + + const forbidden = await inject(viewer.accessToken, 'POST', `/api/v1/renders/${renderId}/deliveries`, { + platform: 'DOUYIN', + channelAccountId, + }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + const cancelled = await request(owner.accessToken, 'DELETE', `/api/v1/deliveries/${created.delivery.id}`) + expect(cancelled.status).toBe('CANCELLED') + }) + + it('applies signed callbacks idempotently and ignores stale terminal regressions', async () => { + const [delivery] = await db.insert(deliveries).values({ + renderId, + channelAccountId, + platform: 'DOUYIN', + status: 'PUBLISHING', + externalId: 'provider-video-callback', + createdById: owner.user.id, + }).returning() + const occurredAt = new Date().toISOString() + const event = { + eventId: `douyin-event-published-${delivery!.id}`, + platform: 'DOUYIN', + deliveryId: delivery!.id, + externalId: 'provider-video-callback', + status: 'PUBLISHED', + occurredAt, + publishedUrl: 'https://www.douyin.com/video/provider-video-callback', + } + const payload = JSON.stringify(event) + const published = await inject(null, 'POST', '/api/v1/publishing/webhooks/connector', payload, { + 'content-type': 'application/json', + 'x-frameflow-signature': connectorWebhookSignature(payload, webhookSecret), + }) + expect(published.statusCode, published.body).toBe(200) + expect(published.json()).toEqual({ received: true, duplicate: false, applied: true }) + + const duplicate = await inject(null, 'POST', '/api/v1/publishing/webhooks/connector', payload, { + 'content-type': 'application/json', + 'x-frameflow-signature': connectorWebhookSignature(payload, webhookSecret), + }) + expect(duplicate.json()).toEqual({ received: true, duplicate: true, applied: false }) + + const stalePayload = JSON.stringify({ + ...event, + eventId: `douyin-event-stale-${delivery!.id}`, + status: 'FAILED', + occurredAt: new Date(Date.parse(occurredAt) - 10_000).toISOString(), + errorMessage: 'late provider timeout', + }) + const stale = await inject(null, 'POST', '/api/v1/publishing/webhooks/connector', stalePayload, { + 'content-type': 'application/json', + 'x-frameflow-signature': connectorWebhookSignature(stalePayload, webhookSecret), + }) + expect(stale.json()).toEqual({ received: true, duplicate: false, applied: false }) + const [stored] = await db.select().from(deliveries).where(eq(deliveries.id, delivery!.id)).limit(1) + expect(stored).toMatchObject({ status: 'PUBLISHED', publishedUrl: event.publishedUrl, errorMessage: null }) + const events = await db.select().from(publishingWebhookEvents).where(eq(publishingWebhookEvents.deliveryId, delivery!.id)) + expect(events).toHaveLength(2) + expect(events.filter((row) => row.applied)).toHaveLength(1) + + const invalid = await inject(null, 'POST', '/api/v1/publishing/webhooks/connector', payload, { + 'content-type': 'application/json', + 'x-frameflow-signature': 'sha256=invalid', + }) + expect(invalid.statusCode, invalid.body).toBe(400) + }) + + it('revokes the provider grant and removes stored credentials', async () => { + const revoked = await request(owner.accessToken, 'DELETE', `/api/v1/publishing/channels/${channelAccountId}`) + expect(revoked.status).toBe('REVOKED') + expect(adapter.revokedAccounts).toEqual(['douyin-creator-1001']) + const [stored] = await db.select().from(publishingChannelAccounts) + .where(eq(publishingChannelAccounts.id, channelAccountId)).limit(1) + expect(stored?.accessTokenCiphertext).toBeNull() + expect(stored?.refreshTokenCiphertext).toBeNull() + }) +}) diff --git a/server/src/routes/publishing.ts b/server/src/routes/publishing.ts new file mode 100644 index 0000000..07d36e1 --- /dev/null +++ b/server/src/routes/publishing.ts @@ -0,0 +1,392 @@ +import { createHash, randomBytes } from 'node:crypto' +import type { FastifyInstance, FastifyRequest } from 'fastify' +import { and, eq, lt } from 'drizzle-orm' +import { z } from 'zod' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { + deliveries, + episodes, + projects, + publishingChannelAccounts, + publishingOauthStates, + publishingWebhookEvents, + renders, +} from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { decryptCredential, encryptCredential } from '../lib/credential-vault.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { createNotification } from '../lib/notifications.js' +import { requireWorkspacePermission } from '../lib/permissions.js' +import { publishRealtimeEvent } from '../lib/realtime.js' +import { + createPublishingAdapterRegistry, + verifyConnectorWebhookSignature, +} from '../publishing/connector.js' +import { + externalPublishingPlatforms, + publishingPlatformDetails, + type ExternalPublishingPlatform, + type PublishingAdapterRegistry, +} from '../publishing/types.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const channelParams = z.object({ channelAccountId: z.uuid() }) +const platformParams = z.object({ + platform: z.string().transform((value) => value.toUpperCase()).pipe(z.enum(externalPublishingPlatforms)), +}) +const startOauthSchema = z.object({ + platform: z.enum(externalPublishingPlatforms), + returnPath: z.string().max(500).refine((value) => value.startsWith('/') && !value.startsWith('//'), 'returnPath must be an application-relative path').default('/?publishing=connected'), +}) +const oauthCallbackQuery = z.object({ + state: z.string().min(32).max(512), + code: z.string().min(1).max(4096).optional(), + error: z.string().max(255).optional(), + error_description: z.string().max(1000).optional(), +}) +export const publishingWebhookSchema = z.object({ + eventId: z.string().min(1).max(255), + platform: z.enum(externalPublishingPlatforms), + deliveryId: z.uuid(), + externalId: z.string().min(1).max(255), + status: z.enum(['PUBLISHING', 'PUBLISHED', 'FAILED']), + occurredAt: z.iso.datetime({ offset: true }), + publishedUrl: z.url().optional(), + errorMessage: z.string().max(4000).optional(), +}) + +export type PublishingWebhookInput = z.infer + +interface PublishingRouteOptions { + publishingAdapters?: PublishingAdapterRegistry + publishingWebhookSecret?: string +} + +function stateHash(state: string) { + return createHash('sha256').update(state).digest('hex') +} + +function platformCallbackUrl(platform: ExternalPublishingPlatform) { + return new URL(`/api/v1/publishing/oauth/callback/${platform.toLowerCase()}`, `${config.API_PUBLIC_ORIGIN}/`).toString() +} + +function browserRedirect(returnPath: string, outcome: 'connected' | 'error') { + const origin = config.WEB_ORIGIN.split(',')[0]?.trim() || 'http://127.0.0.1:4173' + const target = new URL(returnPath, `${origin}/`) + target.searchParams.set('publishing', outcome) + return target.toString() +} + +function publicChannelAccount(account: typeof publishingChannelAccounts.$inferSelect) { + return { + id: account.id, + workspaceId: account.workspaceId, + platform: account.platform, + externalAccountId: account.externalAccountId, + displayName: account.displayName, + avatarUrl: account.avatarUrl, + status: account.status, + tokenExpiresAt: account.tokenExpiresAt, + scopes: account.scopes, + lastVerifiedAt: account.lastVerifiedAt, + errorCode: account.errorCode, + errorMessage: account.errorMessage, + connectedById: account.connectedById, + createdAt: account.createdAt, + updatedAt: account.updatedAt, + } +} + +function publishingTransitionAllowed(current: typeof deliveries.$inferSelect.status, next: PublishingWebhookInput['status']) { + if (current === 'QUEUED') return true + if (current === 'PUBLISHING') return true + if (current === 'PUBLISHED') return next === 'PUBLISHED' + if (current === 'FAILED') return next === 'FAILED' + return false +} + +export async function applyPublishingWebhookEvent(input: PublishingWebhookInput) { + const occurredAt = new Date(input.occurredAt) + const eventKey = `${input.platform}:${input.eventId}` + + return db.transaction(async (tx) => { + const [row] = await tx.select({ + delivery: deliveries, + episode: episodes, + project: projects, + }).from(deliveries) + .innerJoin(renders, eq(renders.id, deliveries.renderId)) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(deliveries.id, input.deliveryId)).limit(1) + if (!row) throw errors.notFound('Delivery') + + const [inserted] = await tx.insert(publishingWebhookEvents).values({ + eventKey, + eventId: input.eventId, + workspaceId: row.project.workspaceId, + platform: input.platform, + deliveryId: input.deliveryId, + status: input.status, + providerOccurredAt: occurredAt, + payload: input, + }).onConflictDoNothing().returning({ eventKey: publishingWebhookEvents.eventKey }) + if (!inserted) return { duplicate: true, applied: false, workspaceId: row.project.workspaceId, delivery: row.delivery } + + const platformMatches = row.delivery.platform === input.platform + const externalIdMatches = !row.delivery.externalId || row.delivery.externalId === input.externalId + const eventIsCurrent = !row.delivery.lastProviderEventAt || row.delivery.lastProviderEventAt <= occurredAt + const transitionAllowed = publishingTransitionAllowed(row.delivery.status, input.status) + const applied = platformMatches && externalIdMatches && eventIsCurrent && transitionAllowed + if (!applied) { + return { duplicate: false, applied: false, workspaceId: row.project.workspaceId, delivery: row.delivery } + } + + const [delivery] = await tx.update(deliveries).set({ + status: input.status, + externalId: input.externalId, + publishedUrl: input.status === 'PUBLISHED' ? input.publishedUrl ?? row.delivery.publishedUrl : row.delivery.publishedUrl, + publishedAt: input.status === 'PUBLISHED' ? occurredAt : row.delivery.publishedAt, + errorMessage: input.status === 'FAILED' ? input.errorMessage ?? '平台发布失败' : null, + lastProviderEventAt: occurredAt, + updatedAt: new Date(), + }).where(eq(deliveries.id, input.deliveryId)).returning() + await tx.update(publishingWebhookEvents).set({ applied: true }).where(eq(publishingWebhookEvents.eventKey, eventKey)) + if (input.status === 'PUBLISHED') { + await tx.update(episodes).set({ status: 'PUBLISHED', updatedAt: new Date() }).where(eq(episodes.id, row.episode.id)) + } + return { duplicate: false, applied: true, workspaceId: row.project.workspaceId, delivery: delivery ?? row.delivery } + }) +} + +async function notifyPublishingCallback(result: Awaited>) { + if (!result.applied) return + await publishRealtimeEvent({ + workspaceId: result.workspaceId, + type: 'delivery.updated', + resourceType: 'delivery', + resourceId: result.delivery.id, + payload: { + id: result.delivery.id, + platform: result.delivery.platform, + status: result.delivery.status, + publishedUrl: result.delivery.publishedUrl, + errorMessage: result.delivery.errorMessage, + }, + }) + if (!['PUBLISHED', 'FAILED'].includes(result.delivery.status)) return + const published = result.delivery.status === 'PUBLISHED' + await createNotification({ + workspaceId: result.workspaceId, + userId: result.delivery.createdById, + kind: published ? 'DELIVERY_PUBLISHED' : 'DELIVERY_FAILED', + tone: published ? 'SUCCESS' : 'ERROR', + title: published ? '平台发布成功' : '平台发布失败', + body: published ? '平台已确认接收并发布成片。' : result.delivery.errorMessage ?? '平台返回发布失败,请检查渠道账号后重试。', + page: 'publish', + resourceType: 'delivery', + resourceId: result.delivery.id, + dedupeKey: `delivery:${result.delivery.id}:${result.delivery.status}`, + metadata: { platform: result.delivery.platform, status: result.delivery.status }, + }) +} + +export async function publishingRoutes(app: FastifyInstance, options: PublishingRouteOptions = {}) { + const adapters = options.publishingAdapters ?? createPublishingAdapterRegistry() + const webhookSecret = options.publishingWebhookSecret ?? config.PUBLISHING_CONNECTOR_SECRET + + app.get('/workspaces/:workspaceId/publishing/channels', { preHandler: requireAuth }, async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const membership = await requireWorkspacePermission(request, workspaceId, 'project:read') + const accounts = await db.select().from(publishingChannelAccounts) + .where(eq(publishingChannelAccounts.workspaceId, workspaceId)) + return { + canManage: ['OWNER', 'ADMIN'].includes(membership.role), + platforms: externalPublishingPlatforms.map((platform) => ({ + id: platform, + ...publishingPlatformDetails[platform], + readiness: adapters.get(platform)?.readiness() ?? { status: 'NOT_CONFIGURED', missingRequirements: ['PUBLISHING_ADAPTER'] }, + accounts: accounts.filter((account) => account.platform === platform).map(publicChannelAccount), + })), + } + }) + + app.post('/workspaces/:workspaceId/publishing/oauth/start', { preHandler: requireAuth }, async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(startOauthSchema, request.body) + await requireWorkspacePermission(request, workspaceId, 'publishing:manage') + const adapter = adapters.get(input.platform) + if (!adapter) throw errors.serviceUnavailable(`${input.platform} publishing adapter is unavailable`) + + await db.delete(publishingOauthStates).where(lt(publishingOauthStates.expiresAt, new Date())) + const state = randomBytes(32).toString('base64url') + const callbackUrl = platformCallbackUrl(input.platform) + const authorization = await adapter.createAuthorization({ state, callbackUrl }) + const expiresAt = new Date(Date.now() + 10 * 60_000) + await db.insert(publishingOauthStates).values({ + stateHash: stateHash(state), + workspaceId, + platform: input.platform, + codeVerifierCiphertext: authorization.codeVerifier ? encryptCredential(authorization.codeVerifier) : null, + returnPath: input.returnPath, + createdById: request.user.sub, + expiresAt, + }) + await audit({ + request, + workspaceId, + action: 'publishing.oauth.start', + resourceType: 'publishing_channel_account', + after: { platform: input.platform, expiresAt }, + }) + return { authorizationUrl: authorization.authorizationUrl, expiresAt } + }) + + app.get('/publishing/oauth/callback/:platform', async (request, reply) => { + const { platform } = parseWith(platformParams, request.params) + const input = parseWith(oauthCallbackQuery, request.query) + const [state] = await db.select().from(publishingOauthStates) + .where(eq(publishingOauthStates.stateHash, stateHash(input.state))).limit(1) + if (!state || state.platform !== platform || state.consumedAt || state.expiresAt <= new Date()) { + throw errors.badRequest('OAuth state is invalid or expired') + } + const [consumed] = await db.update(publishingOauthStates).set({ consumedAt: new Date() }).where(and( + eq(publishingOauthStates.stateHash, state.stateHash), + eq(publishingOauthStates.platform, platform), + )).returning() + if (!consumed) throw errors.badRequest('OAuth state has already been consumed') + if (input.error || !input.code) { + await audit({ + request, + workspaceId: state.workspaceId, + action: 'publishing.oauth.failed', + resourceType: 'publishing_channel_account', + after: { platform, error: input.error ?? 'authorization_code_missing' }, + }) + return reply.redirect(browserRedirect(state.returnPath, 'error')) + } + + const adapter = adapters.get(platform) + if (!adapter) throw errors.serviceUnavailable(`${platform} publishing adapter is unavailable`) + let credentials + try { + credentials = await adapter.exchangeAuthorization({ + code: input.code, + callbackUrl: platformCallbackUrl(platform), + ...(state.codeVerifierCiphertext ? { codeVerifier: decryptCredential(state.codeVerifierCiphertext) } : {}), + }) + } catch (error) { + request.log.error({ err: error, workspaceId: state.workspaceId, platform }, 'Publishing OAuth exchange failed') + return reply.redirect(browserRedirect(state.returnPath, 'error')) + } + + const values = { + displayName: credentials.displayName, + avatarUrl: credentials.avatarUrl ?? null, + status: 'CONNECTED' as const, + accessTokenCiphertext: encryptCredential(credentials.accessToken), + refreshTokenCiphertext: credentials.refreshToken ? encryptCredential(credentials.refreshToken) : null, + tokenExpiresAt: credentials.tokenExpiresAt ? new Date(credentials.tokenExpiresAt) : null, + scopes: credentials.scopes ?? [], + metadata: credentials.metadata ?? {}, + connectedById: state.createdById, + lastVerifiedAt: new Date(), + errorCode: null, + errorMessage: null, + updatedAt: new Date(), + } + const [account] = await db.insert(publishingChannelAccounts).values({ + workspaceId: state.workspaceId, + platform, + externalAccountId: credentials.externalAccountId, + ...values, + }).onConflictDoUpdate({ + target: [publishingChannelAccounts.workspaceId, publishingChannelAccounts.platform, publishingChannelAccounts.externalAccountId], + set: values, + }).returning() + if (!account) throw new Error('Failed to save publishing channel account') + await audit({ + request, + workspaceId: state.workspaceId, + action: 'publishing.channel.connect', + resourceType: 'publishing_channel_account', + resourceId: account.id, + after: { platform, externalAccountId: account.externalAccountId, displayName: account.displayName }, + }) + await publishRealtimeEvent({ + workspaceId: state.workspaceId, + type: 'publishing.channel.updated', + resourceType: 'publishing_channel_account', + resourceId: account.id, + payload: { account: publicChannelAccount(account) }, + }) + return reply.redirect(browserRedirect(state.returnPath, 'connected')) + }) + + app.delete('/publishing/channels/:channelAccountId', { preHandler: requireAuth }, async (request) => { + const { channelAccountId } = parseWith(channelParams, request.params) + const [account] = await db.select().from(publishingChannelAccounts) + .where(eq(publishingChannelAccounts.id, channelAccountId)).limit(1) + if (!account) throw errors.notFound('Publishing channel account') + await requireWorkspacePermission(request, account.workspaceId, 'publishing:manage') + if (account.status === 'REVOKED') return publicChannelAccount(account) + const adapter = adapters.get(account.platform as ExternalPublishingPlatform) + if (!adapter || !account.accessTokenCiphertext) throw errors.serviceUnavailable(`${account.platform} publishing adapter is unavailable`) + await adapter.revoke({ + externalAccountId: account.externalAccountId, + accessToken: decryptCredential(account.accessTokenCiphertext), + ...(account.refreshTokenCiphertext ? { refreshToken: decryptCredential(account.refreshTokenCiphertext) } : {}), + }) + const [revoked] = await db.update(publishingChannelAccounts).set({ + status: 'REVOKED', + accessTokenCiphertext: null, + refreshTokenCiphertext: null, + tokenExpiresAt: null, + updatedAt: new Date(), + }).where(eq(publishingChannelAccounts.id, account.id)).returning() + await audit({ + request, + workspaceId: account.workspaceId, + action: 'publishing.channel.revoke', + resourceType: 'publishing_channel_account', + resourceId: account.id, + before: { platform: account.platform, status: account.status }, + after: { platform: account.platform, status: 'REVOKED' }, + }) + await publishRealtimeEvent({ + workspaceId: account.workspaceId, + type: 'publishing.channel.updated', + resourceType: 'publishing_channel_account', + resourceId: account.id, + payload: { account: publicChannelAccount(revoked ?? account) }, + }) + return publicChannelAccount(revoked ?? account) + }) + + app.post('/publishing/webhooks/connector', { + bodyLimit: 1024 * 1024, + config: { rawBody: true, rateLimit: { max: 600, timeWindow: '1 minute' } }, + }, async (request: FastifyRequest) => { + const signature = request.headers['x-frameflow-signature'] + if (!Buffer.isBuffer(request.rawBody) || typeof signature !== 'string' || !verifyConnectorWebhookSignature(request.rawBody, signature, webhookSecret)) { + throw errors.badRequest('Publishing webhook signature is invalid') + } + const event = parseWith(publishingWebhookSchema, request.body) + const result = await applyPublishingWebhookEvent(event) + await notifyPublishingCallback(result) + if (!result.duplicate && result.applied) { + await audit({ + request, + workspaceId: result.workspaceId, + action: 'publishing.webhook.process', + resourceType: 'delivery', + resourceId: result.delivery.id, + after: { eventId: event.eventId, platform: event.platform, status: event.status }, + }) + } + return { received: true, duplicate: result.duplicate, applied: result.applied } + }) +} diff --git a/server/src/routes/readiness.integration.test.ts b/server/src/routes/readiness.integration.test.ts new file mode 100644 index 0000000..0470b79 --- /dev/null +++ b/server/src/routes/readiness.integration.test.ts @@ -0,0 +1,292 @@ +import type { FastifyInstance } from 'fastify' +import { and, eq, inArray, sql } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' +import { buildApp } from '../app.js' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { auditLogs, providerVerifications, users, workspaces } from '../db/schema.js' +import type { ProviderConfiguration } from '../providers/readiness.js' +import { publishWorkerHeartbeat } from '../queue/heartbeat.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +const verificationConfiguration: ProviderConfiguration = { + openaiApiKey: 'readiness-openai-secret', + openaiTextModel: 'readiness-text-model', + openaiImageModel: 'readiness-image-model', + openaiTtsModel: 'readiness-tts-model', +} + +describe.sequential('service readiness API', () => { + let app: FastifyInstance + let owner: Session + let editor: Session + let outsider: Session + let verificationResponse: 'success' | 'unauthorized' = 'success' + const userIds: string[] = [] + const workspaceIds: string[] = [] + const providerFetch = vi.fn(async (url: string | URL | Request) => { + if (verificationResponse === 'unauthorized') { + return new Response('readiness-openai-secret must never be persisted', { status: 401 }) + } + const model = decodeURIComponent(new URL(String(url)).pathname.split('/').at(-1)!) + return new Response(JSON.stringify({ id: model, created: 1, object: 'model', owned_by: 'openai' }), { + status: 200, + headers: { 'content-type': 'application/json' }, + }) + }) + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + workspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp({ + providerVerificationFetch: providerFetch as typeof fetch, + providerVerificationConfiguration: verificationConfiguration, + }) + owner = await registerAccount('readiness-owner') + editor = await registerAccount('readiness-editor') + outsider = await registerAccount('readiness-outsider') + const membership = await app.inject({ + method: 'POST', + url: `/api/v1/workspaces/${owner.workspaces[0].id}/members`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + payload: { email: editor.user.email, role: 'EDITOR' }, + }) + expect(membership.statusCode, membership.body).toBe(201) + }) + + afterAll(async () => { + if (workspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, workspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('allows authenticated browser mutation methods through CORS preflight', async () => { + const origin = config.WEB_ORIGIN.split(',')[0]?.trim() + const response = await app.inject({ + method: 'OPTIONS', + url: `/api/v1/shots/${crypto.randomUUID()}/production`, + headers: { + origin, + 'access-control-request-method': 'PATCH', + 'access-control-request-headers': 'authorization,content-type', + }, + }) + expect(response.statusCode, response.body).toBe(204) + expect(response.headers['access-control-allow-origin']).toBe(origin) + expect(response.headers['access-control-allow-methods']).toContain('PATCH') + expect(response.headers['access-control-allow-methods']).toContain('DELETE') + }) + + it('requires authentication and workspace membership', async () => { + const workspaceId = owner.workspaces[0].id + const anonymous = await app.inject({ method: 'GET', url: `/api/v1/workspaces/${workspaceId}/service-readiness` }) + expect(anonymous.statusCode, anonymous.body).toBe(401) + + const forbidden = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${workspaceId}/service-readiness`, + headers: { authorization: `Bearer ${outsider.accessToken}` }, + }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + }) + + it('reports structured API readiness when every dependency is available', async () => { + await publishWorkerHeartbeat({ instanceId: 'readiness-integration-test', ttlSeconds: 5 }) + const response = await app.inject({ method: 'GET', url: '/health/ready' }) + expect(response.statusCode, response.body).toBe(200) + expect(response.json()).toEqual({ + status: 'ready', + dependencies: { + postgres: 'ok', + redis: 'ok', + objectStorage: 'ok', + worker: 'ok', + }, + }) + }) + + it('returns live infrastructure and redacted provider configuration status', async () => { + const response = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${owner.workspaces[0].id}/service-readiness`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(response.statusCode, response.body).toBe(200) + const body = response.json() + expect(body.checkedAt).toBeTruthy() + expect(body.infrastructure.services.map((item: { id: string }) => item.id)).toEqual([ + 'postgres', + 'redis', + 'worker', + 'object-storage', + 'ffmpeg', + ]) + expect(body.ai.verificationMode).toBe('CONFIGURATION') + expect(body.ai.workflows).toHaveLength(6) + expect(body.ai.providers.find((provider: { id: string }) => provider.id === 'openai').verification).toBe('CONFIGURATION_ONLY') + expect(response.body).not.toContain(verificationConfiguration.openaiApiKey) + if (config.OPENAI_API_KEY) expect(response.body).not.toContain(config.OPENAI_API_KEY) + if (config.REPLICATE_API_TOKEN) expect(response.body).not.toContain(config.REPLICATE_API_TOKEN) + }) + + it('restricts provider verification to workspace owners and administrators', async () => { + const workspaceId = owner.workspaces[0].id + const url = `/api/v1/workspaces/${workspaceId}/service-readiness/providers/openai/verify` + const callsBefore = providerFetch.mock.calls.length + const anonymous = await app.inject({ method: 'POST', url }) + expect(anonymous.statusCode, anonymous.body).toBe(401) + const forbiddenOutsider = await app.inject({ + method: 'POST', + url, + headers: { authorization: `Bearer ${outsider.accessToken}` }, + }) + expect(forbiddenOutsider.statusCode, forbiddenOutsider.body).toBe(403) + const forbiddenEditor = await app.inject({ + method: 'POST', + url, + headers: { authorization: `Bearer ${editor.accessToken}` }, + }) + expect(forbiddenEditor.statusCode, forbiddenEditor.body).toBe(403) + expect(providerFetch).toHaveBeenCalledTimes(callsBefore) + }) + + it('does not call an unconfigured provider', async () => { + const callsBefore = providerFetch.mock.calls.length + const response = await app.inject({ + method: 'POST', + url: `/api/v1/workspaces/${owner.workspaces[0].id}/service-readiness/providers/replicate/verify`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(response.statusCode, response.body).toBe(400) + expect(response.json().error.details).toEqual({ provider: 'replicate' }) + expect(providerFetch).toHaveBeenCalledTimes(callsBefore) + }) + + it('persists successful owner verification and returns it from later readiness reads', async () => { + verificationResponse = 'success' + const workspaceId = owner.workspaces[0].id + const response = await app.inject({ + method: 'POST', + url: `/api/v1/workspaces/${workspaceId}/service-readiness/providers/openai/verify`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(response.statusCode, response.body).toBe(200) + const provider = response.json().ai.providers.find((item: { id: string }) => item.id === 'openai') + expect(provider).toMatchObject({ + verification: 'VERIFIED', + errorCode: null, + details: { + scope: 'credentials_and_models', + models: ['readiness-text-model', 'readiness-image-model', 'readiness-tts-model'], + }, + }) + expect(provider.checkedAt).toBeTruthy() + expect(provider.verifiedAt).toBe(provider.checkedAt) + expect(response.body).not.toContain(verificationConfiguration.openaiApiKey) + + const later = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${workspaceId}/service-readiness`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(later.statusCode, later.body).toBe(200) + expect(later.json().ai.verificationMode).toBe('PERSISTED') + expect(later.json().ai.providers.find((item: { id: string }) => item.id === 'openai').verification).toBe('VERIFIED') + }) + + it('allows an administrator to verify and records a sanitized audit event', async () => { + const workspaceId = owner.workspaces[0].id + const promoted = await app.inject({ + method: 'PATCH', + url: `/api/v1/workspaces/${workspaceId}/members/${editor.user.id}`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + payload: { role: 'ADMIN' }, + }) + expect(promoted.statusCode, promoted.body).toBe(200) + const response = await app.inject({ + method: 'POST', + url: `/api/v1/workspaces/${workspaceId}/service-readiness/providers/openai/verify`, + headers: { authorization: `Bearer ${editor.accessToken}` }, + }) + expect(response.statusCode, response.body).toBe(200) + expect(response.json().ai.providers.find((item: { id: string }) => item.id === 'openai').verification).toBe('VERIFIED') + + const auditResponse = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${workspaceId}/audit-logs?category=service`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(auditResponse.statusCode, auditResponse.body).toBe(200) + expect(auditResponse.json().items.some((item: { action: string; actorId: string }) => item.action === 'service.provider.verify' && item.actorId === editor.user.id)).toBe(true) + expect(auditResponse.body).not.toContain(verificationConfiguration.openaiApiKey) + }) + + it('persists provider failures without storing tokens or raw response bodies', async () => { + verificationResponse = 'unauthorized' + const workspaceId = owner.workspaces[0].id + const response = await app.inject({ + method: 'POST', + url: `/api/v1/workspaces/${workspaceId}/service-readiness/providers/openai/verify`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(response.statusCode, response.body).toBe(200) + const provider = response.json().ai.providers.find((item: { id: string }) => item.id === 'openai') + expect(provider).toMatchObject({ + verification: 'FAILED', + errorCode: 'AUTHENTICATION_FAILED', + verifiedAt: null, + }) + expect(response.body).not.toContain(verificationConfiguration.openaiApiKey) + expect(response.body).not.toContain('must never be persisted') + + const [stored] = await db.select().from(providerVerifications).where(and( + eq(providerVerifications.workspaceId, workspaceId), + eq(providerVerifications.provider, 'openai'), + )).limit(1) + expect(stored).toMatchObject({ status: 'FAILED', errorCode: 'AUTHENTICATION_FAILED' }) + expect(JSON.stringify(stored)).not.toContain(verificationConfiguration.openaiApiKey) + expect(JSON.stringify(stored)).not.toContain('must never be persisted') + + const later = await app.inject({ + method: 'GET', + url: `/api/v1/workspaces/${workspaceId}/service-readiness`, + headers: { authorization: `Bearer ${owner.accessToken}` }, + }) + expect(later.statusCode, later.body).toBe(200) + expect(later.json().ai.providers.find((item: { id: string }) => item.id === 'openai')).toMatchObject({ + verification: 'FAILED', + errorCode: 'AUTHENTICATION_FAILED', + }) + + const [auditRow] = await db.select().from(auditLogs).where(and( + eq(auditLogs.workspaceId, workspaceId), + eq(auditLogs.action, 'service.provider.verify'), + eq(auditLogs.actorId, owner.user.id), + eq(auditLogs.resourceId, stored.id), + sql`${auditLogs.after} ->> 'status' = 'FAILED'`, + )).limit(1) + expect(auditRow?.after).toMatchObject({ status: 'FAILED', errorCode: 'AUTHENTICATION_FAILED' }) + }) +}) diff --git a/server/src/routes/readiness.ts b/server/src/routes/readiness.ts new file mode 100644 index 0000000..8c7f8ac --- /dev/null +++ b/server/src/routes/readiness.ts @@ -0,0 +1,193 @@ +import { execFile } from 'node:child_process' +import { promisify } from 'node:util' +import type { FastifyInstance } from 'fastify' +import { eq, sql } from 'drizzle-orm' +import { z } from 'zod' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { providerVerifications } from '../db/schema.js' +import { audit } from '../lib/audit.js' +import { requireAuth } from '../lib/auth.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireWorkspacePermission } from '../lib/permissions.js' +import { buildProviderReadiness, providerConfiguration, type ProviderConfiguration } from '../providers/readiness.js' +import { + providerCredentialConfigured, + providerIds, + providerVerificationFingerprint, + verifyProviderConnection, +} from '../providers/verification.js' +import { checkRedis } from '../queue/connection.js' +import { checkWorkerHeartbeat } from '../queue/heartbeat.js' +import { checkStorage } from '../storage/client.js' + +const executeFile = promisify(execFile) +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const providerParams = workspaceParams.extend({ providerId: z.enum(providerIds) }) + +export interface ReadinessRoutesOptions { + providerVerificationFetch?: typeof fetch + providerVerificationConfiguration?: ProviderConfiguration +} + +async function liveCheck(id: string, label: string, check: () => Promise) { + const startedAt = performance.now() + try { + await check() + return { id, label, status: 'AVAILABLE' as const, latencyMs: Math.max(0, Math.round(performance.now() - startedAt)) } + } catch { + return { id, label, status: 'UNAVAILABLE' as const, latencyMs: null } + } +} + +function mergeProviderVerification( + readiness: ReturnType, + rows: Array, + configuration: ProviderConfiguration, +) { + const providers = readiness.providers.map((provider) => { + if (!providerCredentialConfigured(provider.id, configuration)) { + return { + ...provider, + verification: 'NOT_RUN' as const, + checkedAt: null, + verifiedAt: null, + latencyMs: null, + errorCode: null, + message: null, + details: {}, + } + } + const fingerprint = providerVerificationFingerprint(provider.id, configuration) + const row = rows.find((candidate) => candidate.provider === provider.id && candidate.configurationFingerprint === fingerprint) + if (!row) { + return { + ...provider, + verification: 'CONFIGURATION_ONLY' as const, + checkedAt: null, + verifiedAt: null, + latencyMs: null, + errorCode: null, + message: null, + details: {}, + } + } + return { + ...provider, + verification: row.status, + checkedAt: row.checkedAt.toISOString(), + verifiedAt: row.status === 'VERIFIED' ? row.checkedAt.toISOString() : null, + latencyMs: row.latencyMs, + errorCode: row.errorCode, + message: row.message, + details: row.details, + } + }) + const hasPersistedVerification = providers.some((provider) => provider.verification === 'VERIFIED' || provider.verification === 'FAILED') + return { + ...readiness, + verificationMode: hasPersistedVerification ? 'PERSISTED' as const : 'CONFIGURATION' as const, + providers, + } +} + +async function readinessPayload(workspaceId: string, configuration: ProviderConfiguration) { + const [infrastructure, verificationRows] = await Promise.all([ + Promise.all([ + liveCheck('postgres', 'PostgreSQL', () => db.execute(sql`select 1`)), + liveCheck('redis', 'Redis 任务队列', checkRedis), + liveCheck('worker', '生成任务 Worker', checkWorkerHeartbeat), + liveCheck('object-storage', '对象存储', checkStorage), + liveCheck('ffmpeg', 'FFmpeg 合成', () => executeFile(config.FFMPEG_PATH, ['-version'], { timeout: 5000, maxBuffer: 256 * 1024 })), + ]), + db.select().from(providerVerifications).where(eq(providerVerifications.workspaceId, workspaceId)), + ]) + const availableInfrastructure = infrastructure.filter((item) => item.status === 'AVAILABLE').length + return { + checkedAt: new Date().toISOString(), + infrastructure: { + status: availableInfrastructure === infrastructure.length ? 'AVAILABLE' as const : 'DEGRADED' as const, + available: availableInfrastructure, + total: infrastructure.length, + services: infrastructure, + }, + ai: mergeProviderVerification(buildProviderReadiness(configuration), verificationRows, configuration), + } +} + +export async function readinessRoutes(app: FastifyInstance, options: ReadinessRoutesOptions = {}) { + const configuration = options.providerVerificationConfiguration ?? providerConfiguration() + const verificationFetch = options.providerVerificationFetch ?? fetch + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/service-readiness', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'project:read') + return readinessPayload(workspaceId, configuration) + }) + + app.post('/workspaces/:workspaceId/service-readiness/providers/:providerId/verify', { + config: { rateLimit: { max: 10, timeWindow: '1 minute' } }, + }, async (request) => { + const { workspaceId, providerId } = parseWith(providerParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'services:verify') + if (!providerCredentialConfigured(providerId, configuration)) { + const requirement = providerId === 'openai' + ? 'OPENAI_API_KEY' + : providerId === 'replicate' + ? 'REPLICATE_API_TOKEN' + : providerId === 'agnes' + ? 'AGNES_API_KEY' + : 'GENERIC_TEXT_API_KEY、GENERIC_IMAGE_API_KEY 或 GENERIC_VIDEO_API_KEY' + throw errors.badRequest(`${requirement} 尚未配置`, { + provider: providerId, + }) + } + + const result = await verifyProviderConnection(providerId, configuration, verificationFetch) + const checkedAt = new Date() + const [saved] = await db.insert(providerVerifications).values({ + workspaceId, + provider: providerId, + status: result.status, + configurationFingerprint: providerVerificationFingerprint(providerId, configuration), + checkedAt, + latencyMs: result.latencyMs, + errorCode: result.errorCode, + message: result.message, + details: result.details, + checkedById: request.user.sub, + }).onConflictDoUpdate({ + target: [providerVerifications.workspaceId, providerVerifications.provider], + set: { + status: result.status, + configurationFingerprint: providerVerificationFingerprint(providerId, configuration), + checkedAt, + latencyMs: result.latencyMs, + errorCode: result.errorCode, + message: result.message, + details: result.details, + checkedById: request.user.sub, + updatedAt: checkedAt, + }, + }).returning() + if (!saved) throw errors.serviceUnavailable('供应商验证结果未能保存') + + await audit({ + request, + workspaceId, + action: 'service.provider.verify', + resourceType: 'provider_verification', + resourceId: saved.id, + after: { + provider: providerId, + status: result.status, + checkedAt: checkedAt.toISOString(), + latencyMs: result.latencyMs, + errorCode: result.errorCode, + }, + }) + return readinessPayload(workspaceId, configuration) + }) +} diff --git a/server/src/routes/reviews.ts b/server/src/routes/reviews.ts new file mode 100644 index 0000000..3d4bb97 --- /dev/null +++ b/server/src/routes/reviews.ts @@ -0,0 +1,312 @@ +import type { FastifyInstance } from 'fastify' +import { and, desc, eq } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { + assets, + assetVersions, + episodes, + memberships, + projects, + renders, + reviewComments, + reviewRequests, + scriptVersions, + shots, + shotVersions, +} from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { + notifyReviewAssigned, + notifyReviewComment, + notifyReviewRequested, + notifyReviewResolved, +} from '../lib/notifications.js' +import { requireWorkspacePermission } from '../lib/permissions.js' +import { publishRealtimeEvent } from '../lib/realtime.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const reviewParams = z.object({ reviewId: z.uuid() }) +const createReviewSchema = z.object({ + targetType: z.enum(['SCRIPT_VERSION', 'ASSET_VERSION', 'SHOT_VERSION', 'RENDER']), + targetId: z.uuid(), + assignedToId: z.uuid().nullable().optional(), + summary: z.string().trim().max(2000).default(''), +}) +const listReviewQuery = z.object({ + status: z.enum(['OPEN', 'APPROVED', 'CHANGES_REQUESTED', 'CANCELLED']).optional(), + assignedToId: z.uuid().optional(), +}) +const commentSchema = z.object({ + body: z.string().trim().min(1).max(10_000), + timecodeMs: z.number().int().min(0).max(86_400_000).nullable().optional(), + metadata: z.record(z.string(), z.unknown()).default({}), +}) +const decisionSchema = z.object({ + status: z.enum(['APPROVED', 'CHANGES_REQUESTED', 'CANCELLED']), + summary: z.string().trim().max(2000).optional(), +}) +const assignSchema = z.object({ + assignedToId: z.uuid().nullable(), + summary: z.string().trim().max(2000).optional(), +}) + +type ReviewTargetType = z.infer['targetType'] + +interface TargetContext { + workspaceId: string + projectId: string + episodeId?: string + parentId: string +} + +async function targetContext(type: ReviewTargetType, targetId: string): Promise { + if (type === 'SCRIPT_VERSION') { + const [row] = await db.select({ project: projects, episodeId: episodes.id }).from(scriptVersions) + .innerJoin(episodes, eq(episodes.id, scriptVersions.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(scriptVersions.id, targetId)).limit(1) + if (!row) throw errors.notFound('Script version') + return { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episodeId, parentId: row.episodeId } + } + if (type === 'ASSET_VERSION') { + const [row] = await db.select({ project: projects, assetId: assets.id }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .innerJoin(projects, eq(projects.id, assets.projectId)) + .where(eq(assetVersions.id, targetId)).limit(1) + if (!row) throw errors.notFound('Asset version') + return { workspaceId: row.project.workspaceId, projectId: row.project.id, parentId: row.assetId } + } + if (type === 'SHOT_VERSION') { + const [row] = await db.select({ project: projects, episodeId: episodes.id, shotId: shots.id }).from(shotVersions) + .innerJoin(shots, eq(shots.id, shotVersions.shotId)) + .innerJoin(episodes, eq(episodes.id, shots.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(shotVersions.id, targetId)).limit(1) + if (!row) throw errors.notFound('Shot version') + return { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episodeId, parentId: row.shotId } + } + const [row] = await db.select({ project: projects, episodeId: episodes.id, renderId: renders.id }).from(renders) + .innerJoin(episodes, eq(episodes.id, renders.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(renders.id, targetId)).limit(1) + if (!row) throw errors.notFound('Render') + return { workspaceId: row.project.workspaceId, projectId: row.project.id, episodeId: row.episodeId, parentId: row.renderId } +} + +async function reviewWithContext(reviewId: string) { + const [review] = await db.select().from(reviewRequests).where(eq(reviewRequests.id, reviewId)).limit(1) + if (!review) throw errors.notFound('Review request') + const target = await targetContext(review.targetType, review.targetId) + if (target.workspaceId !== review.workspaceId) throw new Error('Review target workspace mismatch') + return { review, target } +} + +async function updateTargetStatus(type: ReviewTargetType, target: TargetContext, decision: 'APPROVED' | 'CHANGES_REQUESTED') { + if (type === 'SCRIPT_VERSION' && target.episodeId) { + await db.update(episodes).set({ status: decision === 'APPROVED' ? 'STORYBOARDING' : 'SCRIPTING', updatedAt: new Date() }) + .where(eq(episodes.id, target.episodeId)) + } else if (type === 'ASSET_VERSION') { + await db.update(assets).set({ status: decision === 'APPROVED' ? 'APPROVED' : 'DRAFT', updatedAt: new Date() }) + .where(eq(assets.id, target.parentId)) + } else if (type === 'SHOT_VERSION') { + await db.update(shots).set({ status: decision === 'APPROVED' ? 'APPROVED' : 'DRAFT', updatedAt: new Date() }) + .where(eq(shots.id, target.parentId)) + } else if (type === 'RENDER') { + await db.update(renders).set({ status: decision === 'APPROVED' ? 'APPROVED' : 'REVIEW', updatedAt: new Date() }) + .where(eq(renders.id, target.parentId)) + } +} + +export async function reviewRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/workspaces/:workspaceId/reviews', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const query = parseWith(listReviewQuery, request.query) + await requireWorkspacePermission(request, workspaceId, 'project:read') + const filters = [eq(reviewRequests.workspaceId, workspaceId)] + if (query.status) filters.push(eq(reviewRequests.status, query.status)) + if (query.assignedToId) filters.push(eq(reviewRequests.assignedToId, query.assignedToId)) + return db.select().from(reviewRequests).where(and(...filters)).orderBy(desc(reviewRequests.updatedAt)).limit(200) + }) + + app.post('/workspaces/:workspaceId/reviews', async (request, reply) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(createReviewSchema, request.body) + await requireWorkspacePermission(request, workspaceId, 'content:write') + const target = await targetContext(input.targetType, input.targetId) + if (target.workspaceId !== workspaceId) throw errors.forbidden('Review target does not belong to this workspace') + if (input.assignedToId) { + const [assignee] = await db.select({ userId: memberships.userId, role: memberships.role }).from(memberships) + .where(and(eq(memberships.workspaceId, workspaceId), eq(memberships.userId, input.assignedToId))).limit(1) + if (!assignee || !['OWNER', 'ADMIN', 'REVIEWER'].includes(assignee.role)) throw errors.badRequest('Assigned reviewer must have review permission') + } + const [existing] = await db.select({ id: reviewRequests.id }).from(reviewRequests).where(and( + eq(reviewRequests.workspaceId, workspaceId), + eq(reviewRequests.targetType, input.targetType), + eq(reviewRequests.targetId, input.targetId), + eq(reviewRequests.status, 'OPEN'), + )).limit(1) + if (existing) throw errors.conflict('An open review already exists for this version') + + const [review] = await db.insert(reviewRequests).values({ + workspaceId, + targetType: input.targetType, + targetId: input.targetId, + requestedById: request.user.sub, + assignedToId: input.assignedToId, + summary: input.summary, + }).returning() + if (!review) throw new Error('Failed to create review request') + await audit({ request, workspaceId, action: 'review.create', resourceType: 'review_request', resourceId: review.id, after: review }) + await Promise.all([ + publishRealtimeEvent({ + workspaceId, + type: 'review.updated', + resourceType: 'review_request', + resourceId: review.id, + payload: { id: review.id, status: review.status }, + }), + notifyReviewRequested({ + workspaceId: review.workspaceId, + reviewId: review.id, + requestedById: review.requestedById, + assignedToId: review.assignedToId, + summary: review.summary, + targetType: review.targetType, + }).catch((error) => { + request.log.error({ err: error, reviewId: review.id }, 'Review notification failed') + return [] + }), + ]) + return reply.code(201).send(review) + }) + + app.get('/reviews/:reviewId', async (request) => { + const { reviewId } = parseWith(reviewParams, request.params) + const { review } = await reviewWithContext(reviewId) + await requireWorkspacePermission(request, review.workspaceId, 'project:read') + const comments = await db.select().from(reviewComments).where(eq(reviewComments.reviewRequestId, reviewId)).orderBy(reviewComments.createdAt) + return { ...review, comments } + }) + + app.post('/reviews/:reviewId/comments', async (request, reply) => { + const { reviewId } = parseWith(reviewParams, request.params) + const input = parseWith(commentSchema, request.body) + const { review } = await reviewWithContext(reviewId) + await requireWorkspacePermission(request, review.workspaceId, 'project:read') + if (review.status !== 'OPEN') throw errors.conflict('Comments can only be added to an open review') + const [comment] = await db.insert(reviewComments).values({ + reviewRequestId: reviewId, + authorId: request.user.sub, + body: input.body, + timecodeMs: input.timecodeMs, + metadata: input.metadata, + }).returning() + if (!comment) throw new Error('Failed to create review comment') + await audit({ request, workspaceId: review.workspaceId, action: 'review.comment.create', resourceType: 'review_comment', resourceId: comment.id, after: { reviewId, timecodeMs: comment.timecodeMs } }) + await Promise.all([ + publishRealtimeEvent({ + workspaceId: review.workspaceId, + type: 'review.updated', + resourceType: 'review_request', + resourceId: review.id, + payload: { id: review.id, status: review.status, commentId: comment.id }, + }), + notifyReviewComment({ + workspaceId: review.workspaceId, + reviewId: review.id, + authorId: request.user.sub, + requestedById: review.requestedById, + assignedToId: review.assignedToId, + body: comment.body, + commentId: comment.id, + }).catch((error) => { + request.log.error({ err: error, reviewId: review.id }, 'Review comment notification failed') + return [] + }), + ]) + return reply.code(201).send(comment) + }) + + app.patch('/reviews/:reviewId', async (request) => { + const { reviewId } = parseWith(reviewParams, request.params) + const input = parseWith(assignSchema, request.body) + const { review } = await reviewWithContext(reviewId) + await requireWorkspacePermission(request, review.workspaceId, 'review:decide') + if (review.status !== 'OPEN') throw errors.conflict('Only open reviews can be reassigned') + if (input.assignedToId) { + const [assignee] = await db.select({ userId: memberships.userId, role: memberships.role }).from(memberships) + .where(and(eq(memberships.workspaceId, review.workspaceId), eq(memberships.userId, input.assignedToId))).limit(1) + if (!assignee || !['OWNER', 'ADMIN', 'REVIEWER'].includes(assignee.role)) throw errors.badRequest('Assigned reviewer must have review permission') + } + const [updated] = await db.update(reviewRequests).set({ + assignedToId: input.assignedToId, + ...(input.summary !== undefined ? { summary: input.summary } : {}), + updatedAt: new Date(), + }).where(and(eq(reviewRequests.id, reviewId), eq(reviewRequests.status, 'OPEN'))).returning() + if (!updated) throw errors.conflict('Review was resolved concurrently') + await audit({ request, workspaceId: review.workspaceId, action: 'review.assign', resourceType: 'review_request', resourceId: reviewId, before: { assignedToId: review.assignedToId }, after: { assignedToId: updated.assignedToId } }) + await publishRealtimeEvent({ + workspaceId: review.workspaceId, + type: 'review.updated', + resourceType: 'review_request', + resourceId: review.id, + payload: { id: review.id, status: review.status, assignedToId: updated.assignedToId }, + }) + if (updated.assignedToId) { + await notifyReviewAssigned({ + workspaceId: review.workspaceId, + reviewId: review.id, + assignedToId: updated.assignedToId, + assignedById: request.user.sub, + summary: updated.summary, + }).catch((error) => request.log.error({ err: error, reviewId: review.id }, 'Review assignment notification failed')) + } + return updated + }) + + app.post('/reviews/:reviewId/decision', async (request) => { + const { reviewId } = parseWith(reviewParams, request.params) + const input = parseWith(decisionSchema, request.body) + const { review, target } = await reviewWithContext(reviewId) + await requireWorkspacePermission(request, review.workspaceId, 'review:decide') + if (review.status !== 'OPEN') throw errors.conflict(`Review has already been resolved as ${review.status}`) + const now = new Date() + const [updated] = await db.update(reviewRequests).set({ + status: input.status, + summary: input.summary ?? review.summary, + resolvedById: request.user.sub, + resolvedAt: now, + updatedAt: now, + }).where(and(eq(reviewRequests.id, reviewId), eq(reviewRequests.status, 'OPEN'))).returning() + if (!updated) throw errors.conflict('Review was resolved concurrently') + if (input.status !== 'CANCELLED') await updateTargetStatus(review.targetType, target, input.status) + await audit({ request, workspaceId: review.workspaceId, action: 'review.decide', resourceType: 'review_request', resourceId: reviewId, before: { status: review.status }, after: { status: input.status } }) + await Promise.all([ + publishRealtimeEvent({ + workspaceId: review.workspaceId, + type: 'review.updated', + resourceType: 'review_request', + resourceId: review.id, + payload: { id: review.id, status: input.status }, + }), + notifyReviewResolved({ + workspaceId: review.workspaceId, + reviewId: review.id, + requestedById: review.requestedById, + resolvedById: request.user.sub, + status: input.status, + summary: updated.summary, + }).catch((error) => { + request.log.error({ err: error, reviewId: review.id }, 'Review resolution notification failed') + return null + }), + ]) + return updated + }) +} diff --git a/server/src/routes/shots.ts b/server/src/routes/shots.ts new file mode 100644 index 0000000..95caa12 --- /dev/null +++ b/server/src/routes/shots.ts @@ -0,0 +1,308 @@ +import type { FastifyInstance } from 'fastify' +import { and, asc, desc, eq, sql } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { assets, assetVersions, episodes, projects, shots, shotVersions } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission } from '../lib/permissions.js' +import { shotProductionSettingsSchema, shotProductionSettingsUpdateSchema } from '../media/ffmpeg.js' +import { presignDownload } from '../storage/client.js' + +const episodeParams = z.object({ episodeId: z.uuid() }) +const shotParams = z.object({ shotId: z.uuid() }) +const shotVersionParams = z.object({ shotId: z.uuid(), versionId: z.uuid() }) +const createShotSchema = z.object({ + shotNumber: z.number().int().positive(), + sceneNumber: z.number().int().positive(), + title: z.string().trim().min(1).max(180), + description: z.string().max(10000).default(''), + shotType: z.string().max(50).default('中景'), + cameraMotion: z.string().max(50).default('静止'), + durationMs: z.number().int().min(100).max(600000).default(3000), + characterAssetIds: z.array(z.uuid()).max(20).default([]), + sceneAssetId: z.uuid().nullable().optional(), + sortOrder: z.number().int(), +}) +const updateShotSchema = createShotSchema.partial().extend({ + status: z.enum(['DRAFT', 'GENERATING', 'REVIEW', 'APPROVED', 'RENDERED']).optional(), +}) +const reorderSchema = z.object({ + shots: z.array(z.object({ id: z.uuid(), sortOrder: z.number().int() })).min(1).max(500), +}) +const versionSchema = z.object({ + imageAssetVersionId: z.uuid().nullable().optional(), + videoStorageKey: z.string().max(1000).nullable().optional(), + audioStorageKey: z.string().max(1000).nullable().optional(), + subtitleText: z.string().max(10000).optional(), + production: shotProductionSettingsUpdateSchema.optional(), + generationParams: z.record(z.string(), z.unknown()).optional(), +}) +const productionEditSchema = z.object({ + title: z.string().trim().min(1).max(180).optional(), + cameraMotion: z.string().max(50).optional(), + durationMs: z.number().int().min(100).max(600000), + subtitleText: z.string().max(10000).optional(), + production: shotProductionSettingsUpdateSchema.default({}), + generationParams: z.record(z.string(), z.unknown()).default({}), +}) + +async function episodeProject(episodeId: string) { + const [row] = await db.select({ episode: episodes, project: projects }).from(episodes).innerJoin(projects, eq(projects.id, episodes.projectId)).where(eq(episodes.id, episodeId)).limit(1) + if (!row) throw errors.notFound('Episode') + return row +} + +async function shotProject(shotId: string) { + const [row] = await db.select({ shot: shots, episode: episodes, project: projects }).from(shots) + .innerJoin(episodes, eq(episodes.id, shots.episodeId)) + .innerJoin(projects, eq(projects.id, episodes.projectId)) + .where(eq(shots.id, shotId)).limit(1) + if (!row) throw errors.notFound('Shot') + return row +} + +async function mediaForVersion(version: typeof shotVersions.$inferSelect, projectId: string) { + let imageStorageKey: string | null = null + if (version.imageAssetVersionId) { + const [image] = await db.select({ storageKey: assetVersions.storageKey }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .where(and(eq(assetVersions.id, version.imageAssetVersionId), eq(assets.projectId, projectId))).limit(1) + imageStorageKey = image?.storageKey ?? null + } + const [imageUrl, videoUrl, audioUrl] = await Promise.all([ + imageStorageKey ? presignDownload(imageStorageKey) : Promise.resolve(null), + version.videoStorageKey ? presignDownload(version.videoStorageKey) : Promise.resolve(null), + version.audioStorageKey ? presignDownload(version.audioStorageKey) : Promise.resolve(null), + ]) + return { versionId: version.id, imageUrl, videoUrl, audioUrl, subtitleText: version.subtitleText } +} + +export async function shotRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.get('/episodes/:episodeId/shots', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'project:read') + return db.select({ shot: shots, currentVersion: shotVersions }).from(shots).leftJoin(shotVersions, and( + eq(shotVersions.shotId, shots.id), + eq(shotVersions.isCurrent, true), + )).where(eq(shots.episodeId, episodeId)).orderBy(asc(shots.sortOrder)) + }) + + app.post('/episodes/:episodeId/shots', async (request, reply) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(createShotSchema, request.body) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'content:write') + const [shot] = await db.insert(shots).values({ episodeId, createdById: request.user.sub, ...input }).returning() + if (!shot) throw new Error('Failed to create shot') + await audit({ request, workspaceId: row.project.workspaceId, action: 'shot.create', resourceType: 'shot', resourceId: shot.id, after: shot }) + return reply.code(201).send(shot) + }) + + app.patch('/episodes/:episodeId/shots/reorder', async (request) => { + const { episodeId } = parseWith(episodeParams, request.params) + const input = parseWith(reorderSchema, request.body) + const row = await episodeProject(episodeId) + await requireProjectPermission(request, row.project.id, 'content:write') + await db.transaction(async (tx) => { + for (const item of input.shots) { + await tx.update(shots).set({ sortOrder: item.sortOrder, updatedAt: new Date() }).where(and(eq(shots.id, item.id), eq(shots.episodeId, episodeId))) + } + }) + await audit({ request, workspaceId: row.project.workspaceId, action: 'shots.reorder', resourceType: 'episode', resourceId: episodeId, after: { shots: input.shots } }) + return { updated: input.shots.length } + }) + + app.get('/shots/:shotId', async (request) => { + const { shotId } = parseWith(shotParams, request.params) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'project:read') + const versions = await db.select().from(shotVersions).where(eq(shotVersions.shotId, shotId)).orderBy(desc(shotVersions.version)) + return { ...row.shot, versions } + }) + + app.get('/shots/:shotId/media', async (request) => { + const { shotId } = parseWith(shotParams, request.params) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'project:read') + const [version] = await db.select().from(shotVersions).where(and( + eq(shotVersions.shotId, shotId), + eq(shotVersions.isCurrent, true), + )).limit(1) + if (!version) return { versionId: null, imageUrl: null, videoUrl: null, audioUrl: null, subtitleText: '' } + + return mediaForVersion(version, row.project.id) + }) + + app.get('/shots/:shotId/versions/:versionId/media', async (request) => { + const { shotId, versionId } = parseWith(shotVersionParams, request.params) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'project:read') + const [version] = await db.select().from(shotVersions).where(and( + eq(shotVersions.id, versionId), + eq(shotVersions.shotId, shotId), + )).limit(1) + if (!version) throw errors.notFound('Shot version') + return mediaForVersion(version, row.project.id) + }) + + app.patch('/shots/:shotId', async (request) => { + const { shotId } = parseWith(shotParams, request.params) + const input = parseWith(updateShotSchema, request.body) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'content:write') + const [updated] = await db.update(shots).set({ ...input, updatedAt: new Date() }).where(eq(shots.id, shotId)).returning() + if (!updated) throw errors.notFound('Shot') + await audit({ request, workspaceId: row.project.workspaceId, action: 'shot.update', resourceType: 'shot', resourceId: shotId, before: row.shot, after: updated }) + return updated + }) + + app.patch('/shots/:shotId/production', async (request) => { + const { shotId } = parseWith(shotParams, request.params) + const input = parseWith(productionEditSchema, request.body) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'content:write') + + const result = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`shot:${shotId}`}))`) + const [latest] = await tx.select().from(shotVersions).where(eq(shotVersions.shotId, shotId)).orderBy(desc(shotVersions.version)).limit(1) + const [current] = await tx.select().from(shotVersions).where(and( + eq(shotVersions.shotId, shotId), + eq(shotVersions.isCurrent, true), + )).limit(1) + const base = current ?? latest + const currentProduction = shotProductionSettingsSchema.parse(base?.generationParams?.production ?? {}) + const production = shotProductionSettingsSchema.parse({ ...currentProduction, ...input.production }) + + const [updatedShot] = await tx.update(shots).set({ + ...(input.title ? { title: input.title } : {}), + ...(input.cameraMotion !== undefined ? { cameraMotion: input.cameraMotion } : {}), + durationMs: input.durationMs, + updatedAt: new Date(), + }).where(eq(shots.id, shotId)).returning() + if (!updatedShot) throw errors.notFound('Shot') + + await tx.update(shotVersions).set({ isCurrent: false }).where(eq(shotVersions.shotId, shotId)) + const [version] = await tx.insert(shotVersions).values({ + shotId, + version: (latest?.version ?? 0) + 1, + imageAssetVersionId: base?.imageAssetVersionId ?? null, + videoStorageKey: base?.videoStorageKey ?? null, + audioStorageKey: base?.audioStorageKey ?? null, + subtitleText: input.subtitleText ?? base?.subtitleText ?? '', + generationParams: { ...(base?.generationParams ?? {}), ...input.generationParams, production, source: 'manual' }, + isCurrent: true, + createdById: request.user.sub, + }).returning() + if (!version) throw new Error('Failed to create shot production version') + return { shot: updatedShot, version } + }) + + await audit({ + request, + workspaceId: row.project.workspaceId, + action: 'shot.production.update', + resourceType: 'shot', + resourceId: shotId, + before: row.shot, + after: { shot: result.shot, version: result.version.version, production: result.version.generationParams.production }, + }) + return result + }) + + app.delete('/shots/:shotId', async (request, reply) => { + const { shotId } = parseWith(shotParams, request.params) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'content:write') + await db.transaction(async (tx) => { + await tx.update(assets).set({ status: 'ARCHIVED', updatedAt: new Date() }).where(and( + eq(assets.projectId, row.project.id), + eq(assets.type, 'SHOT'), + sql`${assets.metadata}->>'shotId' = ${shotId}`, + )) + await tx.delete(shots).where(eq(shots.id, shotId)) + }) + await audit({ request, workspaceId: row.project.workspaceId, action: 'shot.delete', resourceType: 'shot', resourceId: shotId, before: row.shot }) + return reply.code(204).send() + }) + + app.post('/shots/:shotId/versions', async (request, reply) => { + const { shotId } = parseWith(shotParams, request.params) + const input = parseWith(versionSchema, request.body) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'content:write') + const projectPrefix = `${row.project.workspaceId}/${row.project.id}/` + for (const storageKey of [input.videoStorageKey, input.audioStorageKey]) { + if (storageKey && !storageKey.startsWith(projectPrefix)) throw errors.forbidden('Shot media must belong to the same project') + } + if (input.imageAssetVersionId) { + const [image] = await db.select({ id: assetVersions.id }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .where(and(eq(assetVersions.id, input.imageAssetVersionId), eq(assets.projectId, row.project.id))).limit(1) + if (!image) throw errors.badRequest('Image asset version must belong to the same project') + } + + const created = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`shot:${shotId}`}))`) + const [latest] = await tx.select().from(shotVersions).where(eq(shotVersions.shotId, shotId)).orderBy(desc(shotVersions.version)).limit(1) + const [current] = await tx.select().from(shotVersions).where(and( + eq(shotVersions.shotId, shotId), + eq(shotVersions.isCurrent, true), + )).limit(1) + const base = current ?? latest + const latestProduction = shotProductionSettingsSchema.parse(base?.generationParams?.production ?? {}) + const production = input.production + ? shotProductionSettingsSchema.parse({ ...latestProduction, ...input.production }) + : latestProduction + await tx.update(shotVersions).set({ isCurrent: false }).where(eq(shotVersions.shotId, shotId)) + const [version] = await tx.insert(shotVersions).values({ + shotId, + version: (latest?.version ?? 0) + 1, + imageAssetVersionId: input.imageAssetVersionId !== undefined ? input.imageAssetVersionId : base?.imageAssetVersionId ?? null, + videoStorageKey: input.videoStorageKey !== undefined ? input.videoStorageKey : base?.videoStorageKey ?? null, + audioStorageKey: input.audioStorageKey !== undefined ? input.audioStorageKey : base?.audioStorageKey ?? null, + subtitleText: input.subtitleText ?? base?.subtitleText ?? '', + generationParams: { ...(base?.generationParams ?? {}), ...(input.generationParams ?? {}), production, source: 'manual' }, + isCurrent: true, + createdById: request.user.sub, + }).returning() + return version + }) + if (!created) throw new Error('Failed to create shot version') + await audit({ request, workspaceId: row.project.workspaceId, action: 'shot.version.create', resourceType: 'shot_version', resourceId: created.id, after: { shotId, version: created.version } }) + return reply.code(201).send(created) + }) + + app.post('/shots/:shotId/versions/:versionId/activate', async (request) => { + const { shotId, versionId } = parseWith(shotVersionParams, request.params) + const row = await shotProject(shotId) + await requireProjectPermission(request, row.project.id, 'content:write') + + const result = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`shot:${shotId}`}))`) + const [version] = await tx.select().from(shotVersions).where(and( + eq(shotVersions.id, versionId), + eq(shotVersions.shotId, shotId), + )).limit(1) + if (!version) throw errors.notFound('Shot version') + if (version.isCurrent) return { version, changed: false } + await tx.update(shotVersions).set({ isCurrent: false }).where(eq(shotVersions.shotId, shotId)) + const [activated] = await tx.update(shotVersions).set({ isCurrent: true }).where(and( + eq(shotVersions.id, versionId), + eq(shotVersions.shotId, shotId), + )).returning() + if (!activated) throw errors.notFound('Shot version') + return { version: activated, changed: true } + }) + + if (result.changed) { + await audit({ request, workspaceId: row.project.workspaceId, action: 'shot.version.activate', resourceType: 'shot_version', resourceId: versionId, after: { shotId, version: result.version.version } }) + } + return result.version + }) +} diff --git a/server/src/routes/uploads.ts b/server/src/routes/uploads.ts new file mode 100644 index 0000000..bddd010 --- /dev/null +++ b/server/src/routes/uploads.ts @@ -0,0 +1,68 @@ +import type { FastifyInstance } from 'fastify' +import { and, eq } from 'drizzle-orm' +import { z } from 'zod' +import { config } from '../config.js' +import { db } from '../db/client.js' +import { assets, assetVersions, projects } from '../db/schema.js' +import { requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { requireProjectPermission } from '../lib/permissions.js' +import { presignDownload, presignUpload, projectObjectKey, putObject } from '../storage/client.js' + +const projectParams = z.object({ projectId: z.uuid() }) +const versionParams = z.object({ assetId: z.uuid(), versionId: z.uuid() }) +const presignSchema = z.object({ + filename: z.string().trim().min(1).max(255), + contentType: z.string().trim().min(3).max(120), +}) + +export async function uploadRoutes(app: FastifyInstance) { + app.addHook('preHandler', requireAuth) + + app.post('/projects/:projectId/uploads/presign', async (request) => { + const { projectId } = parseWith(projectParams, request.params) + const input = parseWith(presignSchema, request.body) + const { project } = await requireProjectPermission(request, projectId, 'content:write') + const key = projectObjectKey(project.workspaceId, projectId, input.filename) + const uploadUrl = await presignUpload(key, input.contentType) + await audit({ request, workspaceId: project.workspaceId, action: 'upload.presign', resourceType: 'project', resourceId: projectId, after: { key, contentType: input.contentType } }) + return { key, uploadUrl, expiresIn: 900, maxBytes: config.MAX_UPLOAD_BYTES } + }) + + app.post('/projects/:projectId/uploads', async (request, reply) => { + const { projectId } = parseWith(projectParams, request.params) + const { project } = await requireProjectPermission(request, projectId, 'content:write') + const file = await request.file() + if (!file) throw errors.badRequest('A multipart file is required') + const buffer = await file.toBuffer() + if (buffer.length > config.MAX_UPLOAD_BYTES) throw errors.badRequest('File exceeds upload limit') + const key = projectObjectKey(project.workspaceId, projectId, file.filename) + await putObject({ + key, + body: buffer, + contentType: file.mimetype, + metadata: { projectId, uploadedBy: request.user.sub }, + }) + await audit({ request, workspaceId: project.workspaceId, action: 'upload.create', resourceType: 'object', resourceId: projectId, after: { key, byteSize: buffer.length, contentType: file.mimetype } }) + return reply.code(201).send({ key, byteSize: buffer.length, contentType: file.mimetype, filename: file.filename }) + }) + + app.get('/assets/:assetId/versions/:versionId/url', async (request) => { + const { assetId, versionId } = parseWith(versionParams, request.params) + const [row] = await db.select({ + storageKey: assetVersions.storageKey, + projectId: assets.projectId, + workspaceId: projects.workspaceId, + }).from(assetVersions) + .innerJoin(assets, eq(assets.id, assetVersions.assetId)) + .innerJoin(projects, eq(projects.id, assets.projectId)) + .where(and(eq(assetVersions.id, versionId), eq(assetVersions.assetId, assetId))) + .limit(1) + if (!row) throw errors.notFound('Asset version') + await requireProjectPermission(request, row.projectId, 'project:read') + if (!row.storageKey) throw errors.notFound('Asset media') + return { url: await presignDownload(row.storageKey), expiresIn: 900 } + }) +} diff --git a/server/src/routes/version-review.integration.test.ts b/server/src/routes/version-review.integration.test.ts new file mode 100644 index 0000000..a61616e --- /dev/null +++ b/server/src/routes/version-review.integration.test.ts @@ -0,0 +1,219 @@ +import type { FastifyInstance } from 'fastify' +import { eq } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { users, workspaces } from '../db/schema.js' + +describe.sequential('version activation and review workflow', () => { + let app: FastifyInstance + let token = '' + let userId = '' + let workspaceId = '' + let projectId = '' + let episodeId = '' + let assetId = '' + + async function request(method: string, url: string, payload?: unknown) { + const response = await app.inject({ + method, + url, + headers: token ? { authorization: `Bearer ${token}` } : undefined, + payload, + }) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.json() + } + + beforeAll(async () => { + app = await buildApp() + const nonce = crypto.randomUUID().slice(0, 8) + const session = await request('POST', '/api/v1/auth/register', { + email: `version-review-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: '集成测试用户', + workspaceName: `版本审核测试 ${nonce}`, + }) + token = session.accessToken + userId = session.user.id + workspaceId = session.workspaces[0].id + const project = await request('POST', `/api/v1/workspaces/${workspaceId}/projects`, { + name: '版本审核测试项目', + logline: '验证不可变版本和审核状态流转。', + genre: '测试', + visualBible: {}, + }) + projectId = project.id + const episode = await request('POST', `/api/v1/projects/${projectId}/episodes`, { + episodeNumber: 1, + title: '测试分集', + synopsis: '', + targetDurationSeconds: 60, + }) + episodeId = episode.id + }) + + afterAll(async () => { + if (workspaceId) await db.delete(workspaces).where(eq(workspaces.id, workspaceId)) + if (userId) await db.delete(users).where(eq(users.id, userId)) + await app.close() + }) + + it('activates previous script, asset, and shot versions', async () => { + const scriptOne = await request('POST', `/api/v1/episodes/${episodeId}/scripts`, { + title: '测试分集', + content: { source: 'test' }, + plainText: '第一版剧本', + changeSummary: 'v1', + }) + await request('POST', `/api/v1/episodes/${episodeId}/scripts`, { + title: '测试分集', + content: { source: 'test' }, + plainText: '第二版剧本', + changeSummary: 'v2', + }) + await request('POST', `/api/v1/episodes/${episodeId}/scripts/${scriptOne.id}/activate`) + const scripts = await request('GET', `/api/v1/episodes/${episodeId}/scripts`) + expect(scripts.find((version: { id: string }) => version.id === scriptOne.id)?.isCurrent).toBe(true) + expect(scripts.filter((version: { isCurrent: boolean }) => version.isCurrent)).toHaveLength(1) + + const asset = await request('POST', `/api/v1/projects/${projectId}/assets`, { + type: 'CHARACTER', + name: '一致性测试角色', + description: '', + tags: [], + metadata: {}, + }) + assetId = asset.id + const assetOne = await request('POST', `/api/v1/assets/${asset.id}/versions`, { prompt: '角色第一版', generationParams: { source: 'test' } }) + await request('POST', `/api/v1/assets/${asset.id}/versions`, { prompt: '角色第二版', generationParams: { source: 'test' } }) + await request('POST', `/api/v1/assets/${asset.id}/versions/${assetOne.id}/activate`) + const assetDetail = await request('GET', `/api/v1/assets/${asset.id}`) + expect(assetDetail.versions.find((version: { id: string }) => version.id === assetOne.id)?.isCurrent).toBe(true) + expect(assetDetail.versions.filter((version: { isCurrent: boolean }) => version.isCurrent)).toHaveLength(1) + + const shot = await request('POST', `/api/v1/episodes/${episodeId}/shots`, { + shotNumber: 1, + sceneNumber: 1, + title: '测试镜头', + description: '', + shotType: '中景', + cameraMotion: '静止', + durationMs: 3000, + characterAssetIds: [], + sceneAssetId: null, + sortOrder: 100, + }) + const shotOne = await request('POST', `/api/v1/shots/${shot.id}/versions`, { subtitleText: '镜头第一版', generationParams: { source: 'test' } }) + await request('POST', `/api/v1/shots/${shot.id}/versions`, { subtitleText: '镜头第二版', videoStorageKey: `${workspaceId}/${projectId}/shots/video/newer.mp4`, generationParams: { source: 'test' } }) + await request('POST', `/api/v1/shots/${shot.id}/versions/${shotOne.id}/activate`) + const editedShot = await request('POST', `/api/v1/shots/${shot.id}/versions`, { + production: { + trimStartMs: 450, + playbackRate: 1.25, + audioVolume: 0.7, + fit: 'cover', + transition: 'fade', + transitionDurationMs: 300, + }, + generationParams: { operation: 'production-edit' }, + }) + expect(editedShot.version).toBe(3) + expect(editedShot.subtitleText).toBe('镜头第一版') + expect(editedShot.videoStorageKey).toBeNull() + expect(editedShot.generationParams.production).toEqual({ + trimStartMs: 450, + playbackRate: 1.25, + audioVolume: 0.7, + fit: 'cover', + transition: 'fade', + transitionDurationMs: 300, + }) + const shotDetail = await request('GET', `/api/v1/shots/${shot.id}`) + expect(shotDetail.versions.find((version: { id: string }) => version.id === editedShot.id)?.isCurrent).toBe(true) + expect(shotDetail.versions.filter((version: { isCurrent: boolean }) => version.isCurrent)).toHaveLength(1) + + const trimmed = await request('PATCH', `/api/v1/shots/${shot.id}/production`, { + durationMs: 1850, + title: '裁剪后的测试镜头', + subtitleText: '裁剪后的字幕', + production: { trimStartMs: 650 }, + generationParams: { operation: 'timeline-trim' }, + }) + expect(trimmed.shot.durationMs).toBe(1850) + expect(trimmed.shot.title).toBe('裁剪后的测试镜头') + expect(trimmed.version.version).toBe(4) + expect(trimmed.version.subtitleText).toBe('裁剪后的字幕') + expect(trimmed.version.generationParams.operation).toBe('timeline-trim') + expect(trimmed.version.generationParams.production).toEqual({ + trimStartMs: 650, + playbackRate: 1.25, + audioVolume: 0.7, + fit: 'cover', + transition: 'fade', + transitionDurationMs: 300, + }) + + const invalidProduction = await app.inject({ + method: 'POST', + url: `/api/v1/shots/${shot.id}/versions`, + headers: { authorization: `Bearer ${token}` }, + payload: { production: { audioVolume: 2.1 } }, + }) + expect(invalidProduction.statusCode).toBe(400) + }) + + it('assigns, comments on, and approves a version review', async () => { + const scripts = await request('GET', `/api/v1/episodes/${episodeId}/scripts`) + const current = scripts.find((version: { isCurrent: boolean }) => version.isCurrent) + const review = await request('POST', `/api/v1/workspaces/${workspaceId}/reviews`, { + targetType: 'SCRIPT_VERSION', + targetId: current.id, + summary: '测试剧本审核', + }) + const assigned = await request('PATCH', `/api/v1/reviews/${review.id}`, { assignedToId: userId }) + expect(assigned.assignedToId).toBe(userId) + + const comment = await request('POST', `/api/v1/reviews/${review.id}/comments`, { + body: '第 2 秒需要调整对白。', + timecodeMs: 2000, + metadata: {}, + }) + expect(comment.timecodeMs).toBe(2000) + + const decision = await request('POST', `/api/v1/reviews/${review.id}/decision`, { + status: 'APPROVED', + summary: '测试通过', + }) + expect(decision.status).toBe('APPROVED') + const detail = await request('GET', `/api/v1/reviews/${review.id}`) + expect(detail.comments).toHaveLength(1) + expect(detail.status).toBe('APPROVED') + }) + + it('reports usage and prevents jobs from exceeding the workspace limit', async () => { + const summary = await request('GET', `/api/v1/workspaces/${workspaceId}/billing/summary`) + expect(summary.monthlyCreditLimit).toBe(10000) + expect(summary.usedCredits).toBe(0) + expect(summary.reservedCredits).toBe(0) + + await db.update(workspaces).set({ monthlyCreditLimit: 1 }).where(eq(workspaces.id, workspaceId)) + try { + const response = await app.inject({ + method: 'POST', + url: `/api/v1/projects/${projectId}/jobs`, + headers: { authorization: `Bearer ${token}` }, + payload: { + type: 'ASSET_GENERATE', + input: { assetId, prompt: '额度拦截测试' }, + }, + }) + expect(response.statusCode).toBe(402) + const body = response.json() + expect(body.error.code, response.body).toBe('CREDIT_LIMIT_EXCEEDED') + expect(body.error.details.estimatedCredits).toBe(120) + } finally { + await db.update(workspaces).set({ monthlyCreditLimit: 10000 }).where(eq(workspaces.id, workspaceId)) + } + }) +}) diff --git a/server/src/routes/workspace-invitations.integration.test.ts b/server/src/routes/workspace-invitations.integration.test.ts new file mode 100644 index 0000000..a8337b5 --- /dev/null +++ b/server/src/routes/workspace-invitations.integration.test.ts @@ -0,0 +1,227 @@ +import { createHash } from 'node:crypto' +import type { FastifyInstance } from 'fastify' +import { and, eq, inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { auditLogs, users, workspaceInvitations, workspaces } from '../db/schema.js' +import type { WorkspaceInvitationEmailInput } from '../lib/mailer.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +interface CreatedInvitation { + invitation: { + id: string + email: string + role: string + status: string + expiresAt: string + } + token: string + emailDelivery: { + status: 'SENT' | 'NOT_CONFIGURED' | 'FAILED' + provider: 'resend' | 'development' | null + } +} + +describe.sequential('workspace invitations', () => { + let app: FastifyInstance + let owner: Session + let invitee: Session + let outsider: Session + let editor: Session + let workspaceId = '' + let acceptedInvitation: CreatedInvitation + let failInvitationDelivery = false + const invitationEmails: WorkspaceInvitationEmailInput[] = [] + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string | null, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: token ? { authorization: `Bearer ${token}` } : undefined, + payload, + }) + } + + async function request>(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.statusCode === 204 ? null : response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + async function createInvitation(email: string, role = 'EDITOR') { + return request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/invitations`, { email, role }) as Promise + } + + beforeAll(async () => { + app = await buildApp({ + invitationMailer: { + async send(input) { + invitationEmails.push(input) + if (failInvitationDelivery) throw new Error('mailbox unavailable') + return { sent: true, provider: 'resend', id: `email-${invitationEmails.length}` } + }, + }, + }) + owner = await registerAccount('invitation-owner') + invitee = await registerAccount('invitation-target') + outsider = await registerAccount('invitation-outsider') + editor = await registerAccount('invitation-editor') + workspaceId = owner.workspaces[0].id + await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: editor.user.email, + role: 'EDITOR', + }) + }) + + afterAll(async () => { + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('lets administrators create and list a hashed invitation', async () => { + acceptedInvitation = await createInvitation(invitee.user.email.toUpperCase(), 'REVIEWER') + expect(acceptedInvitation.token).toMatch(/^[A-Za-z0-9_-]{43}$/) + expect(acceptedInvitation.invitation).toMatchObject({ + email: invitee.user.email, + role: 'REVIEWER', + status: 'PENDING', + }) + expect(acceptedInvitation.emailDelivery).toEqual({ status: 'SENT', provider: 'resend' }) + expect(acceptedInvitation.invitation).not.toHaveProperty('tokenHash') + + expect(invitationEmails.at(-1)).toMatchObject({ + to: invitee.user.email, + inviterName: 'invitation-owner account', + roleLabel: '审核员', + }) + expect(invitationEmails.at(-1)?.workspaceName).toContain('invitation-owner workspace') + const invitationEmailUrl = new URL(invitationEmails.at(-1)!.url) + expect(invitationEmailUrl.searchParams.get('invite')).toBe(acceptedInvitation.token) + + const [stored] = await db.select().from(workspaceInvitations) + .where(eq(workspaceInvitations.id, acceptedInvitation.invitation.id)).limit(1) + expect(stored?.tokenHash).toBe(createHash('sha256').update(acceptedInvitation.token).digest('hex')) + expect(stored?.tokenHash).not.toContain(acceptedInvitation.token) + + const listed = await request>>(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/invitations`) + expect(listed).toEqual(expect.arrayContaining([expect.objectContaining({ id: acceptedInvitation.invitation.id, status: 'PENDING' })])) + expect(JSON.stringify(listed)).not.toContain(acceptedInvitation.token) + expect(JSON.stringify(listed)).not.toContain('tokenHash') + }) + + it('preserves the invitation when email delivery fails', async () => { + failInvitationDelivery = true + let created: CreatedInvitation + try { + created = await createInvitation(outsider.user.email, 'VIEWER') + } finally { + failInvitationDelivery = false + } + + expect(created!.emailDelivery).toEqual({ status: 'FAILED', provider: null }) + const [stored] = await db.select({ id: workspaceInvitations.id, revokedAt: workspaceInvitations.revokedAt }) + .from(workspaceInvitations).where(eq(workspaceInvitations.id, created!.invitation.id)).limit(1) + expect(stored).toEqual({ id: created!.invitation.id, revokedAt: null }) + }) + + it('rejects unauthenticated and non-admin invitation management', async () => { + const unauthenticated = await inject(null, 'GET', `/api/v1/workspaces/${workspaceId}/invitations`) + expect(unauthenticated.statusCode).toBe(401) + + const forbiddenList = await inject(editor.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/invitations`) + expect(forbiddenList.statusCode, forbiddenList.body).toBe(403) + const forbiddenCreate = await inject(editor.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/invitations`, { + email: outsider.user.email, + role: 'VIEWER', + }) + expect(forbiddenCreate.statusCode, forbiddenCreate.body).toBe(403) + }) + + it('requires the authenticated account email and accepts exactly once', async () => { + const wrongAccount = await inject(outsider.accessToken, 'POST', '/api/v1/workspaces/invitations/accept', { + token: acceptedInvitation.token, + }) + expect(wrongAccount.statusCode, wrongAccount.body).toBe(403) + + const accepted = await request<{ workspace: { id: string; role: string }; invitation: { status: string } }>( + invitee.accessToken, + 'POST', + '/api/v1/workspaces/invitations/accept', + { token: acceptedInvitation.token }, + ) + expect(accepted.workspace).toMatchObject({ id: workspaceId, role: 'REVIEWER' }) + expect(accepted.invitation.status).toBe('ACCEPTED') + + const available = await request>(invitee.accessToken, 'GET', '/api/v1/workspaces') + expect(available).toEqual(expect.arrayContaining([expect.objectContaining({ id: workspaceId, role: 'REVIEWER' })])) + + const duplicate = await inject(invitee.accessToken, 'POST', '/api/v1/workspaces/invitations/accept', { + token: acceptedInvitation.token, + }) + expect(duplicate.statusCode, duplicate.body).toBe(409) + }) + + it('revokes invitations and prevents later acceptance', async () => { + const created = await createInvitation(outsider.user.email, 'VIEWER') + const revoked = await inject(owner.accessToken, 'DELETE', `/api/v1/workspaces/${workspaceId}/invitations/${created.invitation.id}`) + expect(revoked.statusCode, revoked.body).toBe(204) + + const rejected = await inject(outsider.accessToken, 'POST', '/api/v1/workspaces/invitations/accept', { token: created.token }) + expect(rejected.statusCode, rejected.body).toBe(400) + expect(rejected.json().error.message).toContain('revoked') + + const listed = await request>(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/invitations`) + expect(listed.some((invitation) => invitation.id === created.invitation.id)).toBe(false) + }) + + it('rejects expired invitations and records lifecycle audit events', async () => { + const created = await createInvitation(outsider.user.email, 'EDITOR') + await db.update(workspaceInvitations).set({ expiresAt: new Date(Date.now() - 1000) }) + .where(eq(workspaceInvitations.id, created.invitation.id)) + + const expired = await inject(outsider.accessToken, 'POST', '/api/v1/workspaces/invitations/accept', { token: created.token }) + expect(expired.statusCode, expired.body).toBe(400) + expect(expired.json().error.message).toContain('expired') + + const listed = await request>(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/invitations`) + expect(listed).toEqual(expect.arrayContaining([expect.objectContaining({ id: created.invitation.id, status: 'EXPIRED' })])) + + const actions = await db.select({ action: auditLogs.action }).from(auditLogs).where(and( + eq(auditLogs.workspaceId, workspaceId), + inArray(auditLogs.action, ['member.invitation.create', 'member.invitation.revoke', 'member.invitation.accept']), + )) + expect(actions.map((row) => row.action)).toEqual(expect.arrayContaining([ + 'member.invitation.create', + 'member.invitation.revoke', + 'member.invitation.accept', + ])) + }) +}) diff --git a/server/src/routes/workspace-members.integration.test.ts b/server/src/routes/workspace-members.integration.test.ts new file mode 100644 index 0000000..a742625 --- /dev/null +++ b/server/src/routes/workspace-members.integration.test.ts @@ -0,0 +1,141 @@ +import type { FastifyInstance } from 'fastify' +import { inArray } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { buildApp } from '../app.js' +import { db } from '../db/client.js' +import { users, workspaces } from '../db/schema.js' + +interface Session { + accessToken: string + user: { id: string; email: string } + workspaces: Array<{ id: string; role: string }> +} + +describe.sequential('workspace member permissions', () => { + let app: FastifyInstance + let owner: Session + let editor: Session + let secondMember: Session + let workspaceId = '' + const userIds: string[] = [] + const ownedWorkspaceIds: string[] = [] + + async function inject(token: string, method: string, url: string, payload?: unknown) { + return app.inject({ + method, + url, + headers: { authorization: `Bearer ${token}` }, + payload, + }) + } + + async function request(token: string, method: string, url: string, payload?: unknown) { + const response = await inject(token, method, url, payload) + expect(response.statusCode, response.body).toBeLessThan(400) + return response.statusCode === 204 ? null : response.json() + } + + async function registerAccount(label: string): Promise { + const nonce = crypto.randomUUID().slice(0, 8) + const response = await app.inject({ + method: 'POST', + url: '/api/v1/auth/register', + payload: { + email: `${label}-${nonce}@frameflow.test`, + password: 'Integration2026!', + displayName: `${label} account`, + workspaceName: `${label} workspace ${nonce}`, + }, + }) + expect(response.statusCode, response.body).toBe(201) + const session = response.json() as Session + userIds.push(session.user.id) + ownedWorkspaceIds.push(session.workspaces[0].id) + return session + } + + beforeAll(async () => { + app = await buildApp() + owner = await registerAccount('owner') + editor = await registerAccount('editor') + secondMember = await registerAccount('member') + workspaceId = owner.workspaces[0].id + }) + + afterAll(async () => { + if (ownedWorkspaceIds.length) await db.delete(workspaces).where(inArray(workspaces.id, ownedWorkspaceIds)) + if (userIds.length) await db.delete(users).where(inArray(users.id, userIds)) + await app.close() + }) + + it('lets an owner add an existing account while editors can only list members', async () => { + const membership = await request(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: editor.user.email, + role: 'EDITOR', + }) + expect(membership.role).toBe('EDITOR') + + const members = await request(editor.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/members`) + expect(members.map((member: { userId: string }) => member.userId)).toEqual(expect.arrayContaining([owner.user.id, editor.user.id])) + + const availableWorkspaces = await request(editor.accessToken, 'GET', '/api/v1/workspaces') + expect(availableWorkspaces.map((workspace: { id: string }) => workspace.id)).toEqual(expect.arrayContaining([ + editor.workspaces[0].id, + workspaceId, + ])) + + const forbidden = await inject(editor.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: secondMember.user.email, + role: 'VIEWER', + }) + expect(forbidden.statusCode, forbidden.body).toBe(403) + expect(forbidden.json().error.code).toBe('FORBIDDEN') + }) + + it('lets an owner promote a member and an admin manage another non-owner member', async () => { + const promoted = await request(owner.accessToken, 'PATCH', `/api/v1/workspaces/${workspaceId}/members/${editor.user.id}`, { + role: 'ADMIN', + }) + expect(promoted.role).toBe('ADMIN') + + const added = await request(editor.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: secondMember.user.email, + role: 'VIEWER', + }) + expect(added.role).toBe('VIEWER') + + const updated = await request(editor.accessToken, 'PATCH', `/api/v1/workspaces/${workspaceId}/members/${secondMember.user.id}`, { + role: 'REVIEWER', + }) + expect(updated.role).toBe('REVIEWER') + }) + + it('protects the owner membership from upsert, role changes, and removal', async () => { + const upsert = await inject(owner.accessToken, 'POST', `/api/v1/workspaces/${workspaceId}/members`, { + email: owner.user.email, + role: 'ADMIN', + }) + expect(upsert.statusCode, upsert.body).toBe(403) + + const change = await inject(editor.accessToken, 'PATCH', `/api/v1/workspaces/${workspaceId}/members/${owner.user.id}`, { + role: 'VIEWER', + }) + expect(change.statusCode, change.body).toBe(403) + + const remove = await inject(editor.accessToken, 'DELETE', `/api/v1/workspaces/${workspaceId}/members/${owner.user.id}`) + expect(remove.statusCode, remove.body).toBe(403) + + const members = await request(owner.accessToken, 'GET', `/api/v1/workspaces/${workspaceId}/members`) + expect(members.find((member: { userId: string }) => member.userId === owner.user.id)?.role).toBe('OWNER') + }) + + it('prevents an admin from changing or removing their own membership', async () => { + const change = await inject(editor.accessToken, 'PATCH', `/api/v1/workspaces/${workspaceId}/members/${editor.user.id}`, { + role: 'VIEWER', + }) + expect(change.statusCode, change.body).toBe(403) + + const remove = await inject(editor.accessToken, 'DELETE', `/api/v1/workspaces/${workspaceId}/members/${editor.user.id}`) + expect(remove.statusCode, remove.body).toBe(403) + }) +}) diff --git a/server/src/routes/workspaces.ts b/server/src/routes/workspaces.ts new file mode 100644 index 0000000..17b0660 --- /dev/null +++ b/server/src/routes/workspaces.ts @@ -0,0 +1,327 @@ +import { randomBytes } from 'node:crypto' +import type { FastifyInstance } from 'fastify' +import { and, desc, eq, isNull, sql } from 'drizzle-orm' +import { z } from 'zod' +import { db } from '../db/client.js' +import { memberships, users, workspaceInvitations, workspaces } from '../db/schema.js' +import { hashToken, requireAuth } from '../lib/auth.js' +import { audit } from '../lib/audit.js' +import { errors } from '../lib/errors.js' +import { parseWith } from '../lib/http.js' +import { + resendInvitationMailer, + workspaceInvitationUrl, + type InvitationMailer, +} from '../lib/mailer.js' +import { requireWorkspacePermission } from '../lib/permissions.js' + +const workspaceParams = z.object({ workspaceId: z.uuid() }) +const memberParams = z.object({ workspaceId: z.uuid(), userId: z.uuid() }) +const invitationParams = z.object({ workspaceId: z.uuid(), invitationId: z.uuid() }) +const memberBody = z.object({ + email: z.email(), + role: z.enum(['ADMIN', 'EDITOR', 'REVIEWER', 'VIEWER']), +}) +const roleBody = z.object({ role: z.enum(['ADMIN', 'EDITOR', 'REVIEWER', 'VIEWER']) }) +const invitationBody = memberBody.extend({ + expiresInDays: z.number().int().min(1).max(30).default(7), +}) +const acceptInvitationBody = z.object({ + token: z.string().regex(/^[A-Za-z0-9_-]{43}$/, 'Invitation token is invalid'), +}) + +const invitationRoleLabels = { + ADMIN: '管理员', + EDITOR: '编辑', + REVIEWER: '审核员', + VIEWER: '访客', +} as const + +export interface WorkspaceRouteOptions { + invitationMailer?: InvitationMailer +} + +function invitationResponse(invitation: typeof workspaceInvitations.$inferSelect) { + return { + id: invitation.id, + workspaceId: invitation.workspaceId, + email: invitation.email, + role: invitation.role, + expiresAt: invitation.expiresAt, + acceptedAt: invitation.acceptedAt, + acceptedById: invitation.acceptedById, + revokedAt: invitation.revokedAt, + invitedById: invitation.invitedById, + createdAt: invitation.createdAt, + updatedAt: invitation.updatedAt, + status: invitation.acceptedAt + ? 'ACCEPTED' as const + : invitation.revokedAt + ? 'REVOKED' as const + : invitation.expiresAt.getTime() <= Date.now() + ? 'EXPIRED' as const + : 'PENDING' as const, + } +} + +export async function workspaceRoutes(app: FastifyInstance, options: WorkspaceRouteOptions = {}) { + const invitationMailer = options.invitationMailer ?? resendInvitationMailer + app.addHook('preHandler', requireAuth) + + app.get('/', async (request) => { + return db.select({ + id: workspaces.id, + name: workspaces.name, + slug: workspaces.slug, + plan: workspaces.plan, + monthlyCreditLimit: workspaces.monthlyCreditLimit, + role: memberships.role, + createdAt: workspaces.createdAt, + }).from(memberships).innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId)).where(eq(memberships.userId, request.user.sub)) + }) + + app.get('/:workspaceId/members', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'project:read') + return db.select({ + userId: users.id, + email: users.email, + displayName: users.displayName, + avatarKey: users.avatarKey, + role: memberships.role, + joinedAt: memberships.joinedAt, + }).from(memberships).innerJoin(users, eq(users.id, memberships.userId)).where(eq(memberships.workspaceId, workspaceId)) + }) + + app.get('/:workspaceId/invitations', async (request) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + const rows = await db.select().from(workspaceInvitations).where(and( + eq(workspaceInvitations.workspaceId, workspaceId), + isNull(workspaceInvitations.acceptedAt), + isNull(workspaceInvitations.revokedAt), + )).orderBy(desc(workspaceInvitations.createdAt)) + return rows.map(invitationResponse) + }) + + app.post('/:workspaceId/invitations', { + config: { rateLimit: { max: 20, timeWindow: '10 minutes' } }, + }, async (request, reply) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(invitationBody, request.body) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + + const email = input.email.trim().toLowerCase() + const token = randomBytes(32).toString('base64url') + const now = new Date() + const expiresAt = new Date(now.getTime() + input.expiresInDays * 24 * 60 * 60 * 1000) + const [[workspace], [inviter]] = await Promise.all([ + db.select({ name: workspaces.name }).from(workspaces).where(eq(workspaces.id, workspaceId)).limit(1), + db.select({ email: users.email, displayName: users.displayName }).from(users).where(eq(users.id, request.user.sub)).limit(1), + ]) + if (!workspace || !inviter) throw errors.notFound('Workspace invitation context') + const invitation = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`workspace-invitation:${workspaceId}:${email}`}))`) + const [account] = await tx.select({ id: users.id }).from(users).where(eq(users.email, email)).limit(1) + if (account) { + const [membership] = await tx.select({ role: memberships.role }).from(memberships).where(and( + eq(memberships.workspaceId, workspaceId), + eq(memberships.userId, account.id), + )).limit(1) + if (membership) throw errors.conflict('This account is already a workspace member') + } + + await tx.update(workspaceInvitations).set({ revokedAt: now, updatedAt: now }).where(and( + eq(workspaceInvitations.workspaceId, workspaceId), + eq(workspaceInvitations.email, email), + isNull(workspaceInvitations.acceptedAt), + isNull(workspaceInvitations.revokedAt), + )) + const [created] = await tx.insert(workspaceInvitations).values({ + workspaceId, + email, + role: input.role, + tokenHash: hashToken(token), + expiresAt, + invitedById: request.user.sub, + }).returning() + if (!created) throw new Error('Failed to create workspace invitation') + return created + }) + + const url = workspaceInvitationUrl(token) + let emailDelivery: { status: 'SENT' | 'NOT_CONFIGURED' | 'FAILED'; provider: 'resend' | 'development' | null } + try { + const delivery = await invitationMailer.send({ + to: invitation.email, + inviterName: inviter.displayName || inviter.email, + workspaceName: workspace.name, + roleLabel: invitationRoleLabels[input.role], + expiresAt: invitation.expiresAt, + url, + }) + emailDelivery = delivery.sent + ? { status: 'SENT', provider: delivery.provider } + : { status: 'NOT_CONFIGURED', provider: delivery.provider } + } catch (error) { + request.log.error({ err: error, invitationId: invitation.id }, 'Workspace invitation email delivery failed') + emailDelivery = { status: 'FAILED', provider: null } + } + + await audit({ + request, + workspaceId, + action: 'member.invitation.create', + resourceType: 'workspace_invitation', + resourceId: invitation.id, + after: { email: invitation.email, role: invitation.role, expiresAt: invitation.expiresAt.toISOString(), emailDeliveryStatus: emailDelivery.status }, + }) + return reply.code(201).send({ invitation: invitationResponse(invitation), token, emailDelivery }) + }) + + app.delete('/:workspaceId/invitations/:invitationId', async (request, reply) => { + const { workspaceId, invitationId } = parseWith(invitationParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + const [invitation] = await db.select().from(workspaceInvitations).where(and( + eq(workspaceInvitations.id, invitationId), + eq(workspaceInvitations.workspaceId, workspaceId), + )).limit(1) + if (!invitation) throw errors.notFound('Workspace invitation') + if (invitation.acceptedAt) throw errors.conflict('An accepted invitation cannot be revoked') + if (invitation.revokedAt) return reply.code(204).send() + + const revokedAt = new Date() + await db.update(workspaceInvitations).set({ revokedAt, updatedAt: revokedAt }).where(eq(workspaceInvitations.id, invitation.id)) + await audit({ + request, + workspaceId, + action: 'member.invitation.revoke', + resourceType: 'workspace_invitation', + resourceId: invitation.id, + before: { email: invitation.email, role: invitation.role, expiresAt: invitation.expiresAt.toISOString() }, + after: { revokedAt: revokedAt.toISOString() }, + }) + return reply.code(204).send() + }) + + app.post('/invitations/accept', { + config: { rateLimit: { max: 20, timeWindow: '1 minute' } }, + }, async (request, reply) => { + const { token } = parseWith(acceptInvitationBody, request.body) + const tokenHash = hashToken(token) + const acceptedAt = new Date() + const result = await db.transaction(async (tx) => { + await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`workspace-invitation-token:${tokenHash}`}))`) + const [row] = await tx.select({ invitation: workspaceInvitations, workspace: workspaces }).from(workspaceInvitations) + .innerJoin(workspaces, eq(workspaces.id, workspaceInvitations.workspaceId)) + .where(eq(workspaceInvitations.tokenHash, tokenHash)).limit(1) + if (!row) throw errors.badRequest('Workspace invitation is invalid') + if (row.invitation.acceptedAt) throw errors.conflict('Workspace invitation has already been accepted') + if (row.invitation.revokedAt) throw errors.badRequest('Workspace invitation has been revoked') + if (row.invitation.expiresAt.getTime() <= acceptedAt.getTime()) throw errors.badRequest('Workspace invitation has expired') + + const [account] = await tx.select({ id: users.id, email: users.email, disabledAt: users.disabledAt }).from(users) + .where(eq(users.id, request.user.sub)).limit(1) + if (!account || account.disabledAt) throw errors.unauthorized('Account is unavailable') + if (account.email.toLowerCase() !== row.invitation.email) { + throw errors.forbidden('The signed-in account does not match this invitation') + } + + await tx.insert(memberships).values({ + workspaceId: row.invitation.workspaceId, + userId: account.id, + role: row.invitation.role, + invitedById: row.invitation.invitedById, + }).onConflictDoNothing() + const [membership] = await tx.select().from(memberships).where(and( + eq(memberships.workspaceId, row.invitation.workspaceId), + eq(memberships.userId, account.id), + )).limit(1) + if (!membership) throw new Error('Failed to create invitation membership') + + const [accepted] = await tx.update(workspaceInvitations).set({ + acceptedAt, + acceptedById: account.id, + updatedAt: acceptedAt, + }).where(eq(workspaceInvitations.id, row.invitation.id)).returning() + if (!accepted) throw new Error('Failed to accept workspace invitation') + return { invitation: accepted, workspace: row.workspace, membership } + }) + + await audit({ + request, + workspaceId: result.workspace.id, + action: 'member.invitation.accept', + resourceType: 'workspace_invitation', + resourceId: result.invitation.id, + after: { email: result.invitation.email, role: result.membership.role, acceptedAt: acceptedAt.toISOString() }, + }) + return reply.code(201).send({ + invitation: invitationResponse(result.invitation), + workspace: { + id: result.workspace.id, + name: result.workspace.name, + slug: result.workspace.slug, + plan: result.workspace.plan, + monthlyCreditLimit: result.workspace.monthlyCreditLimit, + role: result.membership.role, + }, + }) + }) + + app.post('/:workspaceId/members', async (request, reply) => { + const { workspaceId } = parseWith(workspaceParams, request.params) + const input = parseWith(memberBody, request.body) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + const [user] = await db.select({ id: users.id, email: users.email }).from(users).where(eq(users.email, input.email.toLowerCase())).limit(1) + if (!user) throw errors.notFound('User account') + const [existingMembership] = await db.select({ role: memberships.role }).from(memberships).where(and( + eq(memberships.workspaceId, workspaceId), + eq(memberships.userId, user.id), + )).limit(1) + if (existingMembership?.role === 'OWNER') throw errors.forbidden('The workspace owner role cannot be changed') + + const [membership] = await db.insert(memberships).values({ + workspaceId, + userId: user.id, + role: input.role, + invitedById: request.user.sub, + }).onConflictDoUpdate({ + target: [memberships.workspaceId, memberships.userId], + set: { role: input.role, updatedAt: new Date() }, + }).returning() + + await audit({ request, workspaceId, action: 'member.upsert', resourceType: 'membership', resourceId: user.id, after: { role: input.role } }) + return reply.code(201).send(membership) + }) + + app.patch('/:workspaceId/members/:userId', async (request) => { + const { workspaceId, userId } = parseWith(memberParams, request.params) + const input = parseWith(roleBody, request.body) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + if (userId === request.user.sub) throw errors.forbidden('You cannot change your own workspace role') + + const [existing] = await db.select().from(memberships).where(and(eq(memberships.workspaceId, workspaceId), eq(memberships.userId, userId))).limit(1) + if (!existing) throw errors.notFound('Membership') + if (existing.role === 'OWNER') throw errors.forbidden('The workspace owner role cannot be changed') + + const [updated] = await db.update(memberships).set({ role: input.role, updatedAt: new Date() }).where(and( + eq(memberships.workspaceId, workspaceId), + eq(memberships.userId, userId), + )).returning() + await audit({ request, workspaceId, action: 'member.role.update', resourceType: 'membership', resourceId: userId, before: { role: existing.role }, after: { role: input.role } }) + return updated + }) + + app.delete('/:workspaceId/members/:userId', async (request, reply) => { + const { workspaceId, userId } = parseWith(memberParams, request.params) + await requireWorkspacePermission(request, workspaceId, 'members:manage') + if (userId === request.user.sub) throw errors.forbidden('You cannot remove yourself from the workspace') + const [existing] = await db.select().from(memberships).where(and(eq(memberships.workspaceId, workspaceId), eq(memberships.userId, userId))).limit(1) + if (!existing) throw errors.notFound('Membership') + if (existing.role === 'OWNER') throw errors.forbidden('The workspace owner cannot be removed') + await db.delete(memberships).where(and(eq(memberships.workspaceId, workspaceId), eq(memberships.userId, userId))) + await audit({ request, workspaceId, action: 'member.remove', resourceType: 'membership', resourceId: userId, before: { role: existing.role } }) + return reply.code(204).send() + }) +} diff --git a/server/src/storage/client.test.ts b/server/src/storage/client.test.ts new file mode 100644 index 0000000..0562792 --- /dev/null +++ b/server/src/storage/client.test.ts @@ -0,0 +1,14 @@ +import { afterAll, describe, expect, it } from 'vitest' +import { closeStorage, projectSeedObjectKey } from './client.js' + +afterAll(() => closeStorage()) + +describe('project seed object keys', () => { + it('keeps bundled media inside the owning project namespace', () => { + expect(projectSeedObjectKey( + '61380d0c-2992-402e-8468-dc54b7bc5903', + '457b73f9-4e79-4e9a-b98d-91b943ee6cb1', + '../../Character 01.JPG', + )).toBe('61380d0c-2992-402e-8468-dc54b7bc5903/457b73f9-4e79-4e9a-b98d-91b943ee6cb1/seed/Character-01.jpg') + }) +}) diff --git a/server/src/storage/client.ts b/server/src/storage/client.ts new file mode 100644 index 0000000..c553c1a --- /dev/null +++ b/server/src/storage/client.ts @@ -0,0 +1,105 @@ +import { + DeleteObjectCommand, + GetObjectCommand, + HeadBucketCommand, + PutObjectCommand, + S3Client, +} from '@aws-sdk/client-s3' +import { getSignedUrl } from '@aws-sdk/s3-request-presigner' +import { config } from '../config.js' + +function createStorageClient(endpoint: string) { + return new S3Client({ + endpoint, + region: config.S3_REGION, + forcePathStyle: config.S3_FORCE_PATH_STYLE, + credentials: { + accessKeyId: config.S3_ACCESS_KEY, + secretAccessKey: config.S3_SECRET_KEY, + }, + }) +} + +export const storage = createStorageClient(config.S3_ENDPOINT) +const signingStorage = config.S3_PUBLIC_ENDPOINT && config.S3_PUBLIC_ENDPOINT !== config.S3_ENDPOINT + ? createStorageClient(config.S3_PUBLIC_ENDPOINT) + : storage + +export function closeStorage() { + storage.destroy() + if (signingStorage !== storage) signingStorage.destroy() +} + +export async function checkStorage() { + await storage.send(new HeadBucketCommand({ Bucket: config.S3_BUCKET })) +} + +export async function putObject(input: { + key: string + body: Buffer | Uint8Array | string + contentType: string + metadata?: Record +}) { + await storage.send(new PutObjectCommand({ + Bucket: config.S3_BUCKET, + Key: input.key, + Body: input.body, + ContentType: input.contentType, + Metadata: input.metadata, + })) + return { key: input.key, bucket: config.S3_BUCKET } +} + +export async function deleteObject(key: string) { + await storage.send(new DeleteObjectCommand({ Bucket: config.S3_BUCKET, Key: key })) +} + +export async function getObjectBuffer(key: string) { + const response = await storage.send(new GetObjectCommand({ Bucket: config.S3_BUCKET, Key: key })) + if (!response.Body) throw new Error(`Object ${key} has no body`) + const bytes = await response.Body.transformToByteArray() + return Buffer.from(bytes) +} + +export async function presignUpload(key: string, contentType: string, expiresIn = 900) { + return getSignedUrl(signingStorage, new PutObjectCommand({ + Bucket: config.S3_BUCKET, + Key: key, + ContentType: contentType, + }), { expiresIn }) +} + +export async function presignDownload(key: string, expiresIn = 900, filename?: string) { + const encodedFilename = filename + ? encodeURIComponent(filename).replace(/['()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`) + : undefined + const disposition = filename + ? `attachment; filename="${safeObjectName(filename)}"; filename*=UTF-8''${encodedFilename}` + : undefined + return getSignedUrl(signingStorage, new GetObjectCommand({ + Bucket: config.S3_BUCKET, + Key: key, + ...(disposition ? { ResponseContentDisposition: disposition } : {}), + }), { expiresIn }) +} + +export function safeObjectName(filename: string) { + const parts = filename.split('.') + const extension = parts.length > 1 ? `.${parts.pop()!.toLowerCase().replace(/[^a-z0-9]/g, '').slice(0, 10)}` : '' + const stem = parts.join('.').normalize('NFKD').replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'upload' + return `${stem}${extension}` +} + +export function projectObjectKey(workspaceId: string, projectId: string, filename: string) { + return `${workspaceId}/${projectId}/uploads/${crypto.randomUUID()}-${safeObjectName(filename)}` +} + +export function projectSeedObjectKey(workspaceId: string, projectId: string, filename: string) { + return `${workspaceId}/${projectId}/seed/${safeObjectName(filename)}` +} + +export function generatedObjectKey(workspaceId: string, projectId: string, category: string, extension: string) { + const safeCategory = category.replace(/[^a-z0-9_-]/gi, '-').toLowerCase() + const safeExtension = extension.replace(/[^a-z0-9]/gi, '').toLowerCase() + return `${workspaceId}/${projectId}/generated/${safeCategory}/${crypto.randomUUID()}.${safeExtension}` +} diff --git a/server/src/types/fastify.d.ts b/server/src/types/fastify.d.ts new file mode 100644 index 0000000..9090b56 --- /dev/null +++ b/server/src/types/fastify.d.ts @@ -0,0 +1,18 @@ +import '@fastify/jwt' + +declare module '@fastify/jwt' { + interface FastifyJWT { + payload: { + sub: string + email: string + displayName: string + tokenType: 'access' + } + user: { + sub: string + email: string + displayName: string + tokenType: 'access' + } + } +} diff --git a/server/src/worker.ts b/server/src/worker.ts new file mode 100644 index 0000000..5f67ea0 --- /dev/null +++ b/server/src/worker.ts @@ -0,0 +1,251 @@ +import { createServer } from 'node:http' +import { hostname } from 'node:os' +import { UnrecoverableError, Worker, type Job } from 'bullmq' +import { and, eq, inArray, ne, sql } from 'drizzle-orm' +import pino from 'pino' +import { config } from './config.js' +import { closeDatabase, db } from './db/client.js' +import { generationJobs, productionRuns, usageLedger } from './db/schema.js' +import { generationJobDurationSeconds, generationJobQueueDelaySeconds, generationJobsProcessedTotal, generationWorkerActiveJobs, generationWorkerHeartbeatTimestampSeconds, metricsRegistry } from './lib/metrics.js' +import { notifyJobTerminal } from './lib/notifications.js' +import { publishRealtimeEvent } from './lib/realtime.js' +import { createRedisConnection } from './queue/connection.js' +import { publishWorkerHeartbeat } from './queue/heartbeat.js' +import { JobCancelledError, processGenerationJob } from './queue/processors.js' +import { GENERATION_QUEUE, type GenerationJobData, type GenerationJobResult, type JobKind } from './queue/types.js' + +const connection = createRedisConnection() +const heartbeatConnection = createRedisConnection() +const logger = pino({ level: config.LOG_LEVEL, base: { service: 'frameflow-worker', environment: config.NODE_ENV } }) +const workerInstanceId = `${hostname()}:${process.pid}` +let workerReady = false +let lastHeartbeatAt = 0 +let heartbeatTimer: NodeJS.Timeout | null = null + +const worker = new Worker(GENERATION_QUEUE, async (job: Job) => { + const stopTimer = generationJobDurationSeconds.startTimer({ type: job.data.type }) + generationJobQueueDelaySeconds.observe({ type: job.data.type }, Math.max(0, (Date.now() - job.timestamp) / 1000)) + generationWorkerActiveJobs.inc() + logger.info({ event: 'job.started', jobId: job.id, databaseId: job.data.databaseId, type: job.data.type, attempt: job.attemptsMade + 1 }, 'Generation job started') + try { + const [record] = await db.select({ status: generationJobs.status, productionRunId: generationJobs.productionRunId }).from(generationJobs) + .where(eq(generationJobs.id, job.data.databaseId)).limit(1) + if (!record || record.status === 'CANCELLED') { + generationJobsProcessedTotal.inc({ type: job.data.type, result: 'cancelled' }) + throw new UnrecoverableError('Generation job was cancelled') + } + + if (record.productionRunId) { + await db.update(productionRuns).set({ + status: 'RUNNING', + startedAt: sql`coalesce(${productionRuns.startedAt}, now())`, + updatedAt: new Date(), + }).where(and(eq(productionRuns.id, record.productionRunId), eq(productionRuns.status, 'QUEUED'))) + } + + const [started] = await db.update(generationJobs).set({ + status: 'RUNNING', + progress: 1, + attempts: job.attemptsMade + 1, + startedAt: new Date(), + updatedAt: new Date(), + }).where(and(eq(generationJobs.id, job.data.databaseId), inArray(generationJobs.status, ['QUEUED', 'RUNNING']))).returning({ id: generationJobs.id }) + if (!started) throw new UnrecoverableError('Generation job was cancelled') + + await publishRealtimeEvent({ + workspaceId: job.data.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: job.data.databaseId, + payload: { id: job.data.databaseId, type: job.data.type, status: 'RUNNING', progress: 1 }, + }) + + await job.updateProgress(5) + await db.update(generationJobs).set({ progress: 5, updatedAt: new Date() }) + .where(and(eq(generationJobs.id, job.data.databaseId), ne(generationJobs.status, 'CANCELLED'))) + await publishRealtimeEvent({ + workspaceId: job.data.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: job.data.databaseId, + payload: { id: job.data.databaseId, type: job.data.type, status: 'RUNNING', progress: 5 }, + }) + + try { + const result = await processGenerationJob(job.data) + await job.updateProgress(100) + await db.transaction(async (tx) => { + const [completed] = await tx.update(generationJobs).set({ + status: 'SUCCEEDED', + progress: 100, + provider: result.provider, + providerModel: result.providerModel, + output: result.output, + completedAt: new Date(), + updatedAt: new Date(), + errorCode: null, + errorMessage: null, + }).where(and(eq(generationJobs.id, job.data.databaseId), ne(generationJobs.status, 'CANCELLED'))).returning({ id: generationJobs.id }) + if (completed && result.usage?.length) { + await tx.insert(usageLedger).values(result.usage.map((entry) => ({ + workspaceId: job.data.workspaceId, + userId: job.data.userId, + jobId: job.data.databaseId, + kind: entry.kind, + quantity: entry.quantity.toString(), + credits: entry.credits.toString(), + providerCostUsd: entry.providerCostUsd?.toString(), + }))) + } + if (completed && record.productionRunId && job.data.type === 'EPISODE_RENDER') { + await tx.update(productionRuns).set({ status: 'SUCCEEDED', completedAt: new Date(), updatedAt: new Date() }) + .where(and(eq(productionRuns.id, record.productionRunId), inArray(productionRuns.status, ['QUEUED', 'RUNNING']))) + } + }) + await Promise.all([ + publishRealtimeEvent({ + workspaceId: job.data.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: job.data.databaseId, + payload: { id: job.data.databaseId, type: job.data.type, status: 'SUCCEEDED', progress: 100 }, + }), + notifyJobTerminal({ + workspaceId: job.data.workspaceId, + userId: job.data.userId, + jobId: job.data.databaseId, + jobType: job.data.type, + status: 'SUCCEEDED', + output: result.output, + ...(job.data.projectId ? { projectId: job.data.projectId } : {}), + ...(job.data.episodeId ? { episodeId: job.data.episodeId } : {}), + }).catch((notificationError) => { + logger.error({ event: 'notification.create.failed', err: notificationError, jobId: job.data.databaseId }, 'Job completion notification failed') + return null + }), + ]) + generationJobsProcessedTotal.inc({ type: job.data.type, result: 'succeeded' }) + return result + } catch (error) { + generationJobsProcessedTotal.inc({ type: job.data.type, result: error instanceof JobCancelledError ? 'cancelled' : 'failed' }) + if (error instanceof JobCancelledError) throw new UnrecoverableError(error.message) + const exhausted = job.attemptsMade + 1 >= (job.opts.attempts ?? 1) + await db.update(generationJobs).set({ + status: exhausted ? 'FAILED' : 'QUEUED', + errorCode: 'PROCESSOR_ERROR', + errorMessage: error instanceof Error ? error.message : 'Worker failed', + completedAt: exhausted ? new Date() : null, + updatedAt: new Date(), + }).where(and(eq(generationJobs.id, job.data.databaseId), ne(generationJobs.status, 'CANCELLED'))) + if (exhausted && record.productionRunId && job.data.type === 'EPISODE_RENDER') { + await db.update(productionRuns).set({ status: 'FAILED', completedAt: new Date(), updatedAt: new Date() }) + .where(and(eq(productionRuns.id, record.productionRunId), inArray(productionRuns.status, ['QUEUED', 'RUNNING']))) + } + await publishRealtimeEvent({ + workspaceId: job.data.workspaceId, + type: 'job.updated', + resourceType: 'generation_job', + resourceId: job.data.databaseId, + payload: { + id: job.data.databaseId, + type: job.data.type, + status: exhausted ? 'FAILED' : 'QUEUED', + progress: 5, + errorMessage: error instanceof Error ? error.message : 'Worker failed', + }, + }) + if (exhausted) { + await notifyJobTerminal({ + workspaceId: job.data.workspaceId, + userId: job.data.userId, + jobId: job.data.databaseId, + jobType: job.data.type, + status: 'FAILED', + errorMessage: error instanceof Error ? error.message : 'Worker failed', + ...(job.data.projectId ? { projectId: job.data.projectId } : {}), + ...(job.data.episodeId ? { episodeId: job.data.episodeId } : {}), + }).catch((notificationError) => { + logger.error({ event: 'notification.create.failed', err: notificationError, jobId: job.data.databaseId }, 'Job failure notification failed') + }) + } + throw error + } + } finally { + generationWorkerActiveJobs.dec() + stopTimer() + } +}, { + connection, + concurrency: config.WORKER_CONCURRENCY, + lockDuration: 10 * 60 * 1000, +}) + +async function writeHeartbeat() { + try { + const heartbeat = await publishWorkerHeartbeat({ client: heartbeatConnection, instanceId: workerInstanceId }) + lastHeartbeatAt = Date.parse(heartbeat.updatedAt) + generationWorkerHeartbeatTimestampSeconds.set(lastHeartbeatAt / 1000) + } catch (error) { + logger.error({ event: 'worker.heartbeat.failed', err: error }, 'Worker heartbeat write failed') + } +} + +worker.on('ready', () => { + workerReady = true + void writeHeartbeat() + if (!heartbeatTimer) { + heartbeatTimer = setInterval(() => void writeHeartbeat(), config.WORKER_HEARTBEAT_INTERVAL_MS) + heartbeatTimer.unref() + } + logger.info({ event: 'worker.ready', concurrency: config.WORKER_CONCURRENCY, instanceId: workerInstanceId }, 'FrameFlow worker ready') +}) +worker.on('completed', (job) => logger.info({ event: 'job.completed', jobId: job.id, type: job.name, attempts: job.attemptsMade + 1 }, 'Generation job completed')) +worker.on('failed', (job, error) => logger.error({ event: 'job.failed', jobId: job?.id, type: job?.name, attempts: job ? job.attemptsMade + 1 : undefined, err: error }, 'Generation job failed')) +worker.on('error', (error) => logger.error({ event: 'worker.error', err: error }, 'Worker connection error')) + +const metricsServer = createServer(async (request, response) => { + const path = request.url?.split('?')[0] + if (path === '/health/live') { + response.writeHead(200, { 'content-type': 'application/json; charset=utf-8' }).end(JSON.stringify({ status: 'ok', service: 'frameflow-worker' })) + return + } + if (path === '/health/ready') { + const heartbeatAgeMs = lastHeartbeatAt ? Date.now() - lastHeartbeatAt : null + const ready = workerReady && heartbeatAgeMs !== null && heartbeatAgeMs <= config.WORKER_HEARTBEAT_TTL_SECONDS * 1000 + response.writeHead(ready ? 200 : 503, { 'content-type': 'application/json; charset=utf-8' }).end(JSON.stringify({ + status: ready ? 'ready' : 'not_ready', + service: 'frameflow-worker', + instanceId: workerInstanceId, + heartbeatAgeMs, + })) + return + } + if (path !== '/metrics') { + response.writeHead(404).end('Not found') + return + } + if (config.METRICS_TOKEN && request.headers.authorization !== `Bearer ${config.METRICS_TOKEN}`) { + response.writeHead(401, { 'content-type': 'text/plain; charset=utf-8' }).end('Unauthorized') + return + } + response.writeHead(200, { 'content-type': metricsRegistry.contentType }) + response.end(await metricsRegistry.metrics()) +}) + +metricsServer.listen(config.WORKER_METRICS_PORT, config.METRICS_HOST, () => { + logger.info({ event: 'metrics.ready', host: config.METRICS_HOST, port: config.WORKER_METRICS_PORT }, 'Worker metrics endpoint ready') +}) + +async function shutdown(signal: string) { + logger.info({ event: 'worker.shutdown', signal }, 'Worker shutting down') + workerReady = false + if (heartbeatTimer) clearInterval(heartbeatTimer) + await new Promise((resolve, reject) => metricsServer.close((error) => error ? reject(error) : resolve())) + await worker.close() + await Promise.all([connection.quit(), heartbeatConnection.quit()]) + await closeDatabase() + process.exit(0) +} + +process.on('SIGINT', () => void shutdown('SIGINT')) +process.on('SIGTERM', () => void shutdown('SIGTERM')) diff --git a/server/tsconfig.json b/server/tsconfig.json new file mode 100644 index 0000000..7760bee --- /dev/null +++ b/server/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2023"], + "types": ["node"], + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "exactOptionalPropertyTypes": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "outDir": "dist", + "rootDir": "src", + "sourceMap": true + }, + "include": ["src/**/*.ts"], + "exclude": ["dist", "node_modules", "src/**/*.test.ts"] +} diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..5b7e64f --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,4234 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { + AlertCircle, + ArrowLeft, + ArrowRight, + ArrowUpRight, + Bell, + BookOpenText, + Box, + CalendarDays, + Captions, + Check, + CheckCheck, + CheckCircle2, + ChevronDown, + ChevronLeft, + ChevronRight, + CircleDashed, + ClipboardCheck, + Clapperboard, + Cloud, + Command, + Copy, + Cpu, + CreditCard, + Database, + Download, + Eye, + FileText, + Film, + Gauge, + GitCompare, + Grid2X2, + History, + HardDrive, + Image, + KeyRound, + Laptop, + Layers3, + LayoutDashboard, + List, + LockKeyhole, + LogOut, + Map, + Maximize2, + Menu, + MessageSquareText, + Mic2, + MonitorPlay, + Music2, + PanelRightClose, + PanelsTopLeft, + Pause, + Play, + Plus, + RefreshCw, + Save, + Search, + Send, + Server, + Share2, + ShieldCheck, + Shapes, + SlidersHorizontal, + Smartphone, + Sparkles, + SquarePen, + Trash2, + Undo2, + Upload, + UserPlus, + Users, + Volume2, + WandSparkles, + X, + Zap, + ZoomIn, +} from 'lucide-react' +import { api, ApiError, login, logout, register, restoreSession, setSessionExpiredHandler, subscribeRealtime } from './api' +import { findAiCapability, imageProviderChoices, preferredImageProvider, preferredVideoProvider, preferredWorkflowProvider, providerVerificationState, videoProviderChoices } from './aiCapabilities' +import { projectHealthSnapshot } from './projectHealth' +import { clipTrimFromDrag, locateTimelinePosition, timelineDuration } from './timeline' + +const navItems = [ + { id: 'overview', label: '创作总览', icon: LayoutDashboard }, + { id: 'assets', label: '资产中心', icon: Shapes }, + { id: 'script', label: '剧本工坊', icon: BookOpenText }, + { id: 'storyboard', label: '智能分镜', icon: PanelsTopLeft }, + { id: 'production', label: '制作中心', icon: Clapperboard }, + { id: 'jobs', label: '任务中心', icon: CircleDashed }, + { id: 'services', label: 'AI 服务', icon: Cpu }, + { id: 'reviews', label: '审核中心', icon: ClipboardCheck }, + { id: 'publish', label: '发布管理', icon: Send }, + { id: 'team', label: '团队与权限', icon: Users }, + { id: 'audit', label: '操作日志', icon: ShieldCheck, adminOnly: true }, +] + +const fallbackShots = [ + { id: '01', scene: '旧城天台', duration: '3.2s', type: '全景', img: '/assets/scene-rooftop.jpg', copy: '暴雨掠过旧城天台,霓虹在积水中摇晃。', status: '完成' }, + { id: '02', scene: '旧城天台', duration: '2.6s', type: '中景', img: '/assets/character-linyao.jpg', copy: '林遥推开铁门,抬手遮住刺眼的探照灯。', status: '完成' }, + { id: '03', scene: '旧城天台', duration: '2.1s', type: '特写', img: '/assets/character-lucheng.jpg', copy: '陆澄回头,雨水沿着侧脸落下。', status: '完成' }, + { id: '04', scene: '旧城天台', duration: '4.0s', type: '双人', img: '/assets/scene-rooftop.jpg', copy: '两人隔着雨幕对峙,远处钟声响起。', status: '待生成' }, + { id: '05', scene: '雾城街道', duration: '3.6s', type: '航拍', img: '/assets/scene-city.jpg', copy: '镜头越过密集楼宇,追向一辆黑色轿车。', status: '待生成' }, + { id: '06', scene: '林遥工作室', duration: '2.8s', type: '近景', img: '/assets/scene-studio.jpg', copy: '录音机自动亮起,红灯在暗室中闪烁。', status: '草稿' }, +] + +const assetTypeLabels = { CHARACTER: '人物', SCENE: '场景', PROP: '道具', VOICE: '音色', MUSIC: '音乐', SHOT: '镜头' } +const assetTypeValues = { 人物: 'CHARACTER', 场景: 'SCENE', 道具: 'PROP', 音色: 'VOICE', 音乐: 'MUSIC' } +const assetStatusLabels = { DRAFT: '草稿', GENERATING: '生成中', REVIEW: '待审核', APPROVED: '已定稿', ARCHIVED: '已归档' } +const shotStatusLabels = { DRAFT: '草稿', GENERATING: '生成中', REVIEW: '待审核', APPROVED: '完成', RENDERED: '完成' } +const renderStatusLabels = { QUEUED: '排队中', RENDERING: '渲染中', REVIEW: '待审核', APPROVED: '已批准', FAILED: '失败' } +const deliveryStatusLabels = { DRAFT: '草稿', QUEUED: '排队中', PUBLISHING: '交付中', PUBLISHED: '已发布', FAILED: '失败', CANCELLED: '已取消' } +const publishingPlatformLabels = { DOWNLOAD: '下载交付', DOUYIN: '抖音', KUAISHOU: '快手', BILIBILI: 'B 站', XIAOHONGSHU: '小红书' } +const reviewStatusLabels = { OPEN: '待处理', APPROVED: '已通过', CHANGES_REQUESTED: '已退回', CANCELLED: '已取消' } +const reviewTargetLabels = { SCRIPT_VERSION: '剧本版本', ASSET_VERSION: '资产版本', SHOT_VERSION: '镜头版本', RENDER: '成片版本' } +const usageKindLabels = { TEXT_INPUT_TOKEN: '文本输入', TEXT_OUTPUT_TOKEN: '文本输出', IMAGE: '图片生成', AUDIO_SECOND: '语音生成', VIDEO_SECOND: '视频生成', RENDER_SECOND: '成片渲染', STORAGE_BYTE_MONTH: '对象存储' } +const jobTypeLabels = { PIPELINE_HEALTHCHECK: '管线检查', SCRIPT_GENERATE: '剧本生成', STORYBOARD_GENERATE: '智能分镜', ASSET_GENERATE: '画面生成', TTS_GENERATE: '配音生成', VIDEO_GENERATE: '视频生成', LIPSYNC_GENERATE: '口型同步', EPISODE_RENDER: '成片渲染', DELIVERY_PUBLISH: '发布交付' } +const workflowJobTypes = { script: 'SCRIPT_GENERATE', storyboard: 'STORYBOARD_GENERATE', image: 'ASSET_GENERATE', tts: 'TTS_GENERATE', video: 'VIDEO_GENERATE', lipsync: 'LIPSYNC_GENERATE' } +const jobStatusLabels = { QUEUED: '排队中', RUNNING: '执行中', SUCCEEDED: '已完成', FAILED: '失败', CANCELLED: '已取消' } +const productionRunStatusLabels = { QUEUED: '排队中', RUNNING: '生产中', SUCCEEDED: '已完成', FAILED: '失败', CANCELLED: '已取消' } +const billingSubscriptionStatusLabels = { no_subscription: '未开通', incomplete: '待完成支付', incomplete_expired: '支付已过期', trialing: '试用中', active: '生效中', past_due: '待补款', canceled: '已取消', unpaid: '未支付', paused: '已暂停' } +const roleLabels = { OWNER: '所有者', ADMIN: '管理员', EDITOR: '编辑', REVIEWER: '审核员', VIEWER: '访客' } +const auditCategoryOptions = [ + ['ALL', '全部操作'], + ['auth', '账户安全'], + ['member', '成员权限'], + ['project', '项目'], + ['episode', '分集'], + ['script', '剧本'], + ['asset', '资产'], + ['shot', '镜头'], + ['job', '任务'], + ['production_run', '整集生产'], + ['review', '审核'], + ['render', '渲染'], + ['delivery', '交付'], + ['billing', '计费'], + ['upload', '上传'], + ['service', '服务验证'], +] +const auditActionLabels = { + 'auth.register': '创建账号', + 'auth.sessions.revoke_others': '下线其他设备', + 'auth.session.revoke': '下线登录设备', + 'auth.email.verify': '验证邮箱', + 'auth.password.change': '修改密码', + 'auth.password.reset': '重置密码', + 'member.upsert': '添加或更新成员', + 'member.role.update': '修改成员角色', + 'member.remove': '移除成员', + 'member.invitation.create': '创建成员邀请', + 'member.invitation.revoke': '撤销成员邀请', + 'member.invitation.accept': '接受成员邀请', + 'project.create': '创建项目', + 'project.update': '更新项目', + 'project.archive': '归档项目', + 'episode.create': '创建分集', + 'episode.update': '更新分集', + 'script.version.create': '保存剧本版本', + 'script.version.activate': '切换剧本版本', + 'asset.create': '创建资产', + 'asset.update': '更新资产', + 'asset.consistency_profile.update': '更新角色档案', + 'asset.version.create': '创建资产版本', + 'asset.version.activate': '切换资产版本', + 'shot.create': '创建镜头', + 'shot.update': '更新镜头', + 'shot.delete': '删除镜头', + 'shot.production.update': '更新镜头制作', + 'shot.version.create': '创建镜头版本', + 'shot.version.activate': '切换镜头版本', + 'shots.reorder': '调整镜头顺序', + 'job.enqueue': '提交生成任务', + 'job.cancel': '取消任务', + 'job.retry': '重试任务', + 'review.create': '提交审核', + 'review.comment.create': '添加审核意见', + 'review.assign': '指派审核人', + 'review.decide': '完成审核决策', + 'render.create': '创建渲染', + 'production_run.create': '启动整集生产', + 'production_run.cancel': '取消整集生产', + 'delivery.create': '创建交付', + 'delivery.cancel': '取消交付', + 'delivery.retry': '重试交付', + 'billing.checkout.create': '创建订阅结账', + 'billing.portal.create': '打开客户门户', + 'billing.webhook.process': '同步订阅状态', + 'service.provider.verify': '验证 AI 服务连接', + 'upload.presign': '申请上传地址', + 'upload.create': '上传文件', +} +const auditResourceLabels = { membership: '成员', workspace_invitation: '成员邀请', project: '项目', episode: '分集', script_version: '剧本版本', asset: '资产', asset_version: '资产版本', shot: '镜头', shot_version: '镜头版本', generation_job: '任务', production_run: '整集生产', review_request: '审核', review_comment: '审核意见', render: '成片', delivery: '交付', billing_subscription: '订阅', provider_verification: 'AI 服务', object: '文件' } + +function fallbackAssetImage(asset) { + if (asset.type === 'CHARACTER') return asset.name.includes('陆澄') ? '/assets/character-lucheng.jpg' : asset.name.includes('苏玥') ? '/assets/character-suyue.jpg' : '/assets/character-linyao.jpg' + if (asset.type === 'SCENE') return asset.name.includes('工作室') ? '/assets/scene-studio.jpg' : asset.name.includes('城市') || asset.name.includes('中心') ? '/assets/scene-city.jpg' : '/assets/scene-rooftop.jpg' + return '/assets/scene-studio.jpg' +} + +function formatDuration(milliseconds = 0) { + const seconds = Math.max(0, Math.round(milliseconds / 1000)) + return `${String(Math.floor(seconds / 60)).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}` +} + +function formatDateTimeLocal(date) { + const local = new Date(date.getTime() - date.getTimezoneOffset() * 60_000) + return local.toISOString().slice(0, 16) +} + +function formatBytes(bytes) { + if (!bytes) return '等待生成' + if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB` + return `${(bytes / 1024 / 1024).toFixed(1)} MB` +} + +function clampNumber(value, minimum, maximum, fallback = minimum) { + const parsed = Number(value) + return Number.isFinite(parsed) ? Math.min(maximum, Math.max(minimum, parsed)) : fallback +} + +function parseAssetTags(value) { + return [...new Set(value.split(/[,,\n]/).map((tag) => tag.trim()).filter(Boolean))].slice(0, 30) +} + +function errorMessage(error) { + if (error instanceof ApiError) return error.message + return error instanceof Error ? error.message : '请求失败,请稍后重试' +} + +function invitationTokenFromLocation() { + return new URL(window.location.href).searchParams.get('invite') +} + +function invitationUrl(token) { + const url = new URL(window.location.href) + url.search = '' + url.hash = '' + url.searchParams.set('invite', token) + return url.toString() +} + +function clearInvitationFromLocation() { + const url = new URL(window.location.href) + url.searchParams.delete('invite') + window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`) +} + +function billingReturnFromLocation() { + return new URL(window.location.href).searchParams.get('billing') +} + +function clearBillingReturnFromLocation() { + const url = new URL(window.location.href) + url.searchParams.delete('billing') + url.searchParams.delete('session_id') + window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`) +} + +function publishingReturnFromLocation() { + return new URL(window.location.href).searchParams.get('publishing') +} + +function clearPublishingReturnFromLocation() { + const url = new URL(window.location.href) + url.searchParams.delete('publishing') + window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`) +} + +function App() { + const [session, setSession] = useState(null) + const [authLoading, setAuthLoading] = useState(true) + const [page, setPage] = useState('overview') + const [mobileNav, setMobileNav] = useState(false) + const [commandOpen, setCommandOpen] = useState(false) + const [generatorOpen, setGeneratorOpen] = useState(false) + const [generatorTarget, setGeneratorTarget] = useState(null) + const [projectOpen, setProjectOpen] = useState(false) + const [projectMenuOpen, setProjectMenuOpen] = useState(false) + const [workspaceId, setWorkspaceId] = useState(null) + const [projects, setProjects] = useState([]) + const [projectId, setProjectId] = useState(null) + const [project, setProject] = useState(null) + const [episodeId, setEpisodeId] = useState(null) + const [episode, setEpisode] = useState(null) + const [assets, setAssets] = useState([]) + const [assetVersionMedia, setAssetVersionMedia] = useState({}) + const [studioShots, setStudioShots] = useState([]) + const [jobs, setJobs] = useState([]) + const [renders, setRenders] = useState([]) + const [deliveries, setDeliveries] = useState([]) + const [publishingChannels, setPublishingChannels] = useState({ canManage: false, platforms: [] }) + const [productionRuns, setProductionRuns] = useState([]) + const [reviews, setReviews] = useState([]) + const [members, setMembers] = useState([]) + const [invitations, setInvitations] = useState([]) + const [inviteToken, setInviteToken] = useState(invitationTokenFromLocation) + const [inviteAccepting, setInviteAccepting] = useState(false) + const [versionTarget, setVersionTarget] = useState(null) + const [billing, setBilling] = useState(null) + const [serviceReadiness, setServiceReadiness] = useState(null) + const [billingOpen, setBillingOpen] = useState(false) + const [securityOpen, setSecurityOpen] = useState(false) + const [projectSettingsOpen, setProjectSettingsOpen] = useState(false) + const [episodeSettingsOpen, setEpisodeSettingsOpen] = useState(false) + const [notificationOpen, setNotificationOpen] = useState(false) + const [notifications, setNotifications] = useState([]) + const [notificationUnreadCount, setNotificationUnreadCount] = useState(0) + const [realtimeStatus, setRealtimeStatus] = useState('connecting') + const [dataLoading, setDataLoading] = useState(false) + const [toast, setToast] = useState('') + const invitationAttemptRef = useRef(null) + const billingReturnAttemptRef = useRef(null) + const publishingReturnAttemptRef = useRef(null) + + const showToast = useCallback((message) => { + setToast(message) + window.setTimeout(() => setToast(''), 3200) + }, []) + + useEffect(() => { + setSessionExpiredHandler(() => { + setSession(null) + setWorkspaceId(null) + setProjects([]) + setProjectId(null) + setProject(null) + setEpisodeId(null) + setEpisode(null) + setAssets([]) + setStudioShots([]) + setJobs([]) + setRenders([]) + setDeliveries([]) + setPublishingChannels({ canManage: false, platforms: [] }) + setProductionRuns([]) + setReviews([]) + setNotifications([]) + setNotificationUnreadCount(0) + setRealtimeStatus('closed') + setMembers([]) + setInvitations([]) + setBilling(null) + setServiceReadiness(null) + showToast('登录已过期,请重新登录') + }) + return () => setSessionExpiredHandler(null) + }, [showToast]) + + useEffect(() => { + let active = true + restoreSession() + .then((restored) => { + if (!active || !restored) return + setSession(restored) + setWorkspaceId(restored.workspaces?.[0]?.id ?? null) + }) + .catch((error) => { if (active) showToast(errorMessage(error)) }) + .finally(() => { if (active) setAuthLoading(false) }) + return () => { active = false } + }, [showToast]) + + useEffect(() => { + if (!session?.user?.id || !inviteToken) return undefined + const attemptKey = `${session.user.id}:${inviteToken}` + if (invitationAttemptRef.current === attemptKey) return undefined + invitationAttemptRef.current = attemptKey + let active = true + setInviteAccepting(true) + api('/workspaces/invitations/accept', { method: 'POST', body: { token: inviteToken } }) + .then(({ workspace }) => { + if (!active) return + setSession((current) => current ? { + ...current, + workspaces: [...(current.workspaces ?? []).filter((item) => item.id !== workspace.id), workspace], + } : current) + setWorkspaceId(workspace.id) + setPage('team') + setInviteToken(null) + clearInvitationFromLocation() + showToast(`已加入 ${workspace.name}`) + }) + .catch((error) => { + if (!active) return + showToast(errorMessage(error)) + if (error instanceof ApiError && [400, 404, 409].includes(error.status)) { + setInviteToken(null) + clearInvitationFromLocation() + } + }) + .finally(() => { if (active) setInviteAccepting(false) }) + return () => { active = false } + }, [inviteToken, session?.user?.id, showToast]) + + const loadNotifications = useCallback(async (nextWorkspaceId) => { + if (!nextWorkspaceId) return { items: [], unreadCount: 0 } + const result = await api(`/workspaces/${nextWorkspaceId}/notifications?limit=50`) + setNotifications(result.items) + setNotificationUnreadCount(result.unreadCount) + return result + }, []) + + const loadWorkspaceData = useCallback(async (nextWorkspaceId) => { + if (!nextWorkspaceId) return + const [workspaceRows, projectRows, jobRows, reviewRows, memberRows, invitationRows, billingSummary, readiness, notificationResult, channelSummary] = await Promise.all([ + api('/workspaces'), + api(`/workspaces/${nextWorkspaceId}/projects`), + api(`/workspaces/${nextWorkspaceId}/jobs`), + api(`/workspaces/${nextWorkspaceId}/reviews`), + api(`/workspaces/${nextWorkspaceId}/members`), + api(`/workspaces/${nextWorkspaceId}/invitations`).catch((error) => { + if (error instanceof ApiError && error.status === 403) return [] + throw error + }), + api(`/workspaces/${nextWorkspaceId}/billing/summary`).catch((error) => { + if (error instanceof ApiError && error.status === 403) return null + throw error + }), + api(`/workspaces/${nextWorkspaceId}/service-readiness`), + api(`/workspaces/${nextWorkspaceId}/notifications?limit=50`), + api(`/workspaces/${nextWorkspaceId}/publishing/channels`), + ]) + setSession((current) => current ? { ...current, workspaces: workspaceRows } : current) + setProjects(projectRows) + setJobs(jobRows) + setReviews(reviewRows) + setMembers(memberRows) + setInvitations(invitationRows) + setBilling(billingSummary) + setServiceReadiness(readiness) + setNotifications(notificationResult.items) + setNotificationUnreadCount(notificationResult.unreadCount) + setPublishingChannels(channelSummary) + setProjectId((current) => projectRows.some((item) => item.id === current) ? current : projectRows[0]?.id ?? null) + }, []) + + const refreshBilling = useCallback(async (nextWorkspaceId) => { + if (!nextWorkspaceId) return null + const summary = await api(`/workspaces/${nextWorkspaceId}/billing/summary`) + setBilling(summary) + return summary + }, []) + + const loadProjectData = useCallback(async (nextProjectId) => { + if (!nextProjectId || !workspaceId) return + const [projectRow, assetRows] = await Promise.all([ + api(`/projects/${nextProjectId}`), + api(`/projects/${nextProjectId}/assets`), + ]) + setProject(projectRow) + setEpisodeId((current) => projectRow.episodes.some((item) => item.id === current) ? current : projectRow.episodes[0]?.id ?? null) + const mapped = await Promise.all(assetRows.map(async ({ asset, currentVersion }) => { + let imageUrl = fallbackAssetImage(asset) + let hasStoredMedia = false + if (currentVersion?.storageKey?.startsWith(`${workspaceId}/`)) { + try { + const media = await api(`/assets/${asset.id}/versions/${currentVersion.id}/url`) + if (media.url) { + imageUrl = media.url + hasStoredMedia = true + } + } catch { + imageUrl = fallbackAssetImage(asset) + } + } + return { + id: asset.id, + name: asset.name, + type: assetTypeLabels[asset.type] ?? asset.type, + rawType: asset.type, + img: imageUrl, + tag: asset.tags?.[0] ?? '未分类', + tags: asset.tags ?? [], + meta: asset.description || '暂无描述', + description: asset.description, + metadata: asset.metadata ?? {}, + status: assetStatusLabels[asset.status] ?? asset.status, + rawStatus: asset.status, + version: currentVersion ? `v${String(currentVersion.version).padStart(2, '0')}` : '暂无版本', + currentVersionId: currentVersion?.id ?? null, + currentVersion: currentVersion ?? null, + hasStoredMedia, + isPlaceholder: !hasStoredMedia, + } + })) + setAssets(mapped.filter((item) => item.rawType !== 'SHOT')) + setAssetVersionMedia(Object.fromEntries(mapped.filter((item) => item.currentVersionId && item.hasStoredMedia).map((item) => [item.currentVersionId, item.img]))) + }, [workspaceId]) + + const loadEpisodeData = useCallback(async (nextEpisodeId) => { + if (!nextEpisodeId) return + const [episodeRow, shotRows, renderRows, deliveryRows, productionRunRows] = await Promise.all([ + api(`/episodes/${nextEpisodeId}`), + api(`/episodes/${nextEpisodeId}/shots`), + api(`/episodes/${nextEpisodeId}/renders`), + api(`/episodes/${nextEpisodeId}/deliveries`), + api(`/episodes/${nextEpisodeId}/production-runs`), + ]) + const mediaRows = await Promise.all(shotRows.map(async ({ shot }) => { + try { + return await api(`/shots/${shot.id}/media`) + } catch { + return { imageUrl: null, videoUrl: null, audioUrl: null } + } + })) + setEpisode(episodeRow) + setStudioShots(shotRows.map(({ shot, currentVersion }, index) => { + const imageUrl = mediaRows[index]?.imageUrl ?? null + const videoUrl = mediaRows[index]?.videoUrl ?? null + const fallbackImage = currentVersion?.imageAssetVersionId + ? assetVersionMedia[currentVersion.imageAssetVersionId] ?? fallbackShots[index % fallbackShots.length].img + : fallbackShots[index % fallbackShots.length].img + return { + id: shot.id, + label: String(shot.shotNumber).padStart(2, '0'), + title: shot.title, + scene: shot.title, + duration: `${(shot.durationMs / 1000).toFixed(1)}s`, + durationMs: shot.durationMs, + sceneNumber: shot.sceneNumber, + type: shot.shotType, + img: imageUrl ?? fallbackImage, + copy: shot.description, + status: shotStatusLabels[shot.status] ?? shot.status, + cameraMotion: shot.cameraMotion, + subtitleText: currentVersion?.subtitleText ?? '', + videoUrl, + audioUrl: mediaRows[index]?.audioUrl ?? null, + hasImageMedia: Boolean(imageUrl), + hasVisualMedia: Boolean(imageUrl || videoUrl), + isPlaceholderPreview: !imageUrl, + characterAssetIds: shot.characterAssetIds ?? [], + sceneAssetId: shot.sceneAssetId ?? null, + sortOrder: shot.sortOrder, + currentVersion, + } + })) + setRenders(renderRows) + setDeliveries(deliveryRows) + setProductionRuns(productionRunRows) + }, [assetVersionMedia]) + + const realtimeDataRef = useRef(null) + realtimeDataRef.current = { projectId, episodeId, loadProjectData, loadEpisodeData } + + useEffect(() => { + if (!workspaceId) return + setDataLoading(true) + loadWorkspaceData(workspaceId).catch((error) => showToast(errorMessage(error))).finally(() => setDataLoading(false)) + }, [workspaceId, loadWorkspaceData, showToast]) + + useEffect(() => { + const outcome = billingReturnFromLocation() + if (!workspaceId || !outcome) return undefined + const attemptKey = `${workspaceId}:${outcome}` + if (billingReturnAttemptRef.current === attemptKey) return undefined + billingReturnAttemptRef.current = attemptKey + clearBillingReturnFromLocation() + setBillingOpen(true) + showToast(outcome === 'success' ? '支付已完成,正在同步订阅' : outcome === 'cancel' ? '已取消订阅结账' : '订阅管理已返回') + + const delays = outcome === 'success' ? [0, 1500, 4000] : [0] + const timers = delays.map((delay) => window.setTimeout(() => { + refreshBilling(workspaceId).catch((error) => showToast(errorMessage(error))) + }, delay)) + return () => timers.forEach((timer) => window.clearTimeout(timer)) + }, [workspaceId, refreshBilling, showToast]) + + useEffect(() => { + const outcome = publishingReturnFromLocation() + if (!workspaceId || !outcome) return + const attemptKey = `${workspaceId}:${outcome}` + if (publishingReturnAttemptRef.current === attemptKey) return + publishingReturnAttemptRef.current = attemptKey + clearPublishingReturnFromLocation() + setPage('publish') + void loadWorkspaceData(workspaceId).catch((error) => showToast(errorMessage(error))) + showToast(outcome === 'connected' ? '渠道账号已连接' : '渠道账号授权失败') + }, [workspaceId, loadWorkspaceData, showToast]) + + useEffect(() => { + if (!projectId) { + setProject(null) + return + } + loadProjectData(projectId).catch((error) => showToast(errorMessage(error))) + }, [projectId, loadProjectData, showToast]) + + useEffect(() => { + if (!episodeId) { + setEpisode(null) + setStudioShots([]) + setRenders([]) + setDeliveries([]) + setProductionRuns([]) + return + } + loadEpisodeData(episodeId).catch((error) => showToast(errorMessage(error))) + }, [episodeId, loadEpisodeData, showToast]) + + useEffect(() => { + if (!workspaceId || !jobs.some((job) => ['QUEUED', 'RUNNING'].includes(job.status))) return undefined + const timer = window.setInterval(async () => { + try { + const nextJobs = await api(`/workspaces/${workspaceId}/jobs`) + setJobs(nextJobs) + const current = realtimeDataRef.current + if (current?.projectId) await current.loadProjectData(current.projectId) + if (current?.episodeId) await current.loadEpisodeData(current.episodeId) + } catch (error) { + showToast(errorMessage(error)) + } + }, 3500) + return () => window.clearInterval(timer) + }, [workspaceId, projectId, episodeId, jobs, loadProjectData, loadEpisodeData, showToast]) + + useEffect(() => { + if (!workspaceId || !session?.user?.id) return undefined + let refreshTimer = null + let disposed = false + const refreshRealtimeData = async () => { + try { + const [nextJobs, nextReviews] = await Promise.all([ + api(`/workspaces/${workspaceId}/jobs`), + api(`/workspaces/${workspaceId}/reviews`), + ]) + if (disposed) return + setJobs(nextJobs) + setReviews(nextReviews) + if (projectId) await loadProjectData(projectId) + if (episodeId) await loadEpisodeData(episodeId) + } catch (error) { + if (!disposed) showToast(errorMessage(error)) + } + } + const refreshSoon = () => { + if (refreshTimer !== null) window.clearTimeout(refreshTimer) + refreshTimer = window.setTimeout(() => { + refreshTimer = null + void refreshRealtimeData() + }, 180) + } + const unsubscribe = subscribeRealtime(`/workspaces/${workspaceId}/events`, { + onStatus: (status) => { if (!disposed) setRealtimeStatus(status) }, + onEvent: (event) => { + if (disposed || event?.workspaceId !== workspaceId) return + if (event.type === 'realtime.ready') { + void loadNotifications(workspaceId) + refreshSoon() + return + } + if (event.type?.startsWith('notification.')) void loadNotifications(workspaceId) + if (['job.updated', 'review.updated', 'delivery.updated', 'publishing.channel.updated'].includes(event.type)) refreshSoon() + }, + }) + return () => { + disposed = true + if (refreshTimer !== null) window.clearTimeout(refreshTimer) + unsubscribe() + } + }, [workspaceId, session?.user?.id, loadNotifications, showToast]) + + useEffect(() => { + const onKey = (event) => { + if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') { + event.preventDefault() + setCommandOpen((value) => !value) + } + if (event.key === 'Escape') { + setCommandOpen(false) + setGeneratorOpen(false) + setGeneratorTarget(null) + setProjectOpen(false) + setProjectMenuOpen(false) + setVersionTarget(null) + setBillingOpen(false) + setSecurityOpen(false) + setProjectSettingsOpen(false) + setEpisodeSettingsOpen(false) + setNotificationOpen(false) + } + } + window.addEventListener('keydown', onKey) + return () => window.removeEventListener('keydown', onKey) + }, []) + + const navigate = (nextPage) => { + setPage(nextPage) + setMobileNav(false) + setNotificationOpen(false) + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + + const openSecurity = () => { + setSecurityOpen(true) + setMobileNav(false) + } + + const openNotification = async (notification) => { + if (!notification.readAt && notification.persistent) { + const readAt = new Date().toISOString() + setNotifications((current) => current.map((item) => item.id === notification.id ? { ...item, readAt } : item)) + setNotificationUnreadCount((current) => Math.max(0, current - 1)) + void api(`/notifications/${notification.id}`, { method: 'PATCH', body: { read: true } }) + .catch((error) => { + void loadNotifications(workspaceId).catch(() => undefined) + showToast(errorMessage(error)) + }) + } + navigate(notification.page) + } + + const readAllNotifications = async () => { + if (!workspaceId || notificationUnreadCount === 0) return + const readAt = new Date().toISOString() + setNotifications((current) => current.map((item) => ({ ...item, readAt: item.readAt ?? readAt }))) + setNotificationUnreadCount(0) + try { + await api(`/workspaces/${workspaceId}/notifications/read-all`, { method: 'POST' }) + } catch (error) { + await loadNotifications(workspaceId).catch(() => undefined) + showToast(errorMessage(error)) + } + } + + const selectWorkspace = (nextWorkspaceId) => { + if (!nextWorkspaceId || nextWorkspaceId === workspaceId) { + setProjectMenuOpen(false) + return + } + setWorkspaceId(nextWorkspaceId) + setProjectId(null) + setProject(null) + setEpisodeId(null) + setEpisode(null) + setAssets([]) + setStudioShots([]) + setRenders([]) + setDeliveries([]) + setNotifications([]) + setNotificationUnreadCount(0) + setRealtimeStatus('connecting') + setInvitations([]) + setProjectMenuOpen(false) + } + + const refreshCurrentData = async () => { + if (workspaceId) await loadWorkspaceData(workspaceId) + if (projectId) await loadProjectData(projectId) + if (episodeId) await loadEpisodeData(episodeId) + } + + const refreshServiceReadiness = async () => { + if (!workspaceId) return + const readiness = await api(`/workspaces/${workspaceId}/service-readiness`) + setServiceReadiness(readiness) + } + + const verifyServiceProvider = async (providerId) => { + if (!workspaceId) return null + const readiness = await api(`/workspaces/${workspaceId}/service-readiness/providers/${providerId}/verify`, { method: 'POST' }) + setServiceReadiness(readiness) + return readiness.ai?.providers?.find((provider) => provider.id === providerId) ?? null + } + + const requireAiWorkflow = (workflowId) => { + const workflow = findAiCapability(serviceReadiness, workflowId) + if (!workflow || workflow.status === 'CONFIGURED') return + setPage('services') + const missing = workflow.missingRequirements?.join('、') || '服务端模型配置' + throw new Error(`${workflow.label}尚未配置:${missing}`) + } + + const createProject = async (input) => { + const created = await api(`/workspaces/${workspaceId}/projects`, { method: 'POST', body: input }) + await loadWorkspaceData(workspaceId) + setProjectId(created.id) + setProjectOpen(false) + showToast('项目已创建并保存') + } + + const updateProjectSettings = async (input) => { + if (!projectId) return + await api(`/projects/${projectId}`, { method: 'PATCH', body: input }) + await Promise.all([loadWorkspaceData(workspaceId), loadProjectData(projectId)]) + setProjectSettingsOpen(false) + showToast('项目资料已保存') + } + + const archiveProject = async () => { + if (!projectId) return + await api(`/projects/${projectId}`, { method: 'DELETE' }) + setProjectSettingsOpen(false) + setProjectId(null) + setProject(null) + setEpisodeId(null) + setEpisode(null) + await loadWorkspaceData(workspaceId) + showToast('项目已归档,历史制作数据仍然保留') + } + + const updateEpisodeSettings = async (input) => { + if (!episodeId) return + await api(`/episodes/${episodeId}`, { method: 'PATCH', body: input }) + await Promise.all([loadProjectData(projectId), loadEpisodeData(episodeId)]) + setEpisodeSettingsOpen(false) + showToast('分集资料已保存') + } + + const openAssetGenerator = (target = null) => { + setGeneratorTarget(target) + setGeneratorOpen(true) + } + + const closeAssetGenerator = () => { + setGeneratorOpen(false) + setGeneratorTarget(null) + } + + const generateAsset = async (input) => { + requireAiWorkflow(input.provider === 'agnes' ? 'image-agnes' : input.provider === 'replicate' ? 'image-replicate' : input.provider === 'generic' ? 'image-generic' : 'image-openai') + let assetId = input.assetId + if (!assetId) { + const created = await api(`/projects/${projectId}/assets`, { + method: 'POST', + body: { type: assetTypeValues[input.type], name: input.name, description: input.prompt, tags: ['AI 生成'] }, + }) + assetId = created.id + } + await api(`/assets/${assetId}`, { method: 'PATCH', body: { status: 'GENERATING', description: input.prompt } }) + try { + const queued = await api(`/projects/${projectId}/jobs`, { + method: 'POST', + body: { + type: 'ASSET_GENERATE', + input: { + assetId, + prompt: input.prompt, + width: input.width, + height: input.height, + referenceAssetVersionIds: input.referenceAssetVersionIds, + provider: input.provider, + params: { consistencyStrength: input.consistencyStrength }, + }, + }, + }) + closeAssetGenerator() + setPage('assets') + await refreshCurrentData() + showToast(`${input.assetId ? '一致性变体' : '资产生成'}任务已入队 · ${queued.job.id.slice(0, 8)}`) + } catch (error) { + await api(`/assets/${assetId}`, { method: 'PATCH', body: { status: 'DRAFT' } }).catch(() => {}) + throw error + } + } + + const copyAssetReference = async (asset) => { + if (!asset.currentVersionId) throw new Error('当前资产尚无可引用版本') + if (!navigator.clipboard?.writeText) throw new Error('当前浏览器不支持复制到剪贴板') + await navigator.clipboard.writeText(`@${asset.name} [asset:${asset.id}/version:${asset.currentVersionId}]`) + showToast(`已复制 ${asset.name} 的版本引用`) + } + + const importAsset = async ({ file, type, name, description, tags }) => { + const form = new FormData() + form.append('file', file) + const uploaded = await api(`/projects/${projectId}/uploads`, { method: 'POST', body: form }) + const created = await api(`/projects/${projectId}/assets`, { + method: 'POST', + body: { type, name, description, tags }, + }) + await api(`/assets/${created.id}/versions`, { + method: 'POST', + body: { storageKey: uploaded.key, mimeType: uploaded.contentType, byteSize: uploaded.byteSize, generationParams: { source: 'upload', filename: uploaded.filename } }, + }) + await loadProjectData(projectId) + showToast(`${name} 已作为${assetTypeLabels[type]}导入资产库`) + } + + const updateAsset = async (assetId, input, successMessage = '资产信息已保存') => { + await api(`/assets/${assetId}`, { method: 'PATCH', body: input }) + await loadProjectData(projectId) + showToast(successMessage) + } + + const saveCharacterConsistencyProfile = async (assetId, input) => { + await api(`/assets/${assetId}/consistency-profile`, { method: 'PUT', body: input }) + await loadProjectData(projectId) + showToast(input.identityLocked ? '角色身份档案已锁定' : '角色身份档案已保存') + } + + const generateScript = async (instruction) => { + requireAiWorkflow('script') + const provider = preferredWorkflowProvider(serviceReadiness, 'script', 'openai') + const queued = await api(`/projects/${projectId}/jobs`, { + method: 'POST', + body: { type: 'SCRIPT_GENERATE', episodeId, input: { instruction, includeExistingScript: true, provider } }, + }) + await loadWorkspaceData(workspaceId) + showToast(`剧本任务已入队 · ${queued.job.id.slice(0, 8)}`) + } + + const generateStoryboard = async (replaceExisting = false) => { + requireAiWorkflow('storyboard') + const provider = preferredWorkflowProvider(serviceReadiness, 'storyboard', 'openai') + const queued = await api(`/projects/${projectId}/jobs`, { + method: 'POST', + body: { + type: 'STORYBOARD_GENERATE', + episodeId, + input: { instruction: '根据当前已保存剧本生成完整、可制作的漫剧分镜', replaceExisting, provider }, + }, + }) + await loadWorkspaceData(workspaceId) + setPage('storyboard') + showToast(`智能分镜任务已入队 · ${queued.job.id.slice(0, 8)}`) + } + + const saveScript = async (plainText) => { + const saved = await api(`/episodes/${episodeId}/scripts`, { + method: 'POST', + body: { title: episode.title, content: { source: 'editor', plainText }, plainText, changeSummary: '工作台手动保存' }, + }) + await loadEpisodeData(episodeId) + showToast(`剧本 v${saved.version} 已保存`) + } + + const generateShot = async (shot, provider = 'openai') => { + requireAiWorkflow(provider === 'agnes' ? 'image-agnes' : provider === 'replicate' ? 'image-replicate' : provider === 'generic' ? 'image-generic' : 'image-openai') + const queued = await api(`/projects/${projectId}/jobs`, { + method: 'POST', + body: { type: 'ASSET_GENERATE', episodeId, input: { shotId: shot.id, prompt: shot.copy, width: 1536, height: 864, provider } }, + }) + await loadWorkspaceData(workspaceId) + showToast(`镜头 ${shot.label} 生成任务已入队 · ${queued.job.id.slice(0, 8)}`) + } + + const createShot = async () => { + const nextNumber = studioShots.reduce((largest, shot) => Math.max(largest, Number(shot.label)), 0) + 1 + await api(`/episodes/${episodeId}/shots`, { + method: 'POST', + body: { + shotNumber: nextNumber, + sceneNumber: studioShots.at(-1)?.sceneNumber ?? nextNumber, + title: `镜头 ${String(nextNumber).padStart(2, '0')}`, + description: '补充该镜头的画面描述后即可生成。', + shotType: '中景', + cameraMotion: '静止', + durationMs: 3000, + characterAssetIds: [], + sortOrder: nextNumber * 100, + }, + }) + await loadEpisodeData(episodeId) + showToast(`镜头 ${String(nextNumber).padStart(2, '0')} 已创建`) + } + + const updateShot = async (shotId, input) => { + await api(`/shots/${shotId}`, { method: 'PATCH', body: input }) + await loadEpisodeData(episodeId) + showToast('镜头属性已保存') + } + + const enqueueShotProduction = async (type, shot, options = {}) => { + requireAiWorkflow(type === 'TTS_GENERATE' ? 'tts' : type === 'VIDEO_GENERATE' ? 'video' : 'lipsync') + const provider = type === 'TTS_GENERATE' + ? 'openai' + : type === 'VIDEO_GENERATE' + ? preferredVideoProvider(serviceReadiness) + : 'replicate' + const input = type === 'TTS_GENERATE' + ? { shotId: shot.id, text: options.text || shot.subtitleText || shot.copy, voice: options.voice || 'alloy', speed: options.speed || 1, provider } + : type === 'VIDEO_GENERATE' + ? { shotId: shot.id, prompt: shot.copy, durationSeconds: shot.durationMs / 1000, provider } + : { shotId: shot.id, provider } + const queued = await api(`/projects/${projectId}/jobs`, { + method: 'POST', + body: { type, episodeId, input }, + }) + await loadWorkspaceData(workspaceId) + showToast(`${jobTypeLabels[type]}已入队 · ${queued.job.id.slice(0, 8)}`) + } + + const saveShotVersion = async (shotId, input) => { + await api(`/shots/${shotId}/versions`, { method: 'POST', body: input }) + await loadEpisodeData(episodeId) + } + + const saveShotProduction = async (shotId, input) => { + const result = await api(`/shots/${shotId}/production`, { method: 'PATCH', body: input }) + await loadEpisodeData(episodeId) + return result + } + + const importShotMedia = async (file, shot) => { + if (!file.type.startsWith('audio/') && !file.type.startsWith('video/')) throw new Error('制作中心仅支持导入音频或视频文件') + const form = new FormData() + form.append('file', file) + const uploaded = await api(`/projects/${projectId}/uploads`, { method: 'POST', body: form }) + await saveShotVersion(shot.id, { + ...(file.type.startsWith('audio/') ? { audioStorageKey: uploaded.key } : { videoStorageKey: uploaded.key }), + generationParams: { source: 'production-upload', filename: uploaded.filename, mimeType: uploaded.contentType }, + }) + showToast(`${file.name} 已绑定到镜头 ${shot.label}`) + } + + const reorderShot = async (shotId, direction) => { + const ordered = [...studioShots].sort((a, b) => a.sortOrder - b.sortOrder) + const index = ordered.findIndex((shot) => shot.id === shotId) + const target = index + direction + if (index < 0 || target < 0 || target >= ordered.length) return + ;[ordered[index], ordered[target]] = [ordered[target], ordered[index]] + await api(`/episodes/${episodeId}/shots/reorder`, { + method: 'PATCH', + body: { shots: ordered.map((shot, itemIndex) => ({ id: shot.id, sortOrder: (itemIndex + 1) * 100 })) }, + }) + await loadEpisodeData(episodeId) + showToast('镜头顺序已保存') + } + + const duplicateShot = async (shot) => { + const nextNumber = studioShots.reduce((largest, item) => Math.max(largest, Number(item.label)), 0) + 1 + const created = await api(`/episodes/${episodeId}/shots`, { + method: 'POST', + body: { + shotNumber: nextNumber, + sceneNumber: shot.sceneNumber, + title: `${shot.title} · 副本`, + description: shot.copy, + shotType: shot.type, + cameraMotion: shot.cameraMotion, + durationMs: shot.durationMs, + characterAssetIds: shot.characterAssetIds, + sceneAssetId: shot.sceneAssetId, + sortOrder: shot.sortOrder + 1, + }, + }) + if (shot.currentVersion) { + await api(`/shots/${created.id}/versions`, { + method: 'POST', + body: { + imageAssetVersionId: shot.currentVersion.imageAssetVersionId, + videoStorageKey: shot.currentVersion.videoStorageKey, + audioStorageKey: shot.currentVersion.audioStorageKey, + subtitleText: shot.subtitleText, + generationParams: { source: 'duplicate', sourceShotId: shot.id }, + }, + }) + } + await loadEpisodeData(episodeId) + showToast(`镜头 ${shot.label} 已复制`) + } + + const deleteShot = async (shot) => { + await api(`/shots/${shot.id}`, { method: 'DELETE' }) + await loadEpisodeData(episodeId) + showToast(`镜头 ${shot.label} 已删除`) + } + + const createEpisode = async () => { + const nextNumber = (project?.episodes ?? []).reduce((largest, item) => Math.max(largest, item.episodeNumber), 0) + 1 + const created = await api(`/projects/${projectId}/episodes`, { + method: 'POST', + body: { episodeNumber: nextNumber, title: `第 ${String(nextNumber).padStart(2, '0')} 集`, synopsis: '', targetDurationSeconds: 180 }, + }) + await loadProjectData(projectId) + setEpisodeId(created.id) + showToast(`第 ${String(nextNumber).padStart(2, '0')} 集已创建`) + } + + const createRender = async (settings) => { + const queued = await api(`/episodes/${episodeId}/renders`, { method: 'POST', body: { settings } }) + await refreshCurrentData() + showToast(`成片 v${queued.render.version} 已进入渲染队列`) + } + + const startProductionRun = async (settings) => { + const run = await api(`/episodes/${episodeId}/production-runs`, { method: 'POST', body: settings }) + await Promise.all([loadWorkspaceData(workspaceId), loadEpisodeData(episodeId)]) + showToast(`整集生产已启动 · ${run.totalJobs} 个任务`) + return run + } + + const cancelProductionRun = async (run) => { + await api(`/production-runs/${run.id}`, { method: 'DELETE' }) + await Promise.all([loadWorkspaceData(workspaceId), loadEpisodeData(episodeId)]) + showToast('整集生产已取消') + } + + const approveRender = async (render) => { + const review = await api(`/workspaces/${workspaceId}/reviews`, { method: 'POST', body: { targetType: 'RENDER', targetId: render.id, summary: `${episode?.title ?? '成片'} · v${render.version} 终审` } }) + await loadWorkspaceData(workspaceId) + setPage('reviews') + showToast(`成片 v${render.version} 已提交审核 · ${review.id.slice(0, 8)}`) + } + + const publishRender = async (render, options = {}) => { + await api(`/renders/${render.id}/deliveries`, { + method: 'POST', + body: { + platform: options.platform ?? 'DOWNLOAD', + ...(options.channelAccountId ? { channelAccountId: options.channelAccountId } : {}), + ...(options.destination ? { destination: options.destination } : {}), + ...(options.scheduledAt ? { scheduledAt: options.scheduledAt } : {}), + }, + }) + await refreshCurrentData() + const platformLabel = publishingPlatformLabels[options.platform ?? 'DOWNLOAD'] ?? options.platform + showToast(options.scheduledAt + ? `${platformLabel}已安排在 ${new Date(options.scheduledAt).toLocaleString('zh-CN')} 执行` + : `成片 v${render.version} 已进入${platformLabel}队列`) + } + + const connectPublishingChannel = async (platform) => { + const popup = window.open('', '_blank') + try { + const result = await api(`/workspaces/${workspaceId}/publishing/oauth/start`, { + method: 'POST', + body: { platform, returnPath: '/?publishing=connected' }, + }) + if (!popup) throw new Error('浏览器阻止了渠道授权窗口') + popup.location = result.authorizationUrl + } catch (error) { + if (popup) popup.close() + throw error + } + } + + const revokePublishingChannel = async (account) => { + await api(`/publishing/channels/${account.id}`, { method: 'DELETE' }) + await loadWorkspaceData(workspaceId) + showToast(`${publishingPlatformLabels[account.platform] ?? account.platform}账号已解除连接`) + } + + const cancelDelivery = async (delivery) => { + await api(`/deliveries/${delivery.id}`, { method: 'DELETE' }) + await refreshCurrentData() + showToast(`成片 v${delivery.render.version} 的交付已取消`) + } + + const retryDelivery = async (delivery) => { + const result = await api(`/deliveries/${delivery.id}/retry`, { method: 'POST' }) + await refreshCurrentData() + showToast(`成片 v${delivery.render.version} 已重新进入交付队列 · ${result.job.id.slice(0, 8)}`) + } + + const activateVersion = async (target, versionId) => { + const endpoint = target.kind === 'asset' + ? `/assets/${target.id}/versions/${versionId}/activate` + : target.kind === 'script' + ? `/episodes/${target.id}/scripts/${versionId}/activate` + : `/shots/${target.id}/versions/${versionId}/activate` + await api(endpoint, { method: 'POST' }) + await refreshCurrentData() + showToast('当前版本已切换') + } + + const requestVersionReview = async (target, version) => { + const targetType = target.kind === 'asset' ? 'ASSET_VERSION' : target.kind === 'script' ? 'SCRIPT_VERSION' : 'SHOT_VERSION' + const created = await api(`/workspaces/${workspaceId}/reviews`, { + method: 'POST', + body: { targetType, targetId: version.id, summary: `${target.title} · v${version.version}` }, + }) + await loadWorkspaceData(workspaceId) + showToast(`v${version.version} 已提交审核 · ${created.id.slice(0, 8)}`) + } + + const cancelJob = async (job) => { + await api(`/jobs/${job.id}`, { method: 'DELETE' }) + await loadWorkspaceData(workspaceId) + showToast(`${jobTypeLabels[job.type] ?? job.type}任务已取消`) + } + + const retryJob = async (job) => { + const result = await api(`/jobs/${job.id}/retry`, { method: 'POST' }) + await loadWorkspaceData(workspaceId) + showToast(`重试任务已入队 · ${result.job.id.slice(0, 8)}`) + } + + const startBillingCheckout = async (plan) => { + const result = await api(`/workspaces/${workspaceId}/billing/checkout`, { + method: 'POST', + body: { plan, requestId: crypto.randomUUID() }, + }) + window.location.assign(result.url) + } + + const openBillingPortal = async () => { + const result = await api(`/workspaces/${workspaceId}/billing/portal`, { method: 'POST' }) + window.location.assign(result.url) + } + + const endSession = async () => { + try { + await logout() + } finally { + setSession(null) + setWorkspaceId(null) + setProjects([]) + setProjectId(null) + setEpisodeId(null) + setInvitations([]) + setNotifications([]) + setNotificationUnreadCount(0) + setRealtimeStatus('closed') + setServiceReadiness(null) + setSecurityOpen(false) + } + } + + const pageTitle = navItems.find((item) => item.id === page)?.label || '创作总览' + + if (authLoading) return + if (!session?.user) return <> { setSession(nextSession); setWorkspaceId(nextSession.workspaces?.[0]?.id ?? null) }} />{toast && } + + const sessionWorkspaces = session.workspaces ?? [] + const workspace = sessionWorkspaces.find((item) => item.id === workspaceId) ?? sessionWorkspaces[0] + const canEditContent = ['OWNER', 'ADMIN', 'EDITOR'].includes(workspace?.role) + + return ( +
      + setMobileNav(false)} workspace={workspace} user={session.user} jobs={jobs} reviews={reviews} billing={billing} onBilling={() => setBillingOpen(true)} onSecurity={openSecurity} /> +
      + setMobileNav(true)} + onSearch={() => setCommandOpen(true)} + onToast={showToast} + project={project} + episode={episode} + user={session.user} + projects={projects} + workspaces={sessionWorkspaces} + workspace={workspace} + onSecurity={openSecurity} + projectMenuOpen={projectMenuOpen} + onProjectMenu={() => { setProjectMenuOpen((value) => !value); setNotificationOpen(false) }} + onSelectProject={(nextProjectId) => { setProjectId(nextProjectId); setProjectMenuOpen(false) }} + onSelectWorkspace={selectWorkspace} + onProjectSettings={() => { setProjectMenuOpen(false); setProjectSettingsOpen(true) }} + onEpisodeSettings={() => { setProjectMenuOpen(false); setEpisodeSettingsOpen(true) }} + canEditContent={canEditContent} + jobs={jobs} + reviews={reviews} + deliveries={deliveries} + notifications={notifications} + notificationUnreadCount={notificationUnreadCount} + realtimeStatus={realtimeStatus} + notificationOpen={notificationOpen} + onNotifications={() => { setNotificationOpen((value) => !value); setProjectMenuOpen(false) }} + onOpenNotification={openNotification} + onReadAllNotifications={readAllNotifications} + onNavigate={navigate} + /> +
      + {page === 'overview' && ( + setProjectOpen(true)} + onGenerate={() => openAssetGenerator()} + onProjectSettings={() => setProjectSettingsOpen(true)} + canEditContent={canEditContent} + /> + )} + {page === 'assets' && openAssetGenerator()} onVariant={openAssetGenerator} onCopyReference={copyAssetReference} onImport={importAsset} onUpdate={updateAsset} onSaveConsistencyProfile={saveCharacterConsistencyProfile} onToast={showToast} onOpenVersions={(asset) => setVersionTarget({ kind: 'asset', id: asset.id, title: asset.name })} />} + {page === 'script' && setEpisodeSettingsOpen(true)} canEditContent={canEditContent} onNavigate={navigate} onToast={showToast} onGenerate={generateScript} onGenerateStoryboard={generateStoryboard} onSave={saveScript} onOpenVersions={() => episode && setVersionTarget({ kind: 'script', id: episode.id, title: episode.title })} />} + {page === 'storyboard' && setVersionTarget({ kind: 'shot', id: shot.id, title: `SH_${shot.label} · ${shot.title}` })} />} + {page === 'production' && setVersionTarget({ kind: 'shot', id: shot.id, title: `SH_${shot.label} · ${shot.title}` })} />} + {page === 'jobs' && loadWorkspaceData(workspaceId)} onCancel={cancelJob} onRetry={retryJob} onToast={showToast} />} + {page === 'services' && } + {page === 'reviews' && } + {page === 'publish' && } + {page === 'team' && loadWorkspaceData(workspaceId)} onToast={showToast} />} + {page === 'audit' && ['OWNER', 'ADMIN'].includes(workspace?.role) && } + {(dataLoading || inviteAccepting) &&
      {inviteAccepting ? '正在接受工作室邀请' : '同步项目数据'}
      } +
      +
      + {generatorOpen && } + {projectOpen && setProjectOpen(false)} onCreate={createProject} />} + {commandOpen && setCommandOpen(false)} onNavigate={navigate} />} + {versionTarget && setVersionTarget(null)} onActivate={activateVersion} onRequestReview={requestVersionReview} onToast={showToast} />} + {billingOpen && billing && setBillingOpen(false)} onCheckout={startBillingCheckout} onPortal={openBillingPortal} />} + {securityOpen && setSecurityOpen(false)} onLogout={endSession} onPasswordChanged={endSession} onToast={showToast} />} + {projectSettingsOpen && project && setProjectSettingsOpen(false)} onSave={updateProjectSettings} onArchive={archiveProject} onToast={showToast} />} + {episodeSettingsOpen && episode && setEpisodeSettingsOpen(false)} onSave={updateEpisodeSettings} onToast={showToast} />} + {toast && } +
      + ) +} + +function LoadingScreen() { + return
      正在恢复工作台
      +} + +function AuthScreen({ hasInvitation, onAuthenticated }) { + const actionParams = useMemo(() => new URLSearchParams(window.location.search), []) + const verificationToken = actionParams.get('verify_email') + const resetToken = actionParams.get('reset_password') + const [mode, setMode] = useState(verificationToken ? 'verify' : resetToken ? 'reset' : 'login') + const [email, setEmail] = useState(hasInvitation ? '' : 'studio@frameflow.local') + const [password, setPassword] = useState('') + const [confirmPassword, setConfirmPassword] = useState('') + const [displayName, setDisplayName] = useState('') + const [workspaceName, setWorkspaceName] = useState('') + const [submitting, setSubmitting] = useState(false) + const [error, setError] = useState('') + const [notice, setNotice] = useState('') + const [debugUrl, setDebugUrl] = useState('') + const verificationStarted = useRef(false) + + const clearActionParams = useCallback(() => { + const url = new URL(window.location.href) + url.searchParams.delete('verify_email') + url.searchParams.delete('reset_password') + window.history.replaceState({}, '', `${url.pathname}${url.search}${url.hash}`) + }, []) + + useEffect(() => { + if (mode !== 'verify' || !verificationToken || verificationStarted.current) return + verificationStarted.current = true + setSubmitting(true) + api('/auth/verify-email/confirm', { method: 'POST', body: { token: verificationToken }, retryAuth: false }) + .then(() => { + clearActionParams() + setNotice('邮箱验证完成,现在可以登录工作台。') + setMode('notice') + }) + .catch((requestError) => setError(errorMessage(requestError))) + .finally(() => setSubmitting(false)) + }, [clearActionParams, mode, verificationToken]) + + const changeMode = (nextMode) => { + setMode(nextMode) + setError('') + setNotice('') + setDebugUrl('') + setPassword('') + setConfirmPassword('') + if (nextMode === 'register' && email === 'studio@frameflow.local') setEmail('') + } + + const submit = async (event) => { + event.preventDefault() + if (mode === 'reset' && password !== confirmPassword) { + setError('两次输入的新密码不一致') + return + } + setSubmitting(true) + setError('') + try { + if (mode === 'forgot') { + const result = await api('/auth/password/forgot', { method: 'POST', body: { email }, retryAuth: false }) + setNotice('如果该邮箱已注册,密码重置邮件已经发送。') + setDebugUrl(result.debugResetUrl ?? '') + setMode('notice') + return + } + if (mode === 'reset') { + await api('/auth/password/reset', { method: 'POST', body: { token: resetToken, newPassword: password }, retryAuth: false }) + clearActionParams() + setNotice('密码已重置,所有旧设备会话均已退出。') + setMode('notice') + return + } + const nextSession = mode === 'login' ? await login(email, password) : await register({ email, password, displayName, workspaceName }) + if (nextSession.verificationRequired) { + setNotice(nextSession.emailSent ? '验证邮件已经发送,请完成邮箱验证后登录。' : '账号已创建,请通过验证链接完成邮箱验证。') + setDebugUrl(nextSession.debugVerificationUrl ?? '') + setMode('notice') + return + } + onAuthenticated(nextSession) + } catch (requestError) { + if (requestError instanceof ApiError && requestError.code === 'EMAIL_VERIFICATION_REQUIRED') { + try { + const result = await api('/auth/verify-email/request', { method: 'POST', body: { email }, retryAuth: false }) + setNotice('邮箱尚未验证,新的验证邮件已经发送。') + setDebugUrl(result.debugVerificationUrl ?? '') + setMode('notice') + return + } catch (verificationError) { + setError(errorMessage(verificationError)) + return + } + } + setError(errorMessage(requestError)) + } finally { + setSubmitting(false) + } + } + + const brand =
      FRAMEFLOWAI 漫剧工场
      + + if (mode === 'verify') { + return ( +
      {brand}

      正在验证邮箱

      验证链接仅可使用一次,请稍候。

      {submitting &&
      正在确认验证信息
      }{error &&
      {error}
      }{error && }
      + ) + } + + if (mode === 'notice') { + return ( +
      {brand}

      操作已提交

      {notice}

      {debugUrl && 打开本地调试链接}
      + ) + } + + return ( +
      +
      + {brand} + {['login', 'register'].includes(mode) &&
      } +

      {mode === 'login' ? '登录工作台' : mode === 'register' ? '创建创作空间' : mode === 'forgot' ? '找回密码' : '设置新密码'}

      {mode === 'login' ? '继续管理剧本、资产、镜头与成片交付。' : mode === 'register' ? '建立你的工作室账号并开始第一个漫剧项目。' : mode === 'forgot' ? '输入注册邮箱,我们会发送一次性重置链接。' : '新密码设置成功后,所有旧设备会话都会退出。'}

      + {hasInvitation && ['login', 'register'].includes(mode) &&
      工作室邀请待接受请使用收到邀请的邮箱登录或创建账号,成功后将自动加入工作室。
      } + {mode === 'register' && <>} + {mode !== 'reset' && } + {mode !== 'forgot' && } + {mode === 'reset' && } + {mode === 'login' && } + {error &&
      {error}
      } + + {['forgot', 'reset'].includes(mode) && } +
      +
      + ) +} + +function Sidebar({ current, onNavigate, open, onClose, workspace, user, jobs, reviews, billing, onBilling, onSecurity }) { + const activeJobs = jobs.filter((job) => ['QUEUED', 'RUNNING'].includes(job.status)).length + const openReviews = reviews.filter((review) => review.status === 'OPEN').length + const initial = (user?.displayName || user?.email || 'F').slice(0, 1).toUpperCase() + const creditLimit = billing?.monthlyCreditLimit ?? workspace?.monthlyCreditLimit ?? 0 + const remainingCredits = billing?.remainingCredits ?? creditLimit + const availablePercent = creditLimit > 0 ? Math.max(0, Math.min(100, remainingCredits / creditLimit * 100)) : 0 + return ( + <> +
      + + + ) +} + +function Topbar({ pageTitle, onMenu, onSearch, onToast, project, episode, user, projects, workspaces, workspace, projectMenuOpen, onProjectMenu, onSelectProject, onSelectWorkspace, onProjectSettings, onEpisodeSettings, onSecurity, canEditContent, jobs, reviews, notifications: persistentNotifications, notificationUnreadCount, realtimeStatus, notificationOpen, onNotifications, onOpenNotification, onReadAllNotifications }) { + const initial = (user?.displayName || user?.email || 'F').slice(0, 1).toUpperCase() + const notifications = useMemo(() => { + const items = persistentNotifications.map((notification) => ({ + id: notification.id, + title: notification.title, + detail: notification.body, + time: notification.createdAt, + page: notification.page, + tone: notification.tone === 'ERROR' ? 'red' : notification.tone === 'SUCCESS' ? 'green' : notification.tone === 'INFO' ? 'blue' : 'orange', + icon: notification.kind.startsWith('REVIEW_') ? ClipboardCheck : notification.tone === 'ERROR' ? AlertCircle : notification.tone === 'SUCCESS' ? CheckCircle2 : Bell, + readAt: notification.readAt, + resourceId: notification.resourceId, + persistent: true, + })) + const persistedResources = new Set(items.map((item) => item.resourceId).filter(Boolean)) + jobs.filter((job) => ['FAILED', 'QUEUED', 'RUNNING'].includes(job.status) && !persistedResources.has(job.id)).forEach((job) => { + items.push({ + id: `job-${job.id}`, + title: `${jobTypeLabels[job.type] ?? job.type}${job.status === 'FAILED' ? '失败' : job.status === 'RUNNING' ? '执行中' : '排队中'}`, + detail: job.status === 'FAILED' ? job.errorMessage || '任务执行失败,可前往任务中心重试。' : `任务进度 ${job.progress ?? 0}%`, + time: job.updatedAt ?? job.createdAt, + page: 'jobs', + tone: job.status === 'FAILED' ? 'red' : 'orange', + icon: job.status === 'FAILED' ? AlertCircle : CircleDashed, + persistent: false, + }) + }) + reviews.filter((review) => review.status === 'OPEN' && !persistedResources.has(review.id)).forEach((review) => items.push({ + id: `review-${review.id}`, + title: '待处理审核', + detail: review.summary || `${reviewTargetLabels[review.targetType] ?? '版本'}等待审核`, + time: review.updatedAt ?? review.createdAt, + page: 'reviews', + tone: 'orange', + icon: ClipboardCheck, + persistent: false, + })) + return items.sort((left, right) => new Date(right.time).getTime() - new Date(left.time).getTime()).slice(0, 50) + }, [jobs, reviews, persistentNotifications]) + const liveAttentionCount = notifications.filter((item) => !item.persistent && item.tone !== 'green').length + const attentionCount = notificationUnreadCount + liveAttentionCount + return ( +
      +
      + +
      {pageTitle}
      +
      + + {projectMenuOpen &&
      + {workspaces.length > 1 && <>
      工作室
      {workspaces.map((item) => )}
      项目
      } + {projects.map((item) => )} + {projects.length === 0 &&
      当前工作室还没有项目
      } + {project &&
      } +
      } +
      +
      +
      + + +
      + + {notificationOpen &&
      通知中心{notificationUnreadCount > 0 ? `${notificationUnreadCount} 条未读` : liveAttentionCount > 0 ? `${liveAttentionCount} 项进行中` : '暂无未读通知'}
      {notificationUnreadCount > 0 && }
      {notifications.map((item) => { const Icon = item.icon; return })}{notifications.length === 0 &&
      所有任务和审核都已处理
      }
      } +
      + +
      +
      + ) +} + +function OverviewPage({ assets, project, episode, shots, jobs, reviews, renders, user, onNavigate, onNewProject, onGenerate, onProjectSettings, canEditContent }) { + const completedShots = shots.filter((shot) => shot.status === '完成').length + const activeJobs = jobs.filter((job) => ['QUEUED', 'RUNNING'].includes(job.status)).length + const openReviews = reviews.filter((review) => review.status === 'OPEN').length + const episodeNumber = episode?.episodeNumber ?? 0 + const duration = formatDuration(episode?.targetDurationSeconds ? episode.targetDurationSeconds * 1000 : 0) + const readyAssets = assets.filter((asset) => asset.hasStoredMedia).length + const versionedShots = shots.filter((shot) => shot.currentVersion).length + const productionReady = shots.filter((shot) => shot.currentVersion?.videoStorageKey || shot.videoUrl).length + const health = projectHealthSnapshot({ assets, project, episode, shots, jobs, reviews, renders }) + const previewShot = shots.find((shot) => shot.hasImageMedia && shot.img) + const previewAsset = assets.find((asset) => asset.rawType === 'SCENE' && asset.hasStoredMedia) + ?? assets.find((asset) => !['VOICE', 'MUSIC'].includes(asset.rawType) && asset.hasStoredMedia) + const previewImage = previewShot?.img ?? previewAsset?.img ?? '/assets/scene-rooftop.jpg' + const previewLabel = previewShot?.title ?? previewAsset?.name ?? '示例制作画面' + const previewIsPlaceholder = !previewShot && !previewAsset + const dynamicStages = [ + { label: '剧本', detail: episode?.currentScript ? `v${episode.currentScript.version}` : '待创建', state: episode?.currentScript ? 'done' : 'active' }, + { label: '资产', detail: `${readyAssets} / ${assets.length}`, state: assets.length === 0 ? 'next' : readyAssets === assets.length ? 'done' : 'active' }, + { label: '分镜', detail: `${versionedShots} / ${shots.length}`, state: shots.length === 0 ? 'next' : versionedShots === shots.length ? 'done' : 'active' }, + { label: '制作', detail: `${productionReady} / ${shots.length}`, state: shots.length > 0 && productionReady === shots.length ? 'done' : productionReady > 0 ? 'active' : 'next' }, + { label: '成片', detail: renders.length > 0 ? `v${renders[0].version}` : '待开始', state: renders.some((render) => render.status === 'APPROVED') ? 'done' : renders.length ? 'active' : 'next' }, + ] + const stageProgress = Math.round(dynamicStages.filter((stage) => stage.state === 'done').length / dynamicStages.length * 100) + return ( +
      +
      +
      +

      {new Intl.DateTimeFormat('zh-CN', { month: 'long', day: 'numeric', weekday: 'long' }).format(new Date())}

      +

      {user?.displayName ?? '创作者'},继续把故事变成画面。

      +

      {project && episode ? `《${project.name}》第 ${String(episodeNumber).padStart(2, '0')} 集正在制作,当前有 ${openReviews} 项待审核。` : '创建项目和分集后即可开始完整制作流程。'}

      +
      +
      + + {project && } + +
      +
      + +
      +
      + 第 {String(episodeNumber).padStart(2, '0')} 集制作进度 + {stageProgress}% +
      +
      + {dynamicStages.map((stage, index) => ( +
      +
      {stage.state === 'done' ? : index + 1}
      +
      {stage.label}{stage.detail}
      + {index < dynamicStages.length - 1 && } +
      + ))} +
      +
      + +
      +
      + onNavigate('production')} /> +
      +
      + {previewLabel} + {previewIsPlaceholder && 示例预览} +
      + EP {String(episodeNumber).padStart(2, '0')} + + {formatDuration(shots.reduce((total, shot) => total + shot.durationMs, 0))} / {duration} +
      +
      +
      +
      +
      第 {String(episodeNumber).padStart(2, '0')} 集

      {episode?.title ?? '尚未创建分集'}

      + {episode?.status ?? '未开始'} +
      +

      {episode?.synopsis || '为本集补充故事梗概后,AI 编剧将以此作为生成约束。'}

      +
      +
      预计时长{duration}
      +
      镜头数量{shots.length}
      +
      已完成{completedShots}
      +
      待审核{openReviews}
      +
      + +
      +
      +
      + + +
      + +
      + onNavigate('assets')} /> +
      + {assets.slice(0, 6).map((asset) => )} +
      +
      + +
      +
      +
      项目健康度 {health.score}{health.suggestion}
      + +
      +
      + ) +} + +function AssetsPage({ assets, workspaceRole, onGenerate, onVariant, onCopyReference, onImport, onUpdate, onSaveConsistencyProfile, onToast, onOpenVersions }) { + const [tab, setTab] = useState('全部') + const [view, setView] = useState('grid') + const [query, setQuery] = useState('') + const [selected, setSelected] = useState(null) + const [statusFilter, setStatusFilter] = useState('ACTIVE') + const [tagFilter, setTagFilter] = useState('ALL') + const [editTarget, setEditTarget] = useState(null) + const [profileTarget, setProfileTarget] = useState(null) + const [importFile, setImportFile] = useState(null) + const uploadInput = useRef(null) + const tabs = ['全部', '人物', '场景', '道具', '音色', '音乐'] + const canEdit = ['OWNER', 'ADMIN', 'EDITOR'].includes(workspaceRole) + const tags = useMemo(() => [...new Set(assets.flatMap((asset) => asset.tags))].sort((a, b) => a.localeCompare(b, 'zh-CN')), [assets]) + const normalizedQuery = query.trim().toLocaleLowerCase('zh-CN') + const matchesCommonFilters = (asset) => { + const matchesStatus = statusFilter === 'ALL' + || statusFilter === 'ACTIVE' && asset.rawStatus !== 'ARCHIVED' + || asset.rawStatus === statusFilter + const matchesTag = tagFilter === 'ALL' || asset.tags.includes(tagFilter) + const searchable = `${asset.name} ${asset.description} ${asset.tags.join(' ')}`.toLocaleLowerCase('zh-CN') + return matchesStatus && matchesTag && (!normalizedQuery || searchable.includes(normalizedQuery)) + } + const filtered = assets.filter((asset) => matchesCommonFilters(asset) && (tab === '全部' || asset.type === tab)) + const selectedAsset = assets.find((asset) => asset.id === selected) + const activeFilterCount = (statusFilter !== 'ACTIVE' ? 1 : 0) + (tagFilter !== 'ALL' ? 1 : 0) + + useEffect(() => { + if (selected && !filtered.some((asset) => asset.id === selected)) setSelected(null) + }, [filtered, selected]) + + const archiveAsset = async (asset) => { + const restoring = asset.rawStatus === 'ARCHIVED' + if (!restoring && !window.confirm(`确认归档资产「${asset.name}」?历史版本会保留。`)) return + try { + await onUpdate(asset.id, { status: restoring ? 'DRAFT' : 'ARCHIVED' }, restoring ? '资产已恢复为草稿' : '资产已归档') + setSelected(null) + setEditTarget(null) + } catch (error) { + onToast(errorMessage(error)) + } + } + + return ( +
      + { const file = event.target.files?.[0]; if (file) setImportFile(file); event.target.value = '' }} />} + /> +
      +
      + {tabs.map((item) => )} +
      +
      + +
      {activeFilterCount > 0 && }
      +
      +
      +
      + + {filtered.length ? ( +
      + {filtered.map((asset) => setSelected(selected === asset.id ? null : asset.id)} onMore={canEdit ? () => setEditTarget(asset) : null} />)} +
      + ) : ( +

      没有找到匹配资产

      {statusFilter === 'ARCHIVED' ? '归档区目前为空。' : '调整搜索或筛选条件,或创建一项新资产。'}

      {statusFilter === 'ARCHIVED' ? : }
      + )} + + {selected && ( +
      + 已选择 1 项资产 +
      {selectedAsset?.rawType === 'CHARACTER' && }
      +
      + )} + {importFile && setImportFile(null)} onImport={onImport} onToast={onToast} />} + {editTarget && setEditTarget(null)} onSave={onUpdate} onArchive={archiveAsset} onToast={onToast} />} + {profileTarget && setProfileTarget(null)} onSave={onSaveConsistencyProfile} onToast={onToast} />} +
      + ) +} + +function ScriptPage({ project, episodes, episode, onSelectEpisode, onAddEpisode, onEditEpisode, canEditContent, onNavigate, onToast, onGenerate, onGenerateStoryboard, onSave, onOpenVersions }) { + const [assistantOpen, setAssistantOpen] = useState(true) + const [saving, setSaving] = useState(false) + const [assistantBusy, setAssistantBusy] = useState(false) + const [assistantPrompt, setAssistantPrompt] = useState('') + const [scriptText, setScriptText] = useState('') + const [history, setHistory] = useState({ entries: [''], index: 0 }) + const editorRef = useRef(null) + + useEffect(() => { + const nextText = episode?.currentScript?.plainText ?? '' + setScriptText(nextText) + setHistory({ entries: [nextText], index: 0 }) + }, [episode?.id, episode?.currentScript?.id]) + + const savedText = episode?.currentScript?.plainText ?? '' + const dirty = scriptText !== savedText + const canUndo = history.index > 0 + const canRedo = history.index < history.entries.length - 1 + const analysis = useMemo(() => { + const lines = scriptText.split('\n').map((line) => line.trim()).filter(Boolean) + const characters = scriptText.replace(/\s/g, '').length + const sceneCount = lines.filter((line) => /^(第?\s*\d+\s*场|场景|内景|外景|int\.|ext\.)/i.test(line)).length + const dialogueCount = lines.filter((line) => /^[^::\n]{1,16}[::]/.test(line)).length + const actionCount = lines.filter((line) => /【[^】]+】|([^)]+)/.test(line)).length + const targetCharacters = Math.max(400, (episode?.targetDurationSeconds ?? 180) * 4) + const lengthRatio = characters / targetCharacters + const score = characters === 0 ? 0 : Math.min(100, + Math.round(Math.min(45, lengthRatio * 45) + + Math.min(25, sceneCount * 5) + + Math.min(15, dialogueCount * 1.5) + + Math.min(15, actionCount * 2))) + let suggestion = { + tag: '一致性建议', + text: `当前包含 ${sceneCount} 个场景、${dialogueCount} 段对白和 ${actionCount} 处动作提示,可继续检查人物动机与称谓。`, + instruction: '检查并修复角色动机、称谓、场景时间和行为的一致性,不改变核心情节', + } + if (characters === 0) { + suggestion = { tag: '起稿建议', text: '当前分集还没有正文,可先根据梗概生成分场剧本。', instruction: '根据本集梗概生成包含场景、动作与对白的完整分场剧本' } + } else if (sceneCount < 2) { + suggestion = { tag: '结构建议', text: '场景标记较少,建议明确拆分内外景、时间和地点,方便后续自动分镜。', instruction: '将当前剧本整理为清晰的分场结构,为每场补充内外景、时间和地点标记' } + } else if (dialogueCount === 0) { + suggestion = { tag: '对白建议', text: '尚未识别到“角色:对白”结构,建议补充可直接用于配音的对白。', instruction: '为主要场景补充角色对白,并统一使用“角色:对白”格式' } + } else if (lengthRatio < 0.65) { + suggestion = { tag: '篇幅建议', text: `当前约 ${characters} 字,低于本集目标时长对应篇幅,可补充关键行动与转折。`, instruction: '在不注水的前提下补充关键行动、情绪递进和场景转折,使篇幅匹配目标时长' } + } else if (lengthRatio > 1.35) { + suggestion = { tag: '节奏建议', text: `当前约 ${characters} 字,超过目标时长对应篇幅,建议压缩重复信息与冗余对白。`, instruction: '压缩重复信息和冗余对白,保留核心冲突,使剧本匹配目标时长' } + } else if (actionCount < Math.max(1, Math.floor(sceneCount / 2))) { + suggestion = { tag: '画面建议', text: '动作与环境提示偏少,建议增加可直接转化为镜头的视觉行动。', instruction: '为对白密集场景补充简洁的动作和环境变化,增强可视化表达' } + } + return { score, characters, sceneCount, dialogueCount, actionCount, suggestion } + }, [scriptText, episode?.targetDurationSeconds]) + + const updateScriptText = (nextText) => { + setScriptText(nextText) + setHistory((current) => { + if (current.entries[current.index] === nextText) return current + let entries = [...current.entries.slice(0, current.index + 1), nextText] + if (entries.length > 100) entries = entries.slice(entries.length - 100) + return { entries, index: entries.length - 1 } + }) + } + + const moveHistory = (direction) => { + const nextIndex = Math.max(0, Math.min(history.entries.length - 1, history.index + direction)) + if (nextIndex === history.index) return + setHistory((current) => ({ ...current, index: nextIndex })) + setScriptText(history.entries[nextIndex]) + window.requestAnimationFrame(() => editorRef.current?.focus()) + } + + const formatSelection = (prefix, suffix, placeholder) => { + const editor = editorRef.current + if (!editor) return + const start = editor.selectionStart + const end = editor.selectionEnd + const selectedText = scriptText.slice(start, end) || placeholder + const replacement = `${prefix}${selectedText}${suffix}` + updateScriptText(`${scriptText.slice(0, start)}${replacement}${scriptText.slice(end)}`) + window.requestAnimationFrame(() => { + editor.focus() + editor.setSelectionRange(start + prefix.length, start + prefix.length + selectedText.length) + }) + } + + const insertScriptBlock = (prefix, placeholder) => { + const editor = editorRef.current + if (!editor) return + const start = editor.selectionStart + const end = editor.selectionEnd + const selectedText = scriptText.slice(start, end) || placeholder + const leadingBreak = start > 0 && scriptText[start - 1] !== '\n' ? '\n' : '' + const trailingBreak = end < scriptText.length && scriptText[end] !== '\n' ? '\n' : '' + const replacement = `${leadingBreak}${prefix}${selectedText}${trailingBreak}` + updateScriptText(`${scriptText.slice(0, start)}${replacement}${scriptText.slice(end)}`) + const selectionStart = start + leadingBreak.length + prefix.length + window.requestAnimationFrame(() => { + editor.focus() + editor.setSelectionRange(selectionStart, selectionStart + selectedText.length) + }) + } + + const runAiAction = async (instruction, message) => { + if (!instruction.trim() || assistantBusy) return false + setAssistantBusy(true) + try { + if (dirty) await onSave(scriptText) + await onGenerate(instruction) + onToast(message) + return true + } catch (error) { + onToast(errorMessage(error)) + return false + } finally { + setAssistantBusy(false) + } + } + + const submitAssistant = async (event) => { + event?.preventDefault() + const instruction = assistantPrompt.trim() + if (!instruction) return + if (await runAiAction(instruction, '自定义剧本修改任务已提交')) setAssistantPrompt('') + } + + const saveCurrent = async () => { + if (!dirty || saving) return + setSaving(true) + try { + await onSave(scriptText) + } catch (error) { + onToast(errorMessage(error)) + } finally { + setSaving(false) + } + } + + const onEditorKeyDown = (event) => { + if (!(event.metaKey || event.ctrlKey)) return + const key = event.key.toLowerCase() + if (key === 's') { + event.preventDefault() + saveCurrent() + } else if (key === 'z') { + event.preventDefault() + moveHistory(event.shiftKey ? 1 : -1) + } else if (key === 'y') { + event.preventDefault() + moveHistory(1) + } else if (key === 'b') { + event.preventDefault() + formatSelection('**', '**', '重点文本') + } else if (key === 'i') { + event.preventDefault() + formatSelection('*', '*', '强调文本') + } + } + + const createStoryboard = async () => { + const hasShots = (episode?.shots?.length ?? 0) > 0 + if (hasShots && !window.confirm('当前分集已有分镜。仅草稿分镜可以被重新生成,确认继续吗?')) return + setSaving(true) + try { + if (scriptText !== (episode?.currentScript?.plainText ?? '')) await onSave(scriptText) + await onGenerateStoryboard(hasShots) + } catch (error) { + onToast(errorMessage(error)) + } finally { + setSaving(false) + } + } + + return ( +
      + } /> +
      + + +
      +
      +
      +
      {saving ? <>处理中 : dirty ? <>有未保存修改 : <>已保存 · v{episode?.currentScript?.version ?? 0}}
      +
      +
      +
      {project?.name ?? '未选择项目'}EP.{String(episode?.episodeNumber ?? 0).padStart(2, '0')}约 {formatDuration((episode?.targetDurationSeconds ?? 0) * 1000)}
      +

      {episode?.title ?? '尚未创建分集'}

      +

      ${action}

      1CG1i6P{w3DZ|Xbq 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