feat(render): node-agent AE snapshot runner (Epic C2) + colour render-binding (Epic B)
Build backend images / build content-svc (push) Failing after 13s
Build backend images / build file-svc (push) Failing after 53s
Build backend images / build gateway (push) Failing after 1m22s
Build backend images / build identity-svc (push) Failing after 19s
Build backend images / build notification-svc (push) Failing after 21s
Build backend images / build render-svc (push) Failing after 20s
Build backend images / build studio-svc (push) Failing after 1m6s

C2 — real-AE scene snapshots on the node:
- node-agent: runner/snapshot.go RunSnapshot (aerender -comp <key> -s f -e f
  → findRenderedOutput → ffmpeg -frames:v 1 PNG); client ClaimSnapshot /
  GetSnapshotUploadURL / ReportSnapshotResult / ReportSnapshotFail; snapshotLoop +
  pollSnapshotOnce mirroring the scan loop (reuses the AE-exclusive lock).
- render-svc: GetSnapshotJobMeta + UploadURL handler presigns a PUT to the
  public-read user-uploads bucket at snapshots/{project}/{scene}.png and returns a
  permanent public_url (not the time-limited export presign); MINIO_UPLOAD_BUCKET +
  MINIO_PUBLIC_URL config + compose env + /snapshot/:id/upload-url route.

Epic B — bind edited colours into the render:
- render-svc GetRenderBindings UNIONs studio.saved_shared_colors +
  saved_scene_colors (type 'color') so the node writes them before render.
- node-agent binder.go routes type:"color" bindings into the bind-spec colors[]
  array that bind.jsx already applies to the frshare colour layers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-11 18:08:43 +03:30
parent 8488acb115
commit 6cf8716d7e
9 changed files with 329 additions and 5 deletions
+9 -1
View File
@@ -36,6 +36,13 @@ func main() {
minioUseSSL := getEnv("MINIO_USE_SSL", "false") == "true"
minioBucket := getEnv("MINIO_BUCKET", "flatrender-exports")
minioTemplatesBucket := getEnv("MINIO_TEMPLATES_BUCKET", "flatrender-templates")
minioUploadBucket := getEnv("MINIO_UPLOAD_BUCKET", "user-uploads") // public-read — scene snapshots
minioPublicBase := getEnv("MINIO_PUBLIC_URL", func() string {
if minioUseSSL {
return "https://" + minioEndpoint
}
return "http://" + minioEndpoint
}())
notificationURL := getEnv("NOTIFICATION_URL", "http://localhost:8080")
identityURL := getEnv("IDENTITY_URL", "")
serviceToken := getEnv("SERVICE_TOKEN", "internal-service-secret")
@@ -82,7 +89,7 @@ func main() {
fontH := handlers.NewFontHandler(store)
bundleH := handlers.NewTemplateBundleHandler(mc, minioTemplatesBucket)
scanH := handlers.NewScanHandler(store, mc, minioTemplatesBucket)
snapJobH := handlers.NewSnapshotJobHandler(store, mc, minioTemplatesBucket)
snapJobH := handlers.NewSnapshotJobHandler(store, mc, minioTemplatesBucket, minioUploadBucket, minioPublicBase)
internalH := handlers.NewInternalHandler(store, notifyClient, mc, minioTemplatesBucket, minioBucket)
// ── Dev mock worker (no AE node needed) ────────────────────────────────────
@@ -217,6 +224,7 @@ func main() {
// AE scene snapshots (node claims, renders one frame, posts the image URL)
internal.POST("/snapshot/claim", snapJobH.Claim)
internal.POST("/snapshot/:id/upload-url", snapJobH.UploadURL)
internal.POST("/snapshot/:id/result", snapJobH.Result)
internal.POST("/snapshot/:id/fail", snapJobH.Fail)