Files
soroush.asadi 62ea110605
CI/CD / CI · Web (tsc) (push) Successful in 1m33s
CI/CD / Deploy · full stack (push) Failing after 20s
feat(payment): admin-editable ZarinPal settings + in-panel test payment
Lets the broker's ZarinPal merchant / sandbox / amount-unit be set from
Admin → درگاه پرداخت (persisted in payment.settings) instead of env +
redeploy, and adds a per-app "test payment" button that mints a real
ZarinPal StartPay link straight from the panel — no site wiring needed.

- migration 33_payment_settings.sql: singleton payment.settings + a
  transactions.is_test column. (33, not 32 — 32 is content_render_engine.)
- broker read-path precedence: per-client override > DB settings > env.
- POST /v1/admin/clients/:id/test-payment + GET/PUT /v1/admin/settings.
- admin UI: «تنظیمات زرین‌پال» tab + «پرداخت آزمایشی» button.

Adversarial-review fixes (2 confirmed HIGH):
- do NOT pre-seed the settings row — a seeded sandbox=TRUE default would
  override a production ZARINPAL_SANDBOX=false env and silently route real
  payments to sandbox.zarinpal.com until an admin untouched the toggle.
  No row → env governs until an admin saves.
- test transactions are tagged is_test and the webhook dispatcher skips
  them, so an admin smoke-test can never notify (or credit) a real client,
  regardless of metadata. Broker-authoritative, not consumer-dependent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 00:47:10 +03:30
..

FlatRender V2 — Database Schemas

PostgreSQL 15+. Single database, one schema per microservice.

Run order

Apply migrations in numerical order:

psql -d flatrender -f migrations/00_setup.sql
psql -d flatrender -f migrations/01_identity_tenants.sql
psql -d flatrender -f migrations/02_identity_users.sql
psql -d flatrender -f migrations/03_identity_billing.sql
psql -d flatrender -f migrations/04_identity_gamification.sql
psql -d flatrender -f migrations/05_content_taxonomy.sql
psql -d flatrender -f migrations/06_content_projects.sql
psql -d flatrender -f migrations/07_content_scenes.sql
psql -d flatrender -f migrations/08_content_characters_presets.sql
psql -d flatrender -f migrations/09_content_cms.sql
psql -d flatrender -f migrations/10_studio_saved_projects.sql
psql -d flatrender -f migrations/11_render_nodes.sql
psql -d flatrender -f migrations/12_render_jobs.sql
psql -d flatrender -f migrations/13_file_manager.sql
psql -d flatrender -f migrations/14_notification.sql

Schemas

Schema Owner Service Purpose
identity Identity Service (.NET) tenants, users, auth, plans, payments, gamification
content Content Service (.NET) templates, scenes, presets, blogs, CMS
studio Studio Service (.NET) user's saved projects + audio (music/voiceover/sfx)
render Render Orchestrator (Go) jobs, nodes, frame jobs, snapshots, exports
file_mgr File Service (Go) user files, folders, quotas, cleanup
notification Notification Service (Go) in-app, push, email, SMS, telegram

Cross-schema design

Schemas are loosely coupled. Where it matters for integrity (within a service), FKs are used. Across services, FKs are deliberately omitted so services can evolve independently — referential integrity is enforced via service code and events.

Hard FKs across schemas (intentional)

  • identity.earned_gifts.notification_idnotification.notifications.id

Everything else uses soft references (column documented but no FK).

Multi-tenancy

identity.tenants is the root of multi-tenancy. The default FlatRender tenant has UUID 00000000-0000-0000-0000-000000000001.

Every user, project, render job, file, and notification carries a tenant_id. Resellers (B2B API customers) are tenants. White-label branding, API keys, webhooks, and usage metering all hang off identity.tenants.*.

New features (vs V1)

  • Multi-tenancy / Reseller API: identity.tenants, tenant_branding, tenant_api_keys, tenant_webhooks, tenant_usage_daily
  • Voiceover support: studio.saved_projects.voiceover_*, render.render_jobs.has_voiceover
  • Per-track volume: music_volume, sfx_volume, voiceover_volume
  • Scene snapshots: render.snapshots with cache key
  • AE crash tracking: render.node_crashes + auto-recovery
  • Frame repair jobs: render.frame_repair_jobs
  • AEP local cache on nodes: render.node_template_cache (LRU)
  • SVG color previews: content.template_svg_previews (drop image → traced SVG)
  • PWA push subscriptions: identity.push_subscriptions
  • MFA: identity.mfa_factors
  • Multipart uploads: file_mgr.upload_sessions
  • Cleanup scheduler: file_mgr.cleanup_schedules
  • Per-user / per-channel notification preferences: notification.notification_preferences

Partitioning

Time-series tables are partitioned monthly (initial partition for 2026-01 created; ops creates new ones via cron):

  • identity.tenant_api_request_logs
  • render.node_health_logs

Service user grants

Each microservice connects with its own DB role limited to its schema. See top of 00_setup.sql for the recipe.