Files
NianAIGC/findings.md
2026-05-29 14:32:02 +08:00

144 lines
15 KiB
Markdown

# 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 <key>` 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.
- Public API asset access now includes `/api/v1/assets/:id` and `/api/v1/assets/:id/download`.
- Uploaded and generated assets created through public API flows are tagged as `api-client:<clientId>` so integrations can query and download their own results later.
- OpenAPI is generated dynamically from the current deployment origin at `/api/v1/openapi.json`.
- Operations handoff docs live in `docs/DEPLOYMENT.md`; partner API docs live in `docs/API.md`.
## 2026-05-29 Image Tuning Findings
- Jimeng image generation supports the current `scale` parameter, so UI presets should submit numeric text-influence values for that engine.
- EvoLink image generation does not use Jimeng `scale`; the per-request engine-aware control should submit EvoLink `quality` instead.
- Current local `/api/health` reports `image.generate` using EvoLink, so `/create` should show `生成质量` options rather than `文本影响`.