19 KiB
19 KiB
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 --shortreturned "fatal: not a git repository". - Root contains orchestration/docs files plus a
removed extracted runtimeapplication directory. removed extracted runtime/node_modulesis 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.mdstates 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.jsononly orchestrates scripts:start/devcallremoved runtime start script,healthcallsscripts/health-check.mjs, andinfocallsremoved 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 underremoved extracted runtime. removed runtime start scriptloads.envand.env.local, optionally bundled.env.runtimeonly whenZHINIAN_LOAD_BUNDLED_ENV=1.- Startup creates
.runtime/data,.runtime/uploads, and.runtime/generated-results, then launchesremoved extracted runtime/server.jswithNODE_ENV=production. - Health check targets
/api/desktop/healthand expects JSON withappId: "removed-runtime"andok: true. .env.exampleshows the real generation path depends on Seedance / Volcengine Ark plus Aliyun OSS configuration.- Extraction notes confirm copied assets include Next standalone server runtime,
.nextoutput, runtimenode_modules, public/reference media, content manifests, and planning cases; secrets, user uploads, generated results, and Electron host/process manager code were excluded. npm run infosucceeded and reports runtime app idremoved-runtime, bundle timestamp2026-05-14T04:01:58.653Z, entryserver.js, and size949,760,759bytes.- 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 typestoryboard_cards. - Starter catalog has 14 cases across
storefront_avatar_storyboard,music_sync_ad, andcreative_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.jsonwithusers,assets,projects,generation_jobs, andcredit_transactions. - The default local user is
demo-merchant/demo@localmerchant.aiwith 9999 demo credits. /api/projectsreturns projects with their jobs; project creation is coupled to generation creation and deducts credits based on duration/resolution/ratio./api/assets/uploadaccepts multipartfile,role, and optionalpromptLabel; it stores to Ali OSS when OSS env is complete, otherwise writes to local uploads and records an asset./api/prompt/assemblebuilds 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, modeldoubao-seedance-2-0-260128, ratio9:16, duration15, resolution720p. - Real generation creation posts to
/contents/generations/tasks; query uses/contents/generations/tasks/{id}. - Missing
SEEDANCE_API_KEYcauses a user-facing error and the project/job path refunds credits after marking the job failed. - Health response includes
services.seedanceConfiguredandservices.objectStorageConfigured. GET /api/generations/:idreads a local job, polls Seedance whenprovider_job_idexists, and backs up successful result videos to OSS or local generated-results.POST /api/generations/:id/retryloads the original project settings and re-runs the generation creation flow.GET /api/projects/:idreturns one project with jobs;DELETE /api/projects/:idremoves the project, jobs, and related credit transactions.GET /api/assetsreturns local assets for the demo owner;GET /api/billingreturns 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 typestoryboard_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, andcreative_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 infosucceeded,npm startlaunched Next onhttp://127.0.0.1:3000, andnpm run healthreturnedok: true. - Health verification reports
seedanceConfigured: falseandobjectStorageConfigured: false, matching the empty local env configuration. - Direct curl verification with
--noproxy '*'returned200 OKfor/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.jsonwith 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/settingswere checked during the product polish work.375,768,1024, and1440width checks showed no horizontal overflow after the compact header and mobile control changes.- The video duration dropdown on
/create?mode=videoexposes only4 秒through15 秒. - 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 runtimestandalone-only flow described in the earliest findings. - GSAP is used through
lib/ui/motion.tsrather 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.pngby 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
durationsupports integer seconds in[4, 15], or-1for model-chosen duration. - Seedance 2.0 and Seedance 1.5 Pro support
adaptiveratio behavior. - Supported ratios include
16:9,4:3,1:1,3:4,9:16,21:9, andadaptive. - Supported resolutions include
480p,720p, and1080p, but Seedance 2.0 fast does not support1080p. framesis not supported for Seedance 2.0 / Seedance 1.5 Pro, so the current app should continue using integerduration.generate_audiodefaults 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 quitandpkill -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-uion127.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; setAPP_PORTin.env.localor shell to change it. NEXT_PUBLIC_APP_URLshould 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.localis intentionally used as the composeenv_fileand 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, supportingAuthorization: Bearer <key>andX-Zhinian-Api-Key. - Task creation and provider execution are now split: submit routes enqueue
GenerationJobrecords; Worker ticks claim and process jobs. generation_jobsnow carries external client, idempotency, priority, attempts, lock, schedule, timing, and webhook fields.- Supabase/Postgres production mode expects the
claim_generation_jobsfunction fromsupabase/schema.sqlfor 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 thezhinian-workerDocker Compose service. - Internal Worker processing goes through
/api/internal/worker/tickprotected byZHINIAN_INTERNAL_WORKER_TOKENin 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
succeededthroughnpm run worker:oncein mock mode. - Public API asset access now includes
/api/v1/assets/:idand/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 indocs/API.md.
2026-05-29 Image Tuning Findings
- Jimeng image generation supports the current
scaleparameter, 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 EvoLinkqualityinstead. - Current local
/api/healthreportsimage.generateusing EvoLink, so/createshould show生成质量options rather than文本影响.
2026-05-29 Account Login / SSO Findings
- User requested account login before release so the project is safe to use.
- Provided SSO guide recommends OAuth2 Authorization Code for Web SSO: redirect to
${AUTH_BASE}/oauth2/authorize, receivecodeandstate, then exchange code server-side at${AUTH_BASE}/oauth2/token. - OAuth client defaults in the guide use
client_id=customPCandscope=server;client_secretmust stay on the server. - Access tokens are JWTs; resource services should verify locally with JWKS from
${AUTH_BASE}/oauth2/jwksrather than calling auth on every request. - Minimum JWT checks from the guide: RS256 signature,
exp,nbf/iat, issuerhttps://pig4cloud.com, OAuth client id, scope/authority requirements. - Logout endpoint is
DELETE ${AUTH_BASE}/token/logout, but local session deletion remains required because existing JWTs may stay valid untilexp. - Current app has no login middleware or session helper; pages are client components under a global shell.
- Current local data store defaults all assets/jobs to
DEFAULT_OWNER_ID = "demo-merchant", so account login must also address per-user owner IDs for first-party UI APIs. - Public API v1 already has separate API key auth through
ZHINIAN_API_KEYS; SSO should preserve that server-to-server surface. - First-party UI APIs that currently need session ownership include
/api/assets,/api/assets/upload,/api/assets/:id/*,/api/generations/image*,/api/generations/video*, and/api/settings. - Generation services already accept optional
ownerId, so route handlers can pass the authenticated owner without rewriting provider dispatch or worker logic. - Retry helpers currently preserve the original request payload; they need to override
ownerIdon retry so a user cannot retry another user's job if they know the id. /uploads/*and/generated-results/*serve local runtime files directly; middleware should protect these paths for cookie-authenticated browser sessions./api/v1/*and/api/internal/worker/tickmust remain outside browser SSO middleware because they use API keys and worker tokens.- Implemented browser SSO with signed HttpOnly
zhinian_sessioncookies; middleware validates the signed session instead of exposing JWTs to client JavaScript. - JWT access tokens are verified in the callback using RS256 and configured JWKS, with issuer, client id, expiry, not-before, issued-at, and scope checks.
- Local file routes now resolve
storagePathback to an asset record and require the current owner to match before serving bytes. - Public API v1 remains API-key based and can still read/download its assets through public API routes even when browser SSO protects the Web UI.
2026-05-29 Password Captcha Login Findings
- User provided live auth configuration and a password grant sample; real secret values remain only in the ignored local environment file.
${AUTH_BASE}/code/image?randomStr=...returns a PNG captcha image.- The password grant sample successfully returns a JWT access token, refresh token, expected client/user claims, tenant id, and
serverscope. - The local
/api/auth/passwordendpoint verified the returned JWT with JWKS and created a signed browser session for the authenticated user. - Browser form login with the displayed math captcha succeeded and redirected to
/create; the topbar showed the authenticated username and logout button. - Logout cleared the session and returned to
/auth/login?loggedOut=1.
2026-05-29 Standalone Login Page Findings
- Login routes under
/auth/*should not render the shared app topbar; the login page is a standalone entry surface. - The login page now intentionally presents only the NIANXX logo,
智念AIGC平台, and the account/password/captcha form. - The visible
统一认证中心OAuth entry was removed from the login page after user feedback. - The standalone login page uses the existing GSAP motion helper layer (
runScopedMotion,revealChildren,pulseFeedback) for consistent app motion. - Browser viewport checks passed at 1280x800 and 390x844: no topbar, no SSO link text, logo and platform name present, login panel present, and no horizontal overflow.