# Findings & Decisions ## Requirements - User asked: "了解整个项目" — inspect and understand the whole project, then explain it clearly. - Expected output: concise but useful project map in Chinese, including purpose, stack, structure, runtime flow, commands, and notable risks. ## Research Findings - Top-level project is not a Git repository; `git status --short` returned "fatal: not a git repository". - Root contains orchestration/docs files plus a `removed extracted runtime` application directory. - `removed extracted runtime/node_modules` is present, so dependencies appear already installed for the embedded runtime app. - The initial full file scan showed many bundled media assets under `removed extracted runtime/public`, especially starter/planning/Seedance examples. - `README.md` states this was extracted from the `智念助手` desktop app into an independent `智念创作助手` project. - The project is based on an existing extracted runtime Next.js standalone runtime; original source was deleted, so this is not a full source restoration. - Root `package.json` only orchestrates scripts: `start`/`dev` call `removed runtime start script`, `health` calls `scripts/health-check.mjs`, and `info` calls `removed runtime info script`. - Runtime package uses Next `^15.1.4`, React `^19.0.0`, Supabase client, Ali OSS, lucide-react, TypeScript, Vitest, and ESLint, but it is treated as generated runtime. - Runtime state should be written to root `.runtime/`, not under `removed extracted runtime`. - `removed runtime start script` loads `.env` and `.env.local`, optionally bundled `.env.runtime` only when `ZHINIAN_LOAD_BUNDLED_ENV=1`. - Startup creates `.runtime/data`, `.runtime/uploads`, and `.runtime/generated-results`, then launches `removed extracted runtime/server.js` with `NODE_ENV=production`. - Health check targets `/api/desktop/health` and expects JSON with `appId: "removed-runtime"` and `ok: true`. - `.env.example` shows the real generation path depends on Seedance / Volcengine Ark plus Aliyun OSS configuration. - Extraction notes confirm copied assets include Next standalone server runtime, `.next` output, runtime `node_modules`, public/reference media, content manifests, and planning cases; secrets, user uploads, generated results, and Electron host/process manager code were excluded. - `npm run info` succeeded and reports runtime app id `removed-runtime`, bundle timestamp `2026-05-14T04:01:58.653Z`, entry `server.js`, and size `949,760,759` bytes. - App routes include: `/`, `/studio`, `/studio/[mode]`, `/planning`, `/projects`, `/projects/[id]`, and `/billing`. - API routes include: `/api/assets`, `/api/assets/upload`, `/api/billing`, `/api/desktop/health`, `/api/generations`, `/api/generations/[id]`, `/api/generations/[id]/retry`, `/api/projects`, `/api/projects/[id]`, `/api/prompt/assemble`, and `/api/reference-templates`. - File-serving routes expose runtime uploads and generated results via `/uploads/[...path]` and `/generated-results/[...path]`. - Creation modes currently report one mode: `video_studio` / `宣传片创作台`, editor type `storyboard_cards`. - Starter catalog has 14 cases across `storefront_avatar_storyboard`, `music_sync_ad`, and `creative_remix`; planning cases include five visible categories such as short-video promo and premium-brand. - Compiled API code reveals a local JSON store at `app-state.json` with `users`, `assets`, `projects`, `generation_jobs`, and `credit_transactions`. - The default local user is `demo-merchant` / `demo@localmerchant.ai` with 9999 demo credits. - `/api/projects` returns projects with their jobs; project creation is coupled to generation creation and deducts credits based on duration/resolution/ratio. - `/api/assets/upload` accepts multipart `file`, `role`, and optional `promptLabel`; it stores to Ali OSS when OSS env is complete, otherwise writes to local uploads and records an asset. - `/api/prompt/assemble` builds a Chinese Seedance-style video prompt from shop/project details, selected template, storyboard, and optional avatar/outfit selection. - Seedance client defaults: base URL `https://ark.cn-beijing.volces.com/api/v3`, model `doubao-seedance-2-0-260128`, ratio `9:16`, duration `15`, resolution `720p`. - Real generation creation posts to `/contents/generations/tasks`; query uses `/contents/generations/tasks/{id}`. - Missing `SEEDANCE_API_KEY` causes a user-facing error and the project/job path refunds credits after marking the job failed. - Health response includes `services.seedanceConfigured` and `services.objectStorageConfigured`. - `GET /api/generations/:id` reads a local job, polls Seedance when `provider_job_id` exists, and backs up successful result videos to OSS or local generated-results. - `POST /api/generations/:id/retry` loads the original project settings and re-runs the generation creation flow. - `GET /api/projects/:id` returns one project with jobs; `DELETE /api/projects/:id` removes the project, jobs, and related credit transactions. - `GET /api/assets` returns local assets for the demo owner; `GET /api/billing` returns demo user and credit transactions. - `GET /api/reference-templates?mode=...` returns starter templates filtered by mode. - Content definition has one canonical creation mode: `video_studio`, product name `宣传片创作台`, editor type `storyboard_cards`, reference-first workflow, and six asset slot labels. - Starter catalog contains 14 selectable templates and 85 local asset records from the Seedance guide plus local promo examples. - Template categories represented in content are `storefront_avatar_storyboard`, `music_sync_ad`, and `creative_remix`; docs say legacy mode arguments are accepted for compatibility. - Planning page content has five planning cases: `短视频宣传类`, `剧情宣传类`, `热门玩梗类`, `卡通 IP 类`, and `品质高级类`. - Avatar presets currently include one default digital-human model and one default outfit pairing. - Runtime verification passed: `npm run info` succeeded, `npm start` launched Next on `http://127.0.0.1:3000`, and `npm run health` returned `ok: true`. - Health verification reports `seedanceConfigured: false` and `objectStorageConfigured: false`, matching the empty local env configuration. - Direct curl verification with `--noproxy '*'` returned `200 OK` for `/studio`, `{"projects":[]}` for `/api/projects`, one template for `/api/reference-templates?mode=video_studio`, and the demo billing user. - Starting the runtime created `.runtime/data/app-state.json` with the demo user and initial credit transaction. ## Technical Decisions | Decision | Rationale | |----------|-----------| ## Issues Encountered | Issue | Resolution | |-------|------------| | `git status` cannot run because the project root has no `.git` metadata | Treat this as a plain project folder and avoid Git-based assumptions | | zsh treats `[id]` in file paths as a glob pattern | Quote bracketed Next.js dynamic route paths when reading them | | Initial plain `curl` calls hit a local proxy and returned 502/empty output | Use `curl --noproxy '*'` for localhost verification | ## Resources - Project root: `/Users/inmanx/Documents/zhinian-creation-assistant` - Runtime app: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime` - Root README: `/Users/inmanx/Documents/zhinian-creation-assistant/README.md` - Runtime README: `/Users/inmanx/Documents/zhinian-creation-assistant/runtime/README.md` - Startup script: `/Users/inmanx/Documents/zhinian-creation-assistant/removed runtime start script` - Health script: `/Users/inmanx/Documents/zhinian-creation-assistant/scripts/health-check.mjs` - Runtime info script: `/Users/inmanx/Documents/zhinian-creation-assistant/removed runtime info script` - Extraction notes: `/Users/inmanx/Documents/zhinian-creation-assistant/docs/EXTRACTION_NOTES.md` - App paths manifest: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app-paths-manifest.json` - Compiled projects API: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app/api/projects/route.js` - Compiled upload API: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app/api/assets/upload/route.js` - Compiled prompt assembly API: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app/api/prompt/assemble/route.js` - Compiled generation polling API: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app/api/generations/[id]/route.js` - Compiled generation retry API: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/.next/server/app/api/generations/[id]/retry/route.js` - Creation modes JSON: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/content/seedance-starter/creation-modes.json` - Starter catalog JSON: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/content/seedance-starter/catalog.json` - Planning cases JSON: `/Users/inmanx/Documents/zhinian-creation-assistant/removed extracted runtime/content/removed planning case manifest.json` - Runtime local state file: `/Users/inmanx/Documents/zhinian-creation-assistant/.runtime/data/app-state.json` ## Visual/Browser Findings - 2026-05-29 UI polish verification: - `/create`, `/create?mode=video`, `/assets`, and `/settings` were checked during the product polish work. - `375`, `768`, `1024`, and `1440` width checks showed no horizontal overflow after the compact header and mobile control changes. - The video duration dropdown on `/create?mode=video` exposes only `4 秒` through `15 秒`. - The header logo loads from `public/logo/zhinian-logo.png`; after the final branding pass it has no border, background, or box shadow. ## 2026-05-29 UI/UX and Branding Findings - The current source app is now a Web app in the repository root, not the old `removed extracted runtime` standalone-only flow described in the earliest findings. - GSAP is used through `lib/ui/motion.ts` rather than directly sprinkled across components. - The UI direction is a professional creation workspace, not a marketing landing page. - Visible English eyebrows/descriptions were removed from module headers per user preference. - Topbar should remain compact and avoid horizontal scrolling below it. - Product name is now `智念AIGC平台`. - Logo source folder: `/Users/inmanx/Documents/icon/logo`. - Current logo asset: `public/logo/zhinian-logo.png`. - Current logo was generated from `/Users/inmanx/Documents/icon/logo/2d5b992caa14db16f594c4933e92e37e.png` by removing the white background and cropping whitespace. - Avoid using the white transparent logo on the light topbar unless the topbar itself becomes dark; wrapping the logo in a dark frame changes the brand feel. ## 2026-05-29 Seedance Findings - Official Volcengine Ark "创建视频生成任务 API" docs say Seedance 2.0 `duration` supports integer seconds in `[4, 15]`, or `-1` for model-chosen duration. - Seedance 2.0 and Seedance 1.5 Pro support `adaptive` ratio behavior. - Supported ratios include `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `21:9`, and `adaptive`. - Supported resolutions include `480p`, `720p`, and `1080p`, but Seedance 2.0 fast does not support `1080p`. - `frames` is not supported for Seedance 2.0 / Seedance 1.5 Pro, so the current app should continue using integer `duration`. - `generate_audio` defaults true in the API and remains enabled in the app payload. ## 2026-05-29 Operational Findings - For localhost verification, continue using `curl --noproxy '*'` because local proxy settings can interfere with direct checks. - Before running `npm run build`, stop the dev server (`screen -S zhinian-dev-ui -X quit` and `pkill -f 'next dev --hostname 127.0.0.1 --port 3000'`) to avoid stale Next dev chunk issues. - After build verification, restart the dev server in screen session `zhinian-dev-ui` on `127.0.0.1:3000`. ## 2026-05-29 Deployment Findings - Server one-command deployment is now `bash scripts/deploy.sh`. - Docker Compose service name is `zhinian-aigc`. - Docker Compose defaults to exposing host port `3000`; set `APP_PORT` in `.env.local` or shell to change it. - `NEXT_PUBLIC_APP_URL` should be set to the public domain or server URL in production so generated local file URLs are correct. - Persistent runtime data is bind-mounted through `./.runtime:/app/.runtime`; this folder should be backed up on real servers. - `.env.local` is intentionally used as the compose `env_file` and remains ignored by Git. - Current local machine does not have the Docker CLI available, so Docker build was not run here; script syntax, app tests, production build, and local health were verified instead. ## 2026-05-29 Public API and Task Management Findings - User confirmed multi-task support should be task management logic, not an external message queue. - Public API v1 now uses `ZHINIAN_API_KEYS`, supporting `Authorization: Bearer ` and `X-Zhinian-Api-Key`. - Task creation and provider execution are now split: submit routes enqueue `GenerationJob` records; Worker ticks claim and process jobs. - `generation_jobs` now carries external client, idempotency, priority, attempts, lock, schedule, timing, and webhook fields. - Supabase/Postgres production mode expects the `claim_generation_jobs` function from `supabase/schema.sql` for atomic task claiming. - Local JSON mode serializes task claiming through the existing local write queue and is intended for single-instance development. - Worker execution can run as `npm run worker`, `npm run worker:once`, or the `zhinian-worker` Docker Compose service. - Internal Worker processing goes through `/api/internal/worker/tick` protected by `ZHINIAN_INTERNAL_WORKER_TOKEN` in production. - API v1 routes are `/api/v1/capabilities`, `/api/v1/assets`, `/api/v1/jobs`, `/api/v1/jobs/:id`, `/api/v1/jobs/:id/cancel`, and `/api/v1/openapi.json`. - Local verification created a public API job and processed it to `succeeded` through `npm run worker:once` in mock mode.