Files
flatrender/PROJECT_MEMORY.md
Soroush.Asadi 36e264f3e3 feat: admin API integration, LogoMark, settings page, i18n, RTL font, docs
- Wire admin API into homepage + templates page (ISR 60s, null fallback)
- Add src/lib/admin-api.ts with safeFetch helper
- Add adminProjectToTemplateItem + adminProjectToCatalogTemplate mappers
- Add LogoMark SVG component, replace Sparkles icon in Navbar/Footer/Sidebar
- Add public/favicon.svg (SVG brand mark)
- Rewrite opengraph-image.tsx with FlatRender branding
- Add RTL/Persian font cascade: unlayered [dir=rtl] block forces Vazirmatn
- Dashboard Settings page: Profile, Security, Billing, Notifications sections
- Add src/lib/supabase/client.ts browser client
- Admin API: GET /me, PATCH /profile, POST /change-password endpoints
- Admin API DTOs: AdminUserDto, UpdateProfileRequest, ChangePasswordRequest
- Admin UI Settings page with TanStack Query + mutations
- Add CLAUDE.md + README.md to both repos for new-machine onboarding
- Update PROJECT_MEMORY.md with session log
- Add appsettings.Development.json.example template
2026-05-27 09:06:51 +03:30

408 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 dev` → http://localhost:3000 |
| Render worker | `npm run render-worker` → http://localhost:3355 |
---
## ✅ Completed Features
### Landing Page (`/`)
- [x] `Hero` — gradient on “AI” (`from-blue-600 via-violet-500 to-blue-500`), dual CTA, preview cards, blobs
- [x] `HeroPreviewCards` — Mixkit MP4 loops, play overlay fades on hover, Framer Motion stagger
- [x] `ProductsShowcase` — Video Maker + Image Maker cards with glassmorphism style
- [x] `TemplateGallery` — filter tabs, 8-card grid, `scroll-mt-20` for sticky nav anchor
- [x] `TemplateCard` — hover Mixkit video via `previewVideoUrl`, bottom "Use Template" CTA, `AnimatePresence` fade
- [x] `template-gallery-data.ts``previewVideoUrl` on video/social template entries
- [x] `HowItWorks` — 3-step process, alternating layout, scroll-triggered animations
- [x] `Pricing` — monthly/annual toggle, green “Save 20%” yearly badge, 3 tiers, Stripe checkout wired
- [x] `PricingCompareTable` — full feature comparison table, 5 sections, synced billing toggle, Pro column highlight
- [x] `Testimonials` — 6-card grid
- [x] `FAQ` — accordion, 2-column layout
- [x] `Navbar` — FlatRender logo, Video/Image Maker + Learn dropdowns (shadcn), Pricing link, Sign In / Try for Free; mobile sheet (`navbar-menu-data.ts`)
- [x] `Footer` — 4-column, dark background
### Product Pages
- [x] `/video-maker` — Hero, Features, UseCases, TemplateCarousel, CTA
- [x] `/image-maker` — Hero, BeforeAfter, Gallery, Features, UseCases, CTA
### Templates Page (`/templates`)
- [x] Renderforest layout: 260px category sidebar + carousel rows (`VideoTemplatesCategorySidebar`, `VideoTemplatesCarouselRow`)
- [x] Toolbar: search, Premium Only (Switch), All Sizes select (16:9 / 9:16 / 1:1 / 4:5), Sort by (local state)
- [x] Sidebar filters panel (collapsed): Premium + size; `?category=` from navbar
- [x] `VideoTemplatesPageContent` — client-side filtering via `video-templates-catalog.ts`
- [x] Template detail `/templates/[id]``TemplateDetailContent` (preview, styles, Create Now, examples row); `generateStaticParams` from catalog
### Auth (`/auth`)
- [x] Sign In / Sign Up tabs
- [x] Email + password (react-hook-form + zod)
- [x] Google OAuth button
- [x] Supabase auth integration
- [x] OAuth callback route (`/auth/callback`)
- [x] Sign-out route (`/auth/sign-out`)
- [x] `SupabaseSetupNotice` — shown when env vars missing (dev-friendly)
### Dashboard (`/dashboard`)
- [x] `DashboardShell` — layout wrapper
- [x] `DashboardSidebar` — logo, nav links, user avatar + plan badge
- [x] `DashboardTopBar` — search + "New Project" dropdown
- [x] `NewProjectMenu` — Video / Image / Trimmer options
- [x] `DashboardProjectsSection` — projects grid from Supabase; `isLoading` shows 6-card skeleton grid
- [x] `DashboardProjectsContent` — async Supabase fetch (Suspense on `/dashboard`)
- [x] `SkeletonProjectCard` — pulse placeholders matching `ProjectCard` layout
- [x] `DashboardPlanBadge` — async plan fetch; sidebar `Suspense` + `DashboardPlanBadgeSkeleton`
- [x] `DashboardSidebarNav` — client nav (pathname-aware)
- [x] `DashboardEmptyState` — illustration + CTA
- [x] `ProjectCard` — thumbnail, type badge, status, 3-dot menu
- [x] `/dashboard/settings` — settings page
### Video Creation Studio (`/studio/video/[projectId]`)
- [x] `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}`)
- [x] `StudioSidebarDock` — Audio / TTS / Colors / Transitions / Font / Watermark + Guide + Keyboard (toasts); blue active bar; scenes via timeline strip only
- [x] `WatermarkSidebarContent` — upload placeholder, 3×3 position grid, opacity slider
- [x] Sidebar panels — `AudioSidebarContent`, `ColorsSidebarContent`, `TransitionsSidebarContent` (Random / No Transition tiles, apply all scenes), `FontSidebarContent`, `WatermarkSidebarContent`
- [x] `scene-browser-data.ts`, `SceneBrowserCard`, shadcn `Tabs` for media filter
- [x] `/studio/video/new` — Renderforest-style onboarding (Select Scenes / AI / presets) before editor
- [x] `VideoProjectNewContent`, `TEMPLATE_GALLERY_ITEMS` (picsum thumbnails); preset click → `/templates/[id]`; catalog includes onboarding preset ids
- [x] `SceneBrowserModal` — full-screen library (categories, Video/Photo tabs, search, 28 scenes); onboarding + studio “Browse Scenes”
- [x] `StudioMobileGate` + `useIsMobile` — desktop-only gate for video/image studio (`matchMedia` max-width 767px)
- [x] `ResizableStudioPanel` — drag-to-resize left/right panels
- [x] `StudioTopBar` — breadcrumb (My Projects → name), `StudioTopBarSaveBadge` (Local / Saved ✓ / dot), centered undo/redo + toolbar, `StudioTopBarTextControls` when text layer selected, Export dropdown → `RenderModal` presets
- [x] `PropertiesPanel` — still used by image editor; not mounted in video studio layout
- [x] `dev-project-storage.ts` — dev-only localStorage fallback when Supabase returns 404
- [x] `render-presets.ts` — full / 720p preview / GIF export presets for `RenderModal`
- [x] Scenes managed via timeline `SceneThumbnailStrip` only (no left sidebar scenes panel): 120×80px blocks, rename, browse (`SceneBrowserModal`), duplicate/delete on hover
- [x] `SceneTransitionPicker` — None / Fade / Slide / Zoom popover on outgoing scene
- [x] `scene-transitions.ts` — Framer Motion `animate()` playback (300ms fade, slide-left, zoom)
- [x] `DraggableSceneItem` + `SceneItemActions` — live Konva `thumbnailUrl` previews
- [x] `AddSceneMenu` — blank / from template
- [x] `CanvasEditor` — React-Konva Stage (1280×720), scaled to container
- [x] Text layers (draggable, resizable, rotatable)
- [x] Image layers
- [x] Video clip layers
- [x] Shape layers (rect, circle, line, arrow)
- [x] Transformer (resize handles, rotation, min 8px guard)
- [x] Click empty area → deselect
- [x] Circle drag fix (center-origin correction)
- [x] `CanvasLayerNode` router → `TextLayerNode`, `ImageLayerNode`, `ShapeLayerNode`, `VideoLayerNode`
- [x] `PropertiesPanel` — context-sensitive to selected layer type
- [x] `TextLayerProperties` — font, size, bold/italic, color, align, letter-spacing, line-height, animation style
- [x] `ImageLayerProperties` — opacity, flip H/V, replace, border-radius
- [x] `ShapeLayerProperties` — fill, stroke, stroke-width, border-radius
- [x] `CommonLayerControls` — X/Y/W/H, rotation, z-order, delete
- [x] `PropertyControls` + `useLayerUpdater`
- [x] `Timeline` — 180px Renderforest layout: `TimelineControlBar`, `SceneThumbnailStrip` / `SceneThumbnailBlock`, `TimelineActionRow`; playhead on strip (`STRIP_PX_PER_SECOND` 24); zoom slider 30120
- [x] `TimeRuler` — time markers, click to seek
- [x] `SceneTrack` + `SceneBlock` — color-coded, drag-right-edge to resize duration
- [x] `AudioTrack` — file picker, file name display
- [x] `TimelinePlayhead` — red playhead overlay on thumbnail strip during playback
- [x] Legacy `SceneBlock` / `SceneTrack` / `TimeRuler` / `AudioTrack` — unused by Timeline (kept for reference)
- [x] `StudioToolbar` — add Text / Image / Video / Shape buttons
- [x] `RenderModal` — resolution, FPS, progress bar, download link
- [x] `useCanvasKeyboard` — Delete, Ctrl+C/V/Z/Y
- [x] `useCanvasPreviewPlayback` — scene-by-scene playback with timing
- [x] `useContainerSize` — responsive canvas scaling
- [x] `studio-store.ts` — full Zustand store (scenes, layers, playback, zoom, audio, undo/redo)
- [x] `studio-history.ts` — past/future snapshot undo stack (limit 50)
- [x] `studio-timeline.ts` — duration helpers, zoom levels, scene-at-time
- [x] `studio-types.ts` — Scene, Layer, LayerType, `SceneTransition`, AddLayerInput interfaces
- [x] `studio-snapshot.ts` — Konva stage → PNG download
- [x] `studio-canvas-stage.ts` — global stage ref registry
- [x] `studio-scene-thumbnail.ts``toDataURL({ pixelRatio: 0.2 })` + deferred capture after layer edits
- [x] `studio-scene-data.ts` / `image-scene-data.ts` — parse + serialize `scene_data` for persistence
- [x] `ProjectSaveIndicator` — Saving… / Saved / Local save / Save failed (image editor); video studio uses `StudioTopBarSaveBadge`
- [x] `canvas-transform.ts` — node transform → layer coords
- [x] `studio-layer-props.ts` — typed prop accessors per layer type
- [x] `dev-mock-project.ts` — dev-only mock for testing without Supabase
### Video Trimmer (`/studio/trimmer`)
- [x] `TrimmerUploadZone` — drag-drop + click, accepts video/*
- [x] `TrimmerVideoPreview``<video>` + `react-rnd` crop overlay, aspect ratio buttons
- [x] `TrimmerStrip` — frame thumbnail strip, draggable trim handles
- [x] `TrimmerExportSection` — MP4/WebM toggle, export button, progress, download
- [x] `ffmpeg-trim.worker.ts` — full ffmpeg.wasm Web Worker (init, progress, process, complete)
- [x] `ffmpeg-worker-client.ts` — typed client to communicate with worker
- [x] `trimmer-types.ts` + `trimmer-utils.ts` — types and crop scaling math
### Image Editor (`/studio/image` and `/studio/image/[projectId]`)
- [x] `ImageEditorLayout` — full-viewport, dark theme; mobile gate; `useImageProjectPersistence` auto-save
- [x] `ImageEditorTopBar` — project name, export button
- [x] `ImageEditorToolbar` — Select, Crop, Text, Shape, Draw, AI tools
- [x] `ImageEditorCanvas` — dynamic import (SSR off), Konva stage
- [x] `ImageBaseLayer` — base image rendering with Konva filters
- [x] `ImageEditorLayerNode` — text/shape/draw layer nodes
- [x] `ImageCropOverlay``react-rnd` crop box on canvas (aspect lock)
- [x] `VignetteOverlay` — radial gradient vignette
- [x] `ImageCropControls` — aspect presets (Free, 1:1, 16:9, 4:3, 9:16), Apply/Cancel above canvas
- [x] `image-editor-crop.ts` — aspect math, canvas→source crop, `cropImageDataUrl`
- [x] `ImageEditorRightPanel` — tabbed: Adjust | Filters | Layers
- [x] `AdjustPanel` — brightness, contrast, saturation, hue, blur, sharpen, vignette sliders
- [x] `FiltersPanel` — 12 preset filter thumbnails
- [x] `LayersPanel` — reorder, hide, lock, delete
- [x] `AiRemoveBgModal` — calls `/api/remove-bg`, shows result
- [x] `image-editor-store.ts` — Zustand store for image editor
- [x] `image-editor-filters.ts` — Konva filter pipeline helpers
- [x] `image-editor-konva.ts` — Konva helpers
- [x] `image-editor-types.ts` — ImageLayer, ImageEditorState types
- [x] `image-editor-export.ts` — stage → PNG/JPG/WebP download
- [x] `image-editor-stage-ref.ts` — global stage ref
- [x] `image-editor-transform.ts` — transform helpers
### API Routes
- [x] `POST /api/checkout` — creates Stripe Checkout session
- [x] `POST /api/webhooks/stripe` — updates user plan on checkout.session.completed
- [x] `GET/POST /api/projects` — fetch / create user projects
- [x] `GET/PATCH /api/projects/[projectId]` — load project + auto-save `scene_data`
- [x] `POST /api/remove-bg` — calls remove.bg or rembg service
- [x] `POST /api/render` — queues render job in Supabase
- [x] `GET /api/render/[jobId]/status` — poll render job status
### Server (render worker process)
- [x] `server/render-worker.ts` — HTTP server on port 3355, `/health` + `/process`
- [x] `server/render-job-processor.ts` — fetches job from Supabase, runs nexrender, uploads result
- [x] `server/nexrender-job-builder.ts` — builds nexrender job JSON from scene data
- [x] `server/nexrender.d.ts` — type declarations for @nexrender/core
### Infrastructure
- [x] `supabase/migrations/001_profiles.sql` — profiles table, RLS
- [x] `supabase/migrations/002_render_jobs.sql` — render_jobs table, RLS
- [x] `supabase/migrations/003_projects.sql` — projects table, RLS, updated_at trigger
- [x] `.env.example` — all required env vars documented (including `ADMIN_API_URL`)
- [x] `next.config.mjs` — webpack globalObject fix + COOP/COEP headers (required for ffmpeg.wasm)
- [x] `.cursorrules` — full project rules for Cursor AI
- [x] `tailwind.config.ts` — custom colors, font families (heading, body, vazirmatn)
- [x] `components.json` — shadcn/ui config
- [x] `CLAUDE.md` — Claude Code instructions (auto-read on session start)
- [x] `public/favicon.svg` — brand favicon (SVG, blue rounded square + play icon)
### i18n
- [x] `messages/fa.json` + `messages/en.json` — full translations for all public pages
- [x] Namespaces: hero, nav, products, templates, pricing, testimonials, faq, footer, metadata, videoMaker, imageMaker
- [x] `globals.css``[dir="rtl"]` block forces Vazirmatn on all elements in Persian locale
- [x] `src/i18n/routing.ts``fa` default (no prefix), `en` at `/en/`
### Brand / Logo
- [x] `src/components/ui/LogoMark.tsx` — inline SVG brand mark (play triangle + 3 layer bars in blue square)
- [x] Navbar, Footer, DashboardSidebar — all use `<LogoMark>` (removed old `<Sparkles>` icon)
- [x] `app/opengraph-image.tsx` — proper FlatRender OG image (1200×630, headline + feature pills)
### Admin Panel integration
- [x] `src/lib/admin-api.ts``fetchCategories`, `fetchProjects`, `fetchProject`, `isAdminApiAvailable`
- [x] `app/[locale]/page.tsx` — async, fetches 8 projects → `<TemplateGallery adminItems={...}>`
- [x] `app/[locale]/templates/page.tsx` — async, fetches 100 video projects → `initialCatalog`
- [x] `TemplateGallery.tsx` — accepts `adminItems` prop, maps `AdminProject``TemplateItem`
- [x] `VideoTemplatesPageContent.tsx` — accepts `initialCatalog` prop
- [x] `video-templates-catalog.ts``adminProjectToCatalogTemplate()` mapper added
### Dashboard Settings
- [x] `/dashboard/settings` — full settings page (Profile, Security, Billing, Notifications, Danger zone)
- [x] `src/lib/supabase/client.ts` — browser Supabase client (for client-side auth updates)
- [x] `SettingsProfile.tsx` — editable display name via `supabase.auth.updateUser`
- [x] `SettingsSecurity.tsx` — change password (re-authenticates first)
- [x] `SettingsBilling.tsx` — plan info + features + Stripe billing portal link
- [x] `SettingsNotifications.tsx` — 4 email toggle switches
---
## 🔄 In Progress
_Nothing currently in progress._
### Status as of 2026-05-27
- `npx tsc --noEmit` — clean (zero TypeScript errors)
- All public pages fully built and i18n'd (fa + en)
- Admin panel fully built (backend + frontend) — needs real Postgres + MinIO credentials
- Admin API integrated into Next.js with ISR fallback
- Logo, favicon, OG image all done
- Dashboard settings page fully functional
- Next step: fill in `.env.local` credentials and test end-to-end
---
## 📋 Backlog (Next Tasks)
### 🔴 Must Do Before Launch
- [ ] Create `.env.local` from `.env.example` and fill in Supabase + Stripe keys
- [ ] Run Supabase migrations (`001``002``003`) in SQL Editor
- [ ] Set up admin API: copy `appsettings.Development.json.example``appsettings.Development.json`, fill Postgres + MinIO
- [ ] Seed first admin: `POST /api/auth/seed` with email + password
- [ ] Upload real template categories + projects via admin panel (auto-appears on website)
- [ ] Add real logo image/video assets (currently using picsum + Mixkit placeholders)
- [ ] Test full auth flow (sign up → dashboard → create project → open studio)
- [ ] Test ffmpeg.wasm trimmer end-to-end in browser
- [ ] Build settings page "Delete account" confirmation flow
### 🟡 UI Polish (Cursor screenshot-driven)
- [x] Navbar: Video/Image Maker + Learn dropdowns (Renderforest-style, no mega menu)
- [x] Landing polish pass: `rf-blue` / `rf-blue-light` tokens, Hero AI gradient, pricing Save 20% badge, `#templates` scroll-mt-20
- [x] Hero: animated video thumbnail preview cards (autoplay muted)
- [x] TemplateCard: video preview on hover (autoplay muted loop, AnimatePresence fade)
- [x] Studio: scene thumbnail auto-generated from Konva canvas (toDataURL)
- [x] Studio: transition picker between scenes (fade, slide, zoom)
- [x] Dashboard: skeleton loading states for project cards
- [x] 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.mjs``output: '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 |
| 2026-05-27 | Built admin panel at `D:\Projects\flatrender-admin`: .NET 10 API + React SPA. Categories/Projects/Media CRUD, JWT auth, MinIO storage, public endpoints |
| 2026-05-27 | i18n: added `videoMaker` + `imageMaker` namespaces (fa + en), wired `useTranslations` in all 8 components |
| 2026-05-27 | Wired admin API into Next.js: `admin-api.ts`, homepage + templates page async with ISR, `TemplateGallery` accepts `adminItems` |
| 2026-05-27 | RTL fix: `globals.css` `[dir="rtl"]` block forces Vazirmatn on every text element |
| 2026-05-27 | `LogoMark` SVG component — replaces Sparkles in Navbar, Footer, DashboardSidebar; `public/favicon.svg` added |
| 2026-05-27 | OG image rebranded FlatRender with logo, feature pills |
| 2026-05-27 | Dashboard settings page: Profile, Security (pw change), Billing (plan + Stripe link), Notifications toggles |
| 2026-05-27 | Admin API: added `GET /api/auth/me`, `PATCH /api/auth/profile`, `POST /api/auth/change-password` |
| 2026-05-27 | Admin UI: Settings page (profile edit + password change), Settings link in sidebar |
| 2026-05-27 | `appsettings.Development.json.example` created for admin API local setup |
| 2026-05-27 | `CLAUDE.md` created — Claude Code auto-reads on session start |