f8ea9af3b67bd98ee16843f23f138fbf2e5cfcef
83 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0a7dd9b84c |
feat(nodes): live CPU/RAM/disk monitoring in the node list
Build backend images / build content-svc (push) Failing after 45s
Build backend images / build file-svc (push) Failing after 55s
Build backend images / build gateway (push) Failing after 53s
Build backend images / build identity-svc (push) Failing after 54s
Build backend images / build notification-svc (push) Failing after 53s
Build backend images / build render-svc (push) Failing after 47s
Build backend images / build studio-svc (push) Failing after 51s
- node-agent: internal/metrics — read CPU% (GetSystemTimes), RAM (GlobalMemoryStatusEx), disk used%/total (GetDiskFreeSpaceEx) via stdlib kernel32 (no external dep; windows build + non-windows stub). Heartbeat now reports cpu_pct/ram_available_mb/disk_used_pct/ disk_total_gb + ae_running. - render-svc: heartbeat persists last_disk_pct + disk_total_gb (migration 29); RenderNode model + node SELECT/scan carry them. - admin: rewrite NodesTable to the real RenderNode shape (fixes a pre-existing items/V2Node mismatch that left the list empty) + a CPU/RAM/disk bars column + stale-heartbeat flag. - assets-bundle ingestion: ProjectMediaBundle (jszip) auto-maps project.zip → project/scene image/demo/colour + music; PatchProject gains image/full_demo/shared_colors_svg. - scan: RGBA (4-number) colours recognised + frshare single-int controls detected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
ee670552a8 |
feat: cross-aspect project duplication + AEP convention/rule-engine spec
Build backend images / build content-svc (push) Failing after 1s
Build backend images / build file-svc (push) Failing after 0s
Build backend images / build gateway (push) Failing after 0s
Build backend images / build identity-svc (push) Failing after 0s
Build backend images / build notification-svc (push) Failing after 1s
Build backend images / build render-svc (push) Failing after 2s
Build backend images / build studio-svc (push) Failing after 0s
- content-svc: DuplicateProjectAsync clones full scene/element/colour graph
(identical keys, new dimensions/aspect; AEP intentionally not copied;
starts unpublished) + POST /v1/projects/{id}/duplicate.
- admin: «تکثیر» button + modal on each project row; aspects reduced to
supported 16:9/1:1/9:16; free fps default 21 (clamped 1-60).
- docs/aep-template-convention.md: versioned (v1/v2) convention + rule-engine
spec — modes, scene types, flatrender assembly, duration/fade model,
fit-box, input types, expression-driven data flow, output spec.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
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>
@
|
||
|
|
ebf0e11f22 |
fix(render+admin): render queue shows ALL users' jobs
Build backend images / build content-svc (push) Failing after 53s
Build backend images / build file-svc (push) Failing after 55s
Build backend images / build gateway (push) Failing after 58s
Build backend images / build identity-svc (push) Failing after 1m0s
Build backend images / build notification-svc (push) Failing after 49s
Build backend images / build render-svc (push) Failing after 56s
Build backend images / build studio-svc (push) Failing after 59s
The admin render queue called the user-scoped /v1/renders (so it only showed the admin's own jobs) and parsed items/total instead of data/meta (→ always empty). - render-svc: GET /v1/admin-renders (admin) → ListAllJobs across users, optional ?status= filter; gateway-wired - admin renders page now fetches /v1/admin-renders and reads data/meta correctly Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
928956689b |
feat(render+admin): exports management (all users' rendered videos)
Build backend images / build content-svc (push) Failing after 54s
Build backend images / build file-svc (push) Failing after 55s
Build backend images / build gateway (push) Failing after 52s
Build backend images / build identity-svc (push) Failing after 55s
Build backend images / build notification-svc (push) Failing after 58s
Build backend images / build render-svc (push) Failing after 48s
Build backend images / build studio-svc (push) Failing after 1m0s
- render-svc: admin-scoped store (ListAllExports / GetExportByIDAny / SoftDeleteExportAny) + GET/DELETE/download-url under /v1/admin-exports (admin-gated; separate prefix so it routes to render, not identity's /admin) - gateway: /v1/admin-exports/* → render - admin /admin/exports: paginated table of every rendered export with thumbnail, type/quality, size, duration, dimensions, produce + expiry dates; download (presigned URL) and delete Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
ca0c05db10 |
fix(identity): internal render-charge request binding (record → class)
Build backend images / build content-svc (push) Failing after 1m0s
Build backend images / build file-svc (push) Failing after 47s
Build backend images / build gateway (push) Failing after 57s
Build backend images / build identity-svc (push) Failing after 1m2s
Build backend images / build notification-svc (push) Failing after 1m0s
Build backend images / build render-svc (push) Failing after 1m1s
Build backend images / build studio-svc (push) Failing after 58s
The nested positional record ChargeReq(Guid UserId) failed System.Text.Json binding under the snake_case policy (400). Use a plain class with a settable property. Verified: consume decrements + blocks at 0, refund restores, bad service token → 401. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
7f7feabb85 |
feat(render+admin): stop a render job (admin, any owner)
Build backend images / build content-svc (push) Failing after 1m0s
Build backend images / build file-svc (push) Failing after 1m3s
Build backend images / build gateway (push) Failing after 1m2s
Build backend images / build identity-svc (push) Failing after 1m20s
Build backend images / build notification-svc (push) Failing after 1m13s
Build backend images / build render-svc (push) Failing after 1m5s
Build backend images / build studio-svc (push) Failing after 1m0s
The render-queue cancel button used the owner-scoped /cancel (WHERE user_id=…),
so an admin couldn't stop another user's job. Added:
- render-svc: POST /v1/renders/:job_id/stop (admin-gated) → store.StopJob cancels
any in-progress job regardless of owner and frees the assigned node
- admin: render-queue button now "توقف" → /api/admin/renders/{id}/stop (with confirm)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
c076345ceb |
feat(render+admin): delete render node
Build backend images / build content-svc (push) Failing after 1m7s
Build backend images / build file-svc (push) Failing after 48s
Build backend images / build gateway (push) Failing after 55s
Build backend images / build identity-svc (push) Failing after 56s
Build backend images / build notification-svc (push) Failing after 1m7s
Build backend images / build render-svc (push) Failing after 53s
Build backend images / build studio-svc (push) Failing after 59s
- render-svc: DELETE /v1/nodes/:node_id (store.DeleteNode + handler + route) - admin: حذف button per node row + DELETE /api/admin/nodes/[nodeId] proxy Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
c4839bd35f |
feat(admin): project (template-item) manager + After Effects file upload
Build backend images / build content-svc (push) Failing after 50s
Build backend images / build file-svc (push) Failing after 1m5s
Build backend images / build gateway (push) Failing after 3m13s
Build backend images / build identity-svc (push) Failing after 1m32s
Build backend images / build notification-svc (push) Failing after 5m7s
Build backend images / build render-svc (push) Failing after 1m2s
Build backend images / build studio-svc (push) Failing after 54s
The admin could edit a container but not manage its renderable projects or attach
AE files. Now, inside the template editor:
- add a new project/variant under the container (name, WxH, aspect, resolution,
duration, fps, choose-mode) → POST /v1/projects (maps via container_id)
- upload the After Effects file (.aep/.zip) per project → new PATCH
/v1/projects/{id}/aep (sets AepFileUrl/Minio/Md5/Size + RenderAepComp), with an
"AE ✓ / بدون فایل" status badge
- set the render composition name; delete a variant
- ProjectResponse now surfaces aep_file_url / aep_file_size_bytes / render_aep_comp
Additive only — the existing aspect/resolution variant editing is unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
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>
|
||
|
|
24aa4c51a4 |
fix(identity): plan-statistics LINQ translation (aggregate in memory)
Build backend images / build content-svc (push) Failing after 57s
Build backend images / build file-svc (push) Failing after 58s
Build backend images / build gateway (push) Failing after 4m40s
Build backend images / build identity-svc (push) Failing after 56s
Build backend images / build notification-svc (push) Failing after 10s
Build backend images / build render-svc (push) Failing after 4m3s
Build backend images / build studio-svc (push) Failing after 2m24s
EF Core can't translate a conditional Count(predicate) inside a grouped Select; fetch flat rows then group/aggregate in memory. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
151970accd |
feat(admin): plan statistics + node restart/close-ae actions
Build backend images / build content-svc (push) Failing after 1m22s
Build backend images / build file-svc (push) Failing after 3m8s
Build backend images / build gateway (push) Failing after 53s
Build backend images / build identity-svc (push) Failing after 57s
Build backend images / build notification-svc (push) Failing after 1m25s
Build backend images / build render-svc (push) Failing after 2m5s
Build backend images / build studio-svc (push) Failing after 3m59s
Final legacy-admin items: - identity GET /v1/admin/plan-statistics (active/total users + revenue per plan from user_plans); surfaced as a breakdown table in /admin/stats - NodesTable: wire Restart + Close-AE actions (backend already supported them) via new proxy routes; was only drain/release before Full DivineGateWeb legacy-admin parity achieved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3091911260 |
feat(admin): affiliate/personal discounts, user-videos, internal routes, authz
Build backend images / build content-svc (push) Failing after 1s
Build backend images / build file-svc (push) Failing after 1s
Build backend images / build gateway (push) Failing after 0s
Build backend images / build identity-svc (push) Failing after 0s
Build backend images / build notification-svc (push) Failing after 1s
Build backend images / build render-svc (push) Failing after 1s
Build backend images / build studio-svc (push) Failing after 1s
Closes the remaining legacy-admin gaps:
- Users «مدیریت» modal: create personal discount or affiliate code (owner_user_id +
owner_profit_percentage on existing /v1/discounts), and view the user's saved
projects ("videos") via new admin GET /v1/saved-projects/by-user/{id} (studio)
- Internal routes admin (/admin/routes): CRUD on content.internal_routes
(RoutesController + CmsService + gateway /v1/routes/*)
- Security: lock identity UsersController Search + Ban to [Authorize(Roles="Admin")]
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
0b538e1b1e |
feat(content+admin): home-events CRUD + comments moderation
Build backend images / build content-svc (push) Failing after 45s
Build backend images / build file-svc (push) Failing after 1m3s
Build backend images / build gateway (push) Failing after 0s
Build backend images / build identity-svc (push) Failing after 0s
Build backend images / build notification-svc (push) Failing after 1s
Build backend images / build render-svc (push) Failing after 1s
Build backend images / build studio-svc (push) Failing after 0s
- content-svc: home-events gains Create/Update/Delete + includeInactive list (POST/PUT/DELETE /v1/home-events, admin-gated; dates coerced to UTC) - admin /admin/home-events: full CRUD for homepage hero event banners - admin /admin/comments: list + approve/unapprove + delete (moderation) - AdminResource: optional listQuery to fetch inactive rows for admin views Fills the remaining legacy-admin gaps (home events, comments). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3acd366fda |
feat(admin): music library admin + fix CRM analytics UTC
Build backend images / build content-svc (push) Failing after 1m7s
Build backend images / build file-svc (push) Failing after 50s
Build backend images / build gateway (push) Failing after 59s
Build backend images / build identity-svc (push) Failing after 56s
Build backend images / build notification-svc (push) Failing after 1m0s
Build backend images / build render-svc (push) Failing after 1m0s
Build backend images / build studio-svc (push) Failing after 56s
- /admin/music: list / upload / delete studio audio tracks (content-svc GET/POST/DELETE /v1/music) — fills the legacy music-library gap - fix: CRM analytics coerced query-bound dates to UTC (Npgsql timestamptz rejects Kind=Unspecified) — endpoint was returning 400 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2c961b123b |
feat(content+admin): content ranking + statistics dashboard
Build backend images / build content-svc (push) Failing after 16s
Build backend images / build file-svc (push) Failing after 48s
Build backend images / build gateway (push) Failing after 17s
Build backend images / build identity-svc (push) Failing after 2m12s
Build backend images / build notification-svc (push) Failing after 3m15s
Build backend images / build render-svc (push) Failing after 51s
Build backend images / build studio-svc (push) Failing after 56s
- content-svc: template list gains popularity/rating sort modes (use_count_desc,
popular, rating_desc); new PATCH /v1/templates/{id}/sort to set manual sort
weight (feature/pin) without a full edit
- admin /admin/ranking: templates ordered by popularity with views/uses/rating
and inline manual-sort editor
- admin /admin/stats: overview dashboard (users, revenue, paying customers,
conversion, templates/categories/campaigns/blogs counts) aggregated from
existing identity + content endpoints
- nav: Dashboard + Ranking links
Completes the epic: SMS/Email/Templates → Marketing → CRM → Ranking + Stats.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
e7cdf35b65 |
feat(content): scenes + shared-colors + colour-presets endpoints
Build backend images / build content-svc (push) Failing after 2m53s
Build backend images / build file-svc (push) Failing after 3m55s
Build backend images / build gateway (push) Failing after 53s
Build backend images / build identity-svc (push) Failing after 3m26s
Build backend images / build notification-svc (push) Failing after 3m5s
Build backend images / build render-svc (push) Failing after 46s
Build backend images / build studio-svc (push) Failing after 2m22s
Completes the content backend for the studio building blocks (all project-scoped):
- GET /v1/scenes?project_id= + POST/PUT/DELETE (scene metadata CRUD)
- GET /v1/shared-colors?project_id= + POST/PUT/DELETE
- GET /v1/color-presets?project_id= + POST/PUT/DELETE (palette + items)
SceneColorService + DTOs; reads open, writes [Authorize(Roles=Admin)].
Gateway routes /v1/{scenes,shared-colors,color-presets}/* → content.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
cf5dd4f195 |
feat(admin): category SEO fields, Templates admin, safe project PATCH
Build backend images / build content-svc (push) Failing after 21s
Build backend images / build file-svc (push) Failing after 3m49s
Build backend images / build gateway (push) Failing after 1m2s
Build backend images / build identity-svc (push) Failing after 1m1s
Build backend images / build notification-svc (push) Failing after 1m2s
Build backend images / build render-svc (push) Failing after 1m0s
Build backend images / build studio-svc (push) Failing after 58s
- categories/tags admin forms: add meta title/description/keywords, bot-follow,
sort, is_active (backend already supported these)
- new Templates admin (/admin/templates): container CRUD with description,
keywords, publishing, premium, primary mode, category/tag assignment, plus
editable per-variant aspect & resolution
- content-svc: PATCH /v1/projects/{id} partial update so aspect/resolution edits
never wipe render/colour data (SharedColorsSvg, RenderAepComp, Folder)
- admin resource proxy: add PATCH passthrough
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
cd95ca2c6f |
fix(gateway/services): admin node/render pages 500 — redirect loop + is_admin claim
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 55s
Build backend images / build identity-svc (push) Failing after 48s
Build backend images / build notification-svc (push) Failing after 55s
Build backend images / build render-svc (push) Failing after 57s
Build backend images / build studio-svc (push) Failing after 44s
- gateway proxy: trim trailing slash before forwarding upstream. gin's RedirectTrailingSlash adds /nodes → /nodes/ while render-svc redirects /nodes/ → /nodes, forming an infinite redirect loop (admin pages 500'd) - accept is_admin as bool OR string "true" in render/file/notification/gateway auth middleware (identity emits it as a string) — admin endpoints were 403'ing Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
bcc69f0a2e |
feat: complete node-agent pipeline, TLS proxy, billing cancel, password reset
Node-agent — full render pipeline (items 1-3):
- render-svc: ClaimedJob now includes aep_download_url (presigned MinIO GET,
2h TTL, path=templates/{original_project_id}/template.aep)
- render-svc: POST /v1/internal/render/jobs/:id/output-upload-url
allocates Export row + returns presigned MinIO PUT URL + export_id
- render-svc: db.CreateExportForJob() inserts export row with 30-day retention
- render-svc: InternalHandler now owns minio client (templatesBucket + exportsBucket)
MINIO_TEMPLATES_BUCKET env var (default flatrender-templates)
- node-agent: runner/download.go — DownloadFile() + UploadFile() (stdlib only)
- node-agent: client.GetOutputUploadURL() + ClaimedJob.AEPDownloadURL field
- node-agent: runJob() full flow: download AEP → render → get upload URL →
PUT output to MinIO → Complete(export_id)
All steps are non-fatal with fallback (AEP miss → mock, upload fail → no export)
TLS reverse proxy (item 15):
- Caddyfile: three virtual hosts (DOMAIN, API_DOMAIN, STORAGE_DOMAIN)
auto-TLS via Let's Encrypt; security headers; 512MB upload limit on API
- docker-compose.v2.yml: caddy:2-alpine service, ports 80/443/443udp,
caddy_data + caddy_config volumes; env vars DOMAIN/API_DOMAIN/STORAGE_DOMAIN/ACME_EMAIL
- .env.v2.example: new Caddy + MINIO_TEMPLATES_BUCKET entries
Billing portal (item 5):
- Identity: POST /v1/users/me/plan/cancel — sets cancelled_at, auto_renew=false
(access continues to expiry); 404 when no active plan
- POST /api/billing/cancel — frontend proxy, validates auth
- GET /api/billing/portal — redirects to /dashboard/settings?tab=billing
- SettingsBilling: "Cancel plan" button with confirm dialog + optimistic UI,
"Change plan" button; becomes "use client" component
Password reset UI (item 7):
- POST /api/auth/password-reset — proxies /v1/auth/password/reset/request
(always 200, anti-enumeration)
- POST /api/auth/password-reset-confirm — proxies /v1/auth/password/reset/confirm
- AuthPageContent: "Forgot password?" link on sign-in tab opens 2-step reset flow
(email → OTP+new-password) without leaving the auth page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
d7743a6fbe |
feat: live render preview — node agent pushes PNG frames, frontend displays them in real time
render-svc: - db.UpdateJobPreview(): writes base64 PNG to render_jobs.image_preview_b64 (only on active jobs; Done/Failed/Cancelled rows ignored) - POST /v1/internal/render/jobs/:job_id/preview — node agent endpoint - Route registered under /v1/internal (nodeAuth) node-agent: - runner.PreviewFn callback type alongside ProgressFn - runner.preview.go: GeneratePreviewB64(percent, quality, resolution) — pure stdlib (image/png + encoding/base64), no external deps — 320×180 dark frame with animated progress bar + colored indicator dots - mock render: pushes a preview frame at every step (5→95%) - real AE render: pushes a preview frame every 30s - client.UpdatePreview(): POST /v1/internal/render/jobs/:job_id/preview - main.go: onPreview callback wires client.UpdatePreview() into runner.Run() frontend: - render-jobs.ts: RenderJobRow.preview_b64 field; read from progress endpoint - status/route.ts: previewB64 included in JSON response - RenderModal: aspect-ratio preview pane during polling — shows spinner until first frame arrives, then live-updates with each poll (every 3s); step label overlaid as badge bottom-right Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
ee421ccc68 |
feat(render-svc+node-agent): add job-claim endpoint and build node-agent skeleton
render-svc: - db: ClaimJob() — atomic SELECT FOR UPDATE SKIP LOCKED; transitions job to Preparing, marks node Busy in a single transaction - models: ClaimJobRequest + ClaimedJob types - handlers/internal: POST /v1/internal/render/jobs/claim — 200 with job or 204 when queue empty - main: register the claim route under /v1/internal (nodeAuth) services/node-agent/ (new Go module github.com/flatrender/node-agent): - internal/config: env-var based config (NODE_ID required, sensible defaults) - internal/client: typed orchestrator HTTP client (Online, Heartbeat, ClaimJob, Complete, Fail, ReportCrash) — X-Node-Signature auth - internal/runner: AE render via aerender.exe or mock (for dev without AE) - cmd/agent/main: register online → heartbeat loop (5s) + poll loop (3s) → claim job → run render → report complete/fail; health endpoint on :7777 - Dockerfile: cross-compiles to Windows amd64 static binary Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
7f03ad1d03 |
chore: add demo content seed for V2 content service
Idempotent SQL seed (deterministic UUIDs, ON CONFLICT DO NOTHING) that inserts 4 categories and 8 published template containers linked to them, so the public site shows real data through the gateway /v1/* routes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
8b86f17645 |
fix: make plans list public, fix frontend healthcheck IPv6
PlansController had a class-level [Authorize] that gated the public plans list, contradicting the gateway's optionalAuth on /plans. Mark List/GetById [AllowAnonymous] and resolve tenant optionally so anonymous callers receive global plans (purchase/current-plan stay authenticated). Frontend container stayed "unhealthy" because busybox wget resolves localhost to IPv6 [::1] while the Next.js standalone server binds IPv4 only. Use 127.0.0.1 in the healthcheck. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
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> |