Files
flatrender/PROJECT_MEMORY.md
T

21 KiB
Raw Blame History

FlatRender — Project Memory

Rule: Read this file before starting any task. Update it after every completed feature, bug fix, or architectural decision. Both Cursor AI and Claude Code use this as the project brain.


📌 Project Identity

Key Value
Project folder D:\Projects\flatrender
Brand name FlatRender (package: flatrender) — All UI updated to FlatRender
Products Video Maker · Image Maker
Stack Next.js 14 App Router · TypeScript · Tailwind CSS · shadcn/ui · Framer Motion
Canvas React-Konva (Konva.js) — both Video Studio and Image Editor
State Zustand (studio-store.ts, image-editor-store.ts)
Auth + DB Supabase (@supabase/ssr)
Payments Stripe
Video (browser) ffmpeg.wasm in Web Worker (src/workers/ffmpeg-trim.worker.ts)
Video (server) nexrender + Adobe After Effects (server/render-worker.ts)
Dev server npm run devhttp://localhost:3000
Render worker npm run render-workerhttp://localhost:3355

Completed Features

Landing Page (/)

  • Hero — gradient on “AI” (from-blue-600 via-violet-500 to-blue-500), dual CTA, preview cards, blobs
  • HeroPreviewCards — Mixkit MP4 loops, play overlay fades on hover, Framer Motion stagger
  • ProductsShowcase — Video Maker + Image Maker cards with glassmorphism style
  • TemplateGallery — filter tabs, 8-card grid, scroll-mt-20 for sticky nav anchor
  • TemplateCard — hover Mixkit video via previewVideoUrl, bottom "Use Template" CTA, AnimatePresence fade
  • template-gallery-data.tspreviewVideoUrl on video/social template entries
  • HowItWorks — 3-step process, alternating layout, scroll-triggered animations
  • Pricing — monthly/annual toggle, green “Save 20%” yearly badge, 3 tiers, Stripe checkout wired
  • PricingCompareTable — full feature comparison table, 5 sections, synced billing toggle, Pro column highlight
  • Testimonials — 6-card grid
  • FAQ — accordion, 2-column layout
  • Navbar — FlatRender logo, Video/Image Maker + Learn dropdowns (shadcn), Pricing link, Sign In / Try for Free; mobile sheet (navbar-menu-data.ts)
  • Footer — 4-column, dark background

Product Pages

  • /video-maker — Hero, Features, UseCases, TemplateCarousel, CTA
  • /image-maker — Hero, BeforeAfter, Gallery, Features, UseCases, CTA

Templates Page (/templates)

  • Renderforest layout: 260px category sidebar + carousel rows (VideoTemplatesCategorySidebar, VideoTemplatesCarouselRow)
  • Toolbar: search, Premium Only (Switch), All Sizes select (16:9 / 9:16 / 1:1 / 4:5), Sort by (local state)
  • Sidebar filters panel (collapsed): Premium + size; ?category= from navbar
  • VideoTemplatesPageContent — client-side filtering via video-templates-catalog.ts
  • Template detail /templates/[id]TemplateDetailContent (preview, styles, Create Now, examples row); generateStaticParams from catalog

Auth (/auth)

  • Sign In / Sign Up tabs
  • Email + password (react-hook-form + zod)
  • Google OAuth button
  • Supabase auth integration
  • OAuth callback route (/auth/callback)
  • Sign-out route (/auth/sign-out)
  • SupabaseSetupNotice — shown when env vars missing (dev-friendly)

Dashboard (/dashboard)

  • DashboardShell — layout wrapper
  • DashboardSidebar — logo, nav links, user avatar + plan badge
  • DashboardTopBar — search + "New Project" dropdown
  • NewProjectMenu — Video / Image / Trimmer options
  • DashboardProjectsSection — projects grid from Supabase; isLoading shows 6-card skeleton grid
  • DashboardProjectsContent — async Supabase fetch (Suspense on /dashboard)
  • SkeletonProjectCard — pulse placeholders matching ProjectCard layout
  • DashboardPlanBadge — async plan fetch; sidebar Suspense + DashboardPlanBadgeSkeleton
  • DashboardSidebarNav — client nav (pathname-aware)
  • DashboardEmptyState — illustration + CTA
  • ProjectCard — thumbnail, type badge, status, 3-dot menu
  • /dashboard/settings — settings page

Video Creation Studio (/studio/video/[projectId])

  • VideoStudioLayout — icon dock (56px) + fixed 220px tool panel + full-width canvas/timeline (no right PropertiesPanel); StudioMobileGate below 768px; useStudioProjectPersistence (3s debounced save; dev 404 → localStorage flatrender-project-{id})
  • StudioSidebarDock — Audio / TTS / Colors / Transitions / Font / Watermark + Guide + Keyboard (toasts); blue active bar; scenes via timeline strip only
  • WatermarkSidebarContent — upload placeholder, 3×3 position grid, opacity slider
  • Sidebar panels — AudioSidebarContent, ColorsSidebarContent, TransitionsSidebarContent (Random / No Transition tiles, apply all scenes), FontSidebarContent, WatermarkSidebarContent
  • scene-browser-data.ts, SceneBrowserCard, shadcn Tabs for media filter
  • /studio/video/new — Renderforest-style onboarding (Select Scenes / AI / presets) before editor
  • VideoProjectNewContent, TEMPLATE_GALLERY_ITEMS (picsum thumbnails); preset click → /templates/[id]; catalog includes onboarding preset ids
  • SceneBrowserModal — full-screen library (categories, Video/Photo tabs, search, 28 scenes); onboarding + studio “Browse Scenes”
  • StudioMobileGate + useIsMobile — desktop-only gate for video/image studio (matchMedia max-width 767px)
  • ResizableStudioPanel — drag-to-resize left/right panels
  • StudioTopBar — breadcrumb (My Projects → name), StudioTopBarSaveBadge (Local / Saved ✓ / dot), centered undo/redo + toolbar, StudioTopBarTextControls when text layer selected, Export dropdown → RenderModal presets
  • PropertiesPanel — still used by image editor; not mounted in video studio layout
  • dev-project-storage.ts — dev-only localStorage fallback when Supabase returns 404
  • render-presets.ts — full / 720p preview / GIF export presets for RenderModal
  • Scenes managed via timeline SceneThumbnailStrip only (no left sidebar scenes panel): 120×80px blocks, rename, browse (SceneBrowserModal), duplicate/delete on hover
  • SceneTransitionPicker — None / Fade / Slide / Zoom popover on outgoing scene
  • scene-transitions.ts — Framer Motion animate() playback (300ms fade, slide-left, zoom)
  • DraggableSceneItem + SceneItemActions — live Konva thumbnailUrl previews
  • AddSceneMenu — blank / from template
  • CanvasEditor — React-Konva Stage (1280×720), scaled to container
    • Text layers (draggable, resizable, rotatable)
    • Image layers
    • Video clip layers
    • Shape layers (rect, circle, line, arrow)
    • Transformer (resize handles, rotation, min 8px guard)
    • Click empty area → deselect
    • Circle drag fix (center-origin correction)
  • CanvasLayerNode router → TextLayerNode, ImageLayerNode, ShapeLayerNode, VideoLayerNode
  • PropertiesPanel — context-sensitive to selected layer type
    • TextLayerProperties — font, size, bold/italic, color, align, letter-spacing, line-height, animation style
    • ImageLayerProperties — opacity, flip H/V, replace, border-radius
    • ShapeLayerProperties — fill, stroke, stroke-width, border-radius
    • CommonLayerControls — X/Y/W/H, rotation, z-order, delete
    • PropertyControls + useLayerUpdater
  • Timeline — 180px Renderforest layout: TimelineControlBar, SceneThumbnailStrip / SceneThumbnailBlock, TimelineActionRow; playhead on strip (STRIP_PX_PER_SECOND 24); zoom slider 30120
    • TimeRuler — time markers, click to seek
    • SceneTrack + SceneBlock — color-coded, drag-right-edge to resize duration
    • AudioTrack — file picker, file name display
    • TimelinePlayhead — red playhead overlay on thumbnail strip during playback
    • Legacy SceneBlock / SceneTrack / TimeRuler / AudioTrack — unused by Timeline (kept for reference)
  • StudioToolbar — add Text / Image / Video / Shape buttons
  • RenderModal — resolution, FPS, progress bar, download link
  • useCanvasKeyboard — Delete, Ctrl+C/V/Z/Y
  • useCanvasPreviewPlayback — scene-by-scene playback with timing
  • useContainerSize — responsive canvas scaling
  • studio-store.ts — full Zustand store (scenes, layers, playback, zoom, audio, undo/redo)
  • studio-history.ts — past/future snapshot undo stack (limit 50)
  • studio-timeline.ts — duration helpers, zoom levels, scene-at-time
  • studio-types.ts — Scene, Layer, LayerType, SceneTransition, AddLayerInput interfaces
  • studio-snapshot.ts — Konva stage → PNG download
  • studio-canvas-stage.ts — global stage ref registry
  • studio-scene-thumbnail.tstoDataURL({ pixelRatio: 0.2 }) + deferred capture after layer edits
  • studio-scene-data.ts / image-scene-data.ts — parse + serialize scene_data for persistence
  • ProjectSaveIndicator — Saving… / Saved / Local save / Save failed (image editor); video studio uses StudioTopBarSaveBadge
  • canvas-transform.ts — node transform → layer coords
  • studio-layer-props.ts — typed prop accessors per layer type
  • dev-mock-project.ts — dev-only mock for testing without Supabase

Video Trimmer (/studio/trimmer)

  • TrimmerUploadZone — drag-drop + click, accepts video/*
  • TrimmerVideoPreview<video> + react-rnd crop overlay, aspect ratio buttons
  • TrimmerStrip — frame thumbnail strip, draggable trim handles
  • TrimmerExportSection — MP4/WebM toggle, export button, progress, download
  • ffmpeg-trim.worker.ts — full ffmpeg.wasm Web Worker (init, progress, process, complete)
  • ffmpeg-worker-client.ts — typed client to communicate with worker
  • trimmer-types.ts + trimmer-utils.ts — types and crop scaling math

Image Editor (/studio/image and /studio/image/[projectId])

  • ImageEditorLayout — full-viewport, dark theme; mobile gate; useImageProjectPersistence auto-save
  • ImageEditorTopBar — project name, export button
  • ImageEditorToolbar — Select, Crop, Text, Shape, Draw, AI tools
  • ImageEditorCanvas — dynamic import (SSR off), Konva stage
    • ImageBaseLayer — base image rendering with Konva filters
    • ImageEditorLayerNode — text/shape/draw layer nodes
    • ImageCropOverlayreact-rnd crop box on canvas (aspect lock)
    • VignetteOverlay — radial gradient vignette
  • ImageCropControls — aspect presets (Free, 1:1, 16:9, 4:3, 9:16), Apply/Cancel above canvas
  • image-editor-crop.ts — aspect math, canvas→source crop, cropImageDataUrl
  • ImageEditorRightPanel — tabbed: Adjust | Filters | Layers
    • AdjustPanel — brightness, contrast, saturation, hue, blur, sharpen, vignette sliders
    • FiltersPanel — 12 preset filter thumbnails
    • LayersPanel — reorder, hide, lock, delete
  • AiRemoveBgModal — calls /api/remove-bg, shows result
  • image-editor-store.ts — Zustand store for image editor
  • image-editor-filters.ts — Konva filter pipeline helpers
  • image-editor-konva.ts — Konva helpers
  • image-editor-types.ts — ImageLayer, ImageEditorState types
  • image-editor-export.ts — stage → PNG/JPG/WebP download
  • image-editor-stage-ref.ts — global stage ref
  • image-editor-transform.ts — transform helpers

API Routes

  • POST /api/checkout — creates Stripe Checkout session
  • POST /api/webhooks/stripe — updates user plan on checkout.session.completed
  • GET/POST /api/projects — fetch / create user projects
  • GET/PATCH /api/projects/[projectId] — load project + auto-save scene_data
  • POST /api/remove-bg — calls remove.bg or rembg service
  • POST /api/render — queues render job in Supabase
  • GET /api/render/[jobId]/status — poll render job status

Server (render worker process)

  • server/render-worker.ts — HTTP server on port 3355, /health + /process
  • server/render-job-processor.ts — fetches job from Supabase, runs nexrender, uploads result
  • server/nexrender-job-builder.ts — builds nexrender job JSON from scene data
  • server/nexrender.d.ts — type declarations for @nexrender/core

Infrastructure

  • supabase/migrations/001_profiles.sql — profiles table, RLS
  • supabase/migrations/002_render_jobs.sql — render_jobs table, RLS
  • supabase/migrations/003_projects.sql — projects table, RLS, updated_at trigger
  • .env.example — all required env vars documented
  • next.config.mjs — webpack globalObject fix + COOP/COEP headers (required for ffmpeg.wasm)
  • .cursorrules — full project rules for Cursor AI
  • tailwind.config.ts — custom colors, font families
  • components.json — shadcn/ui config

🔄 In Progress

Nothing currently in progress.

Landing page status (2026-05-21 polish)

  • npx tsc --noEmit — clean (no TypeScript errors)
  • Tailwind rf.blue / rf.blue-light#2563EB / #EFF6FF
  • Remaining pre-launch work is env/migrations/E2E tests (see Must Do backlog), not landing UI

📋 Backlog (Next Tasks)

🔴 Must Do Before Launch

  • Create .env.local from .env.example and fill in real keys ← NOT DONE YET
  • Run Supabase migrations (001002003) in SQL Editor ← NOT DONE YET
  • Test full auth flow (sign up → dashboard → create project → open studio)
  • Test ffmpeg.wasm trimmer end-to-end in browser

🟡 UI Polish (Cursor screenshot-driven)

  • Navbar: Video/Image Maker + Learn dropdowns (Renderforest-style, no mega menu)
  • Landing polish pass: rf-blue / rf-blue-light tokens, Hero AI gradient, pricing Save 20% badge, #templates scroll-mt-20
  • Hero: animated video thumbnail preview cards (autoplay muted)
  • TemplateCard: video preview on hover (autoplay muted loop, AnimatePresence fade)
  • Studio: scene thumbnail auto-generated from Konva canvas (toDataURL)
  • Studio: transition picker between scenes (fade, slide, zoom)
  • Dashboard: skeleton loading states for project cards
  • Mobile: studio pages desktop gate (under 768px shows StudioMobileGate, not full editor)

🟢 Nice to Have

  • Template system: pre-built .aep templates for nexrender
  • Image editor: text curved/arc effect
  • Image editor: sticker/icon library (200+ SVGs)
  • Video studio: background color/gradient picker per scene
  • Onboarding flow for new users (first project wizard)
  • Usage limits per plan (enforced server-side)

🐛 Known Issues

# Issue File Priority
1 Brand name "CreatorStudio" in UI Fixed 2026-05-21 — all 4 files updated
2 next.config.mjs was missing COOP/COEP headers Fixed 2026-05-21
3 Scene thumbnails are placeholder gray boxes Fixed 2026-05-21 — thumbnailUrl via updateSceneThumbnail
4 No loading/error state in trimmer if ffmpeg CDN is slow TrimmerExportSection 🟡 Medium
5 Image editor crop tool not fully implemented Fixed 2026-05-21 — ImageCropControls, ImageCropOverlay, pixel crop in applyCrop

🏗️ Architecture Decisions

Decision Rationale
React-Konva for all canvas work Consistent layer model across Video Studio and Image Editor
ffmpeg.wasm in Web Worker only Never block main thread; SharedArrayBuffer requires COOP/COEP headers in next.config.mjs
Zustand for studio state (not React context) Avoids re-render cascade on every canvas update
nexrender + aerender for final render AE templates give highest quality output; RENDER_MOCK=true skips it in dev
Supabase RLS on all tables Row-level security — users can only access their own data
studio-canvas-stage.ts global stage ref Allows snapshot/export from any component without prop-drilling
Dynamic import for ImageEditorCanvas Konva cannot run on server — ssr: false prevents SSR crash
dev-mock-project.ts Dev POST mock; dev-project id skips load/save in studio editors

🚀 Production-Ready Checklist

Item Status
next.config.mjsoutput: 'standalone' (Docker)
app/sitemap.ts/, /video-maker, /image-maker, /templates, /pricing
app/robots.ts — allow public; disallow /dashboard, /studio, /api
Page metadata via createPageMetadata (public routes + studio layouts)
app/pricing/page.tsx — dedicated pricing route for SEO/sitemap
app/error.tsx — error boundary with reload
app/not-found.tsx — 404 with home CTA
npx tsc --noEmit clean (re-run before deploy)
.env.local + Supabase migrations Operator setup
NEXT_PUBLIC_SITE_URL set to production domain Required for sitemap/OG URLs

🔑 Environment Variables Checklist

Variable Status Where to get it
NEXT_PUBLIC_SUPABASE_URL Not set Supabase → Settings → API
NEXT_PUBLIC_SUPABASE_ANON_KEY Not set Supabase → Settings → API
SUPABASE_SERVICE_ROLE_KEY Not set Supabase → Settings → API
STRIPE_SECRET_KEY Not set Stripe Dashboard → API Keys
STRIPE_WEBHOOK_SECRET Not set Stripe → Webhooks → signing secret
STRIPE_PRICE_PRO_MONTHLY Not set Stripe → Products → price ID
STRIPE_PRICE_PRO_ANNUAL Not set Stripe → Products → price ID
STRIPE_PRICE_BUSINESS_MONTHLY Not set Stripe → Products → price ID
STRIPE_PRICE_BUSINESS_ANNUAL Not set Stripe → Products → price ID
REMOVE_BG_API_KEY Not set remove.bg → API
RENDER_WORKER_URL Default: http://localhost:3355
RENDER_MOCK Default: true Set to false when AE is configured
NEXRENDER_TEMPLATE_SRC Not set Path to your .aep template file
NEXRENDER_BINARY Not set Path to aerender executable

📁 Key File Map (Quick Reference)

src/
├── app/
│   ├── page.tsx                        ← Landing page
│   ├── video-maker/page.tsx            ← Video Maker product page
│   ├── image-maker/page.tsx            ← Image Maker product page
│   ├── templates/page.tsx              ← Templates gallery
│   ├── pricing/page.tsx                ← Pricing (public SEO route)
│   ├── sitemap.ts / robots.ts          ← SEO + crawler rules
│   ├── error.tsx / not-found.tsx       ← Global error UI
│   ├── auth/page.tsx                   ← Sign in / Sign up
│   ├── dashboard/page.tsx              ← User dashboard
│   ├── studio/
│   │   ├── video/new/page.tsx          ← New video project onboarding
│   │   ├── video/[projectId]/page.tsx  ← Video Creation Studio
│   │   ├── image/[projectId]/page.tsx  ← Image Editor
│   │   └── trimmer/page.tsx            ← Video Trimmer/Cropper
│   └── api/                            ← All API routes
├── components/
│   ├── layout/                         ← Navbar, Footer, SiteChrome
│   ├── sections/                       ← Landing page sections
│   ├── studio/                         ← Video Studio components
│   ├── image-editor/                   ← Image Editor components
│   ├── trimmer/                        ← Video Trimmer components
│   ├── dashboard/                      ← Dashboard components
│   └── ui/                             ← shadcn/ui (do not edit)
├── lib/
│   ├── studio-store.ts                 ← Video Studio Zustand store
│   ├── studio-types.ts                 ← Scene / Layer types
│   ├── image-editor-store.ts           ← Image Editor Zustand store
│   └── supabase/                       ← Supabase client helpers
├── hooks/                              ← useCanvasKeyboard, useContainerSize, useIsMobile, etc.
└── workers/
    └── ffmpeg-trim.worker.ts           ← ffmpeg.wasm Web Worker

server/
├── render-worker.ts                    ← HTTP server (port 3355)
├── render-job-processor.ts            ← nexrender job runner
└── nexrender-job-builder.ts           ← builds AE job from scene JSON

supabase/
└── migrations/                         ← SQL files, run in order in Supabase SQL Editor

📅 Session Log

Date What was done
2026-05-21 Full project scaffolded: all pages, studio modules, API routes, Supabase migrations, server render worker
2026-05-21 Fixed next.config.mjs — added COOP/COEP headers required for ffmpeg.wasm SharedArrayBuffer
2026-05-21 Created PROJECT_MEMORY.md — project brain for Cursor + Claude
2026-05-21 Fixed brand name in 4 files: metadata.ts, DashboardSidebar.tsx, ProductsMegaMenu.tsx, Navbar.tsx
2026-05-21 Discovered ProductsMegaMenu already fully built — moved from backlog to done
2026-05-21 Added PricingCompareTable with 5 feature sections matching Renderforest /subscription layout
2026-05-21 Scene thumbnails: thumbnailUrl on Scene, updateSceneThumbnail, DraggableSceneItem img preview