Commit Graph

11 Commits

Author SHA1 Message Date
soroush.asadi 6661f53734 fix(scan): Fix-mode scanner + dialog suppression + cancel/timer + importer revive
Build backend images / build content-svc (push) Failing after 1m25s
Build backend images / build file-svc (push) Failing after 1m10s
Build backend images / build gateway (push) Failing after 56s
Build backend images / build identity-svc (push) Failing after 53s
Build backend images / build notification-svc (push) Failing after 57s
Build backend images / build render-svc (push) Failing after 48s
Build backend images / build studio-svc (push) Failing after 1m5s
- scan.jsx: app.beginSuppressDialogs() + clean quit (no AE hang on font/footage
  dialogs); FIX-mode branch parses frl_c(x)t/m(y) layer names → scenes by c(x);
  flexible/mockup keep comp-based walk; FR_SCAN_MODE selects.
- render-svc: scan job carries project mode; cancel endpoint + node watchdog that
  kills AE on cancel; parseObjectURL handles minio:// (bucket in host); scan with
  no template fails cleanly; status guards so late results can't un-cancel.
- content importer: revive soft-deleted scenes instead of duplicate-inserting
  (fixes scenes_project_id_key unique violation); orphan diff ignores deleted.
- admin: scan dialog gets project-type picker + elapsed timer + Cancel button.
- node-agent: AE-2026 wiring (host port 5010, host-reachable presign endpoint),
  FR_SCAN_MODE plumbing. docs/aep-template-convention.md: per-type naming + bundles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 19:06:08 +03:30
soroush.asadi 1ff6e494c0 @
Build backend images / build content-svc (push) Failing after 19s
Build backend images / build file-svc (push) Failing after 1m53s
Build backend images / build gateway (push) Failing after 16s
Build backend images / build identity-svc (push) Failing after 7m1s
Build backend images / build notification-svc (push) Failing after 7m24s
Build backend images / build render-svc (push) Failing after 3m12s
Build backend images / build studio-svc (push) Failing after 43s
feat: AE template scanner + scene editor + AEP bundle pipeline

Scene editor (admin): per-project Scenes / Shared Colors / Color Presets
manager (ProjectScenes) reachable from each project.

AEP bundle pipeline: upload .aep or .zip → stored once per template at
templates/{project_id}/(bundle.zip|template.aep); render claim probes and
returns is_bundle+md5; node-agent extracts the bundle, locates the .aep
(zip-slip guarded), and caches by md5 so repeated renders extract once.

AE template scanner ("read scenes/colours/configs from the AEP"):
- content-svc importer: POST /v1/projects/{id}/scan/{preview,apply} —
  review-diff-then-merge into scenes/elements/colours (manual edits kept).
- render-svc Go quick-scan: stdlib RIFX parser extracts comp names+durations
  (no AE) → POST /v1/template-scans/{id}/quick.
- render-svc AE scan jobs + node-agent runner: queue → node runs scan.jsx
  (reverse of legacy JSXGenerator conventions: frfinal/frshare/frl_/frd_) →
  posts ScanResult back. Migration 26_render_scan_jobs.
- admin UI: "اسکن از افترافکت" with quick/full engines + diff-review modal.

Verified: importer preview/apply, Go quick-scan end-to-end (synthetic .aep →
scene imported), bundle extract unit tests, RIFX parser unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-06-04 10:39:45 +03:30
soroush.asadi 7f2f65dd8a feat(render+node-agent+admin): install fonts on all render nodes + verify
Build backend images / build content-svc (push) Failing after 53s
Build backend images / build file-svc (push) Failing after 47s
Build backend images / build gateway (push) Failing after 52s
Build backend images / build identity-svc (push) Failing after 58s
Build backend images / build notification-svc (push) Failing after 55s
Build backend images / build render-svc (push) Failing after 59s
Build backend images / build studio-svc (push) Failing after 48s
Push a font once → every node installs it → admin sees per-node status.

- render-svc: font_requests + node_fonts tables (mig 25); admin GET/POST/DELETE
  /v1/node-fonts (with per-node status matrix); internal (HMAC) GET pending +
  POST status for node-agents
- node-agent: fontSyncLoop polls pending fonts every 60s, downloads, installs
  (Windows Fonts dir + registry / macOS / linux fc-cache), reports Installed/Failed
- gateway: /v1/node-fonts/* → render
- admin /admin/node-fonts: upload a .ttf/.otf → install on all nodes; per-node
  Installed/Pending/Failed badges + counts + delete

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 06:33:48 +03:30
soroush.asadi 1f52f53cf7 feat(render+identity): daily render-limit — consume on submit, refund on admin-stop
Build backend images / build content-svc (push) Failing after 51s
Build backend images / build file-svc (push) Failing after 53s
Build backend images / build gateway (push) Failing after 1m1s
Build backend images / build identity-svc (push) Failing after 48s
Build backend images / build notification-svc (push) Failing after 42s
Build backend images / build render-svc (push) Failing after 47s
Build backend images / build studio-svc (push) Failing after 1m13s
Business rule: each user has a daily render limit. Admin-stop refunds the used
charge (not the user's fault); a user's own cancel does not.

- identity: ConsumeRenderChargeAsync / RefundRenderChargeAsync on DailyRemainRenderCount
  with lazy daily reset (mig 24: daily_renders_reset_at). Convention: max=0 ⇒ UNLIMITED,
  so existing 0/0 users keep rendering until an admin sets a real limit.
- identity InternalController (service-token): POST /v1/internal/render-charge/{consume,refund}
- render-svc: identityclient + on Create consume (block 429 when limit reached, fail-open
  on identity outage); on admin Stop refund the job owner; user /cancel unchanged
- compose: IDENTITY_URL for render-svc, ServiceToken for identity-svc

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 02:18:00 +03:30
soroush.asadi 7fe5f8a563 feat(admin): standalone Projects page + per-project asset manager
Build backend images / build content-svc (push) Failing after 1m36s
Build backend images / build file-svc (push) Failing after 1m28s
Build backend images / build gateway (push) Failing after 2m11s
Build backend images / build identity-svc (push) Failing after 2m11s
Build backend images / build notification-svc (push) Failing after 3m46s
Build backend images / build render-svc (push) Failing after 55s
Build backend images / build studio-svc (push) Failing after 1m2s
- content-svc: GET /v1/projects (browse/search all projects across containers,
  paginated, admin) returning template name/slug + AE status; project_assets
  table (mig 23) + entity; GET/POST/DELETE /v1/projects/{id}/assets
- /admin/projects: searchable, paginated list of every renderable project with
  thumbnail, template, aspect/resolution, AE-file + publish status
- ProjectAssets component: list/upload/delete named footage/image/audio/font
  files per project (reused in the projects page; AE file upload alongside)
- nav + fa/en "Projects" label

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:39:33 +03:30
soroush.asadi 675b60d858 feat(auth+admin): Sign in with Google (OAuth) + Integrations config panel
Build backend images / build content-svc (push) Failing after 1m2s
Build backend images / build file-svc (push) Failing after 3m11s
Build backend images / build gateway (push) Failing after 5m39s
Build backend images / build identity-svc (push) Failing after 38s
Build backend images / build notification-svc (push) Failing after 2m0s
Build backend images / build render-svc (push) Failing after 58s
Build backend images / build studio-svc (push) Failing after 58s
Backend (identity-svc):
- oauth_config table (mig 22) + OAuthConfig entity
- OAuthService: admin config CRUD + Google authorization-code flow (build consent
  URL, exchange code, fetch userinfo, find/create RegisterMode.Google user, issue
  session via AuthService.IssueOAuthSessionAsync)
- AuthController: GET /v1/auth/google/{start,callback} (public); tokens handed to
  frontend via URL fragment
- AdminController: GET/PUT /v1/admin/oauth/{provider} (admin, secret masked)

Frontend:
- "ورود با گوگل" button on /auth → identity start endpoint
- /auth/callback reads fragment tokens → /api/auth/oauth-session sets httpOnly cookies
- /admin/integrations: Google client_id/secret/redirect_uri + enable, with setup guide
- nav + fa/en labels

Client ID/Secret are configured entirely in the admin panel — no redeploy needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:08:21 +03:30
soroush.asadi 62a5121ffe feat(identity+admin): CRM analytics + customer notes + user power-actions
Build backend images / build content-svc (push) Failing after 56s
Build backend images / build file-svc (push) Failing after 54s
Build backend images / build gateway (push) Failing after 1m1s
Build backend images / build identity-svc (push) Failing after 55s
Build backend images / build notification-svc (push) Failing after 54s
Build backend images / build render-svc (push) Failing after 52s
Build backend images / build studio-svc (push) Failing after 1m2s
Modeled on the legacy DivineGateWeb admin (CRM + Security/* actions):
- identity-svc AdminService + AdminController (admin-gated):
  - GET /v1/admin/crm/analytics — signups/buyers/conversion/revenue + daily series
    (from identity.users + identity.payments)
  - GET/PUT /v1/users/{id}/crm — tags / note / pipeline status (user_crm table, mig 20)
  - power-actions: POST /v1/users/{id}/{balance,password,charge,moderator,grant-plan}
- admin UI: /admin/crm dashboard (funnel cards + daily signup/revenue bars);
  per-user "مدیریت" modal in Users (balance, render charge, plan days, password,
  moderator, CRM notes)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:59:07 +03:30
soroush.asadi 6dbb14d146 feat(notifications+admin): marketing campaigns
Build backend images / build content-svc (push) Failing after 14s
Build backend images / build file-svc (push) Failing after 22s
Build backend images / build gateway (push) Failing after 1m21s
Build backend images / build identity-svc (push) Failing after 1m43s
Build backend images / build notification-svc (push) Failing after 1m6s
Build backend images / build render-svc (push) Failing after 53s
Build backend images / build studio-svc (push) Failing after 1m5s
- campaigns table (migration 19) + CRUD + send endpoint in notification-svc
- audience resolution reads cross-schema from identity.users (all / verified /
  with_plan); send dispatches via the SMS or Email channel and logs deliveries
- endpoints: GET/POST /v1/campaigns, POST /v1/campaigns/:id/send, DELETE
- gateway route /v1/campaigns/* → notification
- /admin/marketing: create campaign (channel, audience, template/subject/body),
  list with status + sent counts, send, delete

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 18:17:19 +03:30
soroush.asadi 507ac7e6a4 feat(notifications+admin): SMS (Kavenegar) + Email (SMTP) channels & templates
Build backend images / build content-svc (push) Failing after 56s
Build backend images / build file-svc (push) Failing after 47s
Build backend images / build gateway (push) Failing after 1m0s
Build backend images / build identity-svc (push) Failing after 56s
Build backend images / build notification-svc (push) Failing after 11s
Build backend images / build render-svc (push) Failing after 4m5s
Build backend images / build studio-svc (push) Failing after 56s
Backend (notification-svc):
- channel_config table (per-tenant Kavenegar + SMTP settings) + migration 18
- sender pkg: Kavenegar SMS client + SMTP mailer (STARTTLS / implicit TLS), stdlib only
- endpoints: GET/PUT /v1/channels[/:channel], POST /v1/sms/send, POST /v1/email/send
  (template + {{var}} rendering); deliveries logged
- seeded 3 Persian email templates: welcome / account_verification / promotion
- gateway routes /v1/{channels,sms,email}/* → notification

Admin UI:
- /admin/messaging: SMS + Email provider config cards, test-send, email template editor
- nav link + fa/en labels

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:32:54 +03:30
soroush.asadi 3fc7bf2b97 feat: AI SEO generator, full admin panel, i18n sweep, new logo + auth/RTL fixes
Build backend images / build content-svc (push) Failing after 3m39s
Build backend images / build file-svc (push) Failing after 52s
Build backend images / build gateway (push) Failing after 58s
Build backend images / build identity-svc (push) Failing after 1m21s
Build backend images / build notification-svc (push) Failing after 1m0s
Build backend images / build render-svc (push) Failing after 58s
Build backend images / build studio-svc (push) Failing after 55s
AI SEO content generator
- content-svc: per-tenant OpenAI config (ai_settings) + /v1/ai endpoints
  (settings GET/PUT, seo-post) with SEO-expert prompt → structured article
- admin UI to configure token/base-url/model and generate + save as blog
- configurable base URL for restricted networks

Full data-driven admin panel
- generic /api/admin/resource proxy + reusable AdminResource component
- categories/tags/fonts/blogs (CRUD), users (list + ban), plans/slides
- AI content section; nav + i18n

i18n localization sweep
- localized 116 user-facing + studio/editor components to next-intl (fa+en)
  under the auto.* namespace; merge tooling in scripts/merge-i18n.js

Branding + assets
- Monoline F logo (LogoMark + favicon)
- offline SVG placeholder generator (/api/placeholder), dropped picsum.photos

Fixes
- JWT issuer mismatch on content/studio (flatrender → flatrender-identity)
- missing role claim → [Authorize(Roles="Admin")] now works (RBAC)
- Secure cookies broke HTTP sessions → gated behind AUTH_COOKIE_SECURE
- Radix RTL via DirectionProvider (right-aligned menus in fa)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 09:35:14 +03:30
soroush.asadi 90ac0b81d1 feat: V2 microservices stack — backend services, gateway, JWT auth
Add full V2 architecture: identity, content, studio (.NET 10) and file,
render, notification, gateway (Go) services with vendored deps, plus DB
migrations, event/API contracts, and an init-db script.

Wire the Next.js frontend to the gateway: server-side JWT auth routes
(login/register/refresh/logout/me), gateway fetch helper, and session/
cookie/jwt helpers under src/lib.

Containerize the stack via docker-compose.v2.yml and per-service
Dockerfiles. Base images resolve through a Nexus mirror (Docker Hub) and
MCR directly; npm/NuGet pull from Nexus groups. Self-host fonts via
next/font/local to avoid Google Fonts (geo-blocked).

Add CI workflow and ignore .env.v2, *.stackdump, and .NET bin/obj.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:29:31 +03:30