36 KiB
36 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.
2026-06-09 Repository and Runtime Status Findings
- The current repository root is a Git checkout on
maintrackingorigin/main. - The remote is
https://git.nianxx.cn/wangxuming/NianAIGC.git. - The workspace was overwritten from remote and is currently clean at
d98e58a docs: update public api docs. - The project uses npm (
package-lock.json) and Next.js dev startup throughnpm run dev. - Local Node version during verification was
v22.22.1, satisfying thepackage.json>=20engine. - During startup verification, ports
3000,3001, and3002were already occupied by local Node/Next processes or listeners; use a confirmed-free alternate port rather than assuming3000. npm run dev -- --hostname 127.0.0.1 --port 3003successfully started the current project and reached Next Ready in 2.9 seconds.- A smoke request to
http://127.0.0.1:3003/returned307 Temporary Redirectto/auth/login?next=%2F, confirming the login-protected app flow. - Current status check on 2026-06-09 found no
next dev/next-serverprocess and no listener on3003; the project is verified startable but not currently running.
2026-07-01 Account ID Partitioning Findings
- First-party browser APIs already pass the authenticated session user id into asset and generation flows.
- Public API v1 currently authenticates by
clientId:key, but jobs and assets are still created withownerId = DEFAULT_OWNER_ID. - Public API listing/detail access filters with
externalClientIdandapi-client:<clientId>tags, which works as an access check but keeps all API account data in one default owner partition. - The data store and Supabase schema already support
owner_idindexes and idempotency uniqueness by(owner_id, external_client_id, idempotency_key), so the change can be made by deriving a stable account owner id from the API client id. - Job detail and cancel routes currently check only
externalClientId; they should also require the account owner id so a client id collision cannot cross account partitions. - Implemented owner derivation as
publicApiOwnerId(client), yieldingapi:<sanitizedAccountId>. - Public API job creation, idempotency lookup, job listing/detail/cancel, asset upload/register/list/detail/download now use the derived API account owner.
- Documentation now states that
ZHINIAN_API_KEYSuses账号ID:keyand that records are partitioned underapi:<账号ID>.
2026-07-01 Password Login Captcha Finding
origin/mainis up to date atd98e58a; relevant history includesce358df 修改认证中心对接方式and288e31d 移除验证码输入框.- Current
components/auth-login-panel.tsxdoes not render captcha controls and submits onlyusername,password, andnext. - Current
app/api/auth/password/route.tsno longer requires captcha; it only forwardscodeandrandomStrif they are present in the request body. - Current local
.env.localpoints password login athttps://onefeel.brother7.cn/ingress/authwith client idcustomPC. - A local login probe with fake credentials returned
验证码不能为空; a direct token request to the configured auth center with the same non-secret dummy credentials also returned验证码不能为空. - Therefore the observed captcha error is coming from the configured auth center instance, not from the current AIGC frontend or password route validation.
- The operations SSO guide defaults external projects to OAuth client
app/app, recommends adding token-flow clients tosecurity.ignore-clients, and notescustomPCis a special platform-user compatibility client that skips AES password decrypt. - Dummy token probes showed
app/appreaches normal credential validation (用户名或密码错误) whilecustomPCis intercepted by captcha validation on the current auth center instance. - Updated the project defaults, docs,
.env.example, and local.env.localto useapp/appplusZHINIAN_AUTH_PASSWORD_ENC_KEY=thanks,pig4cloud. - After restarting the dev server, local
/api/auth/passwordwith dummy credentials returns用户名或密码错误, confirming the captcha interception is bypassed for the configured client.
2026-07-01 Internal RBAC / Account Management Findings
- Initial requested guide
/Users/inmanx/Desktop/organization-external-api.mdwas missing; updated guide/Users/inmanx/Desktop/organization-external-api(1).mdis available and has 1310 lines. - Existing JWT session already stores
authoritiesandscopeonAuthUser, making it suitable for internal RBAC. - Before the RBAC change, navigation exposed
创作,结果,日志, and设置to every logged-in user. - Before the RBAC change, middleware only checked whether a user was authenticated and did not distinguish ordinary users from administrators.
- Before the RBAC change,
/api/settingscheckedrequireAppUser()but not admin permission. - Before the RBAC change,
/api/logsrelied on middleware authentication only and did not callrequireAppUser()or admin checks inside the route. - RBAC now hides admin navigation for ordinary users and protects
/logs,/settings,/accounts,/api/logs,/api/settings, and/api/admin/*. - Updated guide covers organization, department, role, member, and enterprise user operation APIs.
- Organization/member APIs are served by
basic-capability-services-biz; enterprise user management APIs are exposed byhotel-staff-server-biz. - Member list APIs remain
@Innerand require headerfrom: Y. - Enterprise user APIs require
Authorizationand a token with administrator role1; otherwise they return仅管理员角色允许调用. - Account creation should use
/adminOrganization/organizationMember/addOrganizationMemberAndCreatePlatformUserto create the enterprise user and bind the organization member in one call. - Password maintenance is available through
/adminPcUser/resetPlatformUserPassword, withtenantId, numericuserId,newPassword, and optionalmustChangePassword. - Updated
/Users/inmanx/Desktop/organization-external-api(2).mdconfirms the external member list path is/adminOrganization/organizationMember/organizationMemberListthroughhotelStaff; only the basic service internal/organizationMember/organizationMemberListpath needsfrom: Y. - The updated
hotelStaffmember-list proxy is reachable from the app, but the current login token can still be rejected by the upstream service with仅管理员角色允许调用. - Local RBAC allow-listing
ceshiopas a platform admin only controls this app's pages and APIs; it does not grant upstreamhotelStaffadministrator role1inside the authentication center token. - Account management now treats upstream member-list administrator denial like a recoverable member-list-only limitation: the page can still load configured organization data and keep account creation/password maintenance available when those upstream endpoints allow the token.
- The updated organization guide exposes department creation at
POST /organizationGroup/createOrganizationGroupwithorganizationId,groupName, optionalgroupDesc, and optionalparentId. - The account page can create a department from the member form and then refresh/select the created department, so admins do not need to leave account management before creating members.
2026-07-02 Image Template Findings
- User requested image-generation templates with selection-time effect preview and preset prompt support.
- This should be account-managed data, not global environment configuration.
- Existing browser image generation API already uses
requireAppUser()and submitsownerId: user.id, so template APIs should use the same owner boundary. - Template configuration should remain inside the image generation module rather than the global settings page.
- The create page already keeps image/video prompt state client-side, detects the active image engine from
/api/health, and submits prompt, materials, size, force-single, and engine-specific tuning to/api/generations/image. - Implemented image templates with fields for name, category, description, preset prompt, preview image URL, width/height, force-single, and sort order.
- New first-party routes are
/api/image-templatesand/api/image-templates/:id; both require the app user and use the authenticated user id as owner id. - Local JSON state now normalizes
imageTemplates; Supabase deployments need the newimage_templatestable fromsupabase/schema.sql. - Browser verification used a temporary auth-disabled dev server to create one demo template, confirm the
/createleft template rail and template application behavior, then deleted the demo template. - Final dev server was restarted with the normal
.env.localauth-enabled environment on127.0.0.1:3001.
2026-07-02 Large Auth Session Finding
- A new real account could receive a successful
/api/auth/passwordresponse and still be redirected back to/auth/login?next=/create, which indicates the browser did not persist a valid session rather than an upstream password failure. - The session cookie stores the signed session plus access token so the app can forward the current login token to organization/staff APIs.
- Accounts with larger JWT or authority payloads can exceed a single browser cookie's practical size limit; splitting
zhinian_sessioninto chunked cookies keeps the same signed payload while allowing middleware and server helpers to reassemble it. - Settings no longer exposes a template tab.
- In image mode,
/createnow renders a left vertical模板选择rail with an icon添加模板button and thumbnail/name-only template cards. - The add-template entry opens an in-module template form modal; it is not exposed from settings.
- Clicking a template selects it and brings its preset prompt, image size, and force-single value into the generation console on the right.
- Desktop and narrow browser verification confirmed the template picker is an independent left-side panel beside the generation panel, not a child of the generation panel, with no horizontal overflow.
- The image/video/edit mode switch is now contained by the generation panel, not placed above or across the far-left template module.
- Template preview image upload now uses the same
/api/assets/uploadroute as workbench materials, so configured OSS storage is reused instead of accepting a manually typed preview URL. - New template configuration no longer exposes category or remark fields; the user-facing free text field is
简介, backed by the existing template description data. - Template preset prompts can contain
@图片1style placeholders. The generation console parses those tokens and shows missing upload slots below the prompt. - Placeholder upload slots bind the uploaded asset to the exact requested token, so clicking the
@图片2slot creates/updates the@图片2material instead of relying on upload order. - Material labels are preserved after removal to avoid silently breaking prompt references created by templates.
- UI/UX skill guidance for the add-template modal was applied as a focused SaaS workspace form: strong preview region, fewer visible decisions at once, clear bottom actions, and responsive stacking on narrow screens.
- While editing a template prompt, parsed placeholder chips are shown below the textarea so users can confirm which upload slots the template will request after selection.
- Image templates now store the target image generation engine in
settings.engine, with Jimeng usingsettings.scaleand Image2/EvoLink usingsettings.quality. - First-party image generation now accepts a per-request
engineoverride and passes it intosubmitImageJob(), so template engine choices are honored by the provider payload. - The generation console exposes the current image engine selector; applying a template updates this selector plus the matching parameter control.
- Material placeholders now require an explicit number, so
@图片1and@图2create upload slots while bare@图片or@图片这种普通文字stay plain prompt text. - Template prompt editing includes explicit placeholder insertion controls for image/video/audio slots, making the placeholder confirmation action deliberate instead of relying on unfinished
@typing. - Existing image templates can be reopened from the top-right edit action on each template card and saved through the account-scoped PATCH route.
- The template rail is intentionally wider on desktop and each card separates image preview, template selection, and template editing into distinct controls.
- Clicking a template thumbnail opens a larger preview dialog; choosing from that dialog applies the template and closes the preview.
- Typing
@in prompt editors now opens a temporary material draft slot instead of immediately writing a partial token into the prompt body. - A material draft is confirmed into the prompt only by Enter or explicit option selection; confirmed values are inserted with text boundaries so subsequent Chinese text is not absorbed into the token.
- The temporary draft slot is shared by the generation prompt and template preset prompt; invalid text such as
图片这种普通文字stays in the slot and does not create upload requirements. - Confirmed numbered tokens keep using the existing visual token overlay, placeholder chips, and missing upload-slot UI.
- The temporary material draft slot should remain visually inside the prompt editor surface, not below the input, so
@entry feels like an inline editing affordance. - Template preset prompts use the same token overlay as the generation prompt; confirmed placeholders such as
@视频1are visibly colored inside the input area before saving the template. - The image template rail now uses a wider desktop/tablet track (
390-480pxdesktop,315-375pxtablet) and stacks above the generation panel on mobile so reference previews stay browseable. - Template thumbnails use a
4:3viewport with contained images, allowing both9:16and16:9reference images to be inspected without cropping. - Template card application now requires the explicit
选择模板button; thumbnail clicks open preview and template name/description text no longer selects the template. - The template rail remains visible in image and video generation modes; only the image-editing modes (
局部重绘,智能超清) use the standalone editor layout without the template rail. - Template cards are fixed compact items (
138px x 184px) inside the rail list, so each template has a consistent smaller footprint. - The template rail height is synchronized from the right generation panel through a
ResizeObserver; the rail body is split into fixed header/action rows and a scrolling template-list row. - The scrollbar belongs only to
.image-template-rail-list;模板选择and添加模板stay outside the scroll container. - Template rail cards now use their preview image as a full-bleed card surface with
object-fit: cover. - Template card title, intro, and select action sit inside a bottom floating frosted-glass overlay; the select button remains the only action that applies the template.
- The zoom icon was removed from template cards, while the edit icon remains on the top-right corner above the image.
- Selected template cards use a heavier layered shadow and slight upward transform to create stronger depth.
- The template intro/description field is no longer part of the create/edit template UI or card display; old stored descriptions may still exist in data but are ignored by this surface.
- The template edit icon now sits inside the card's frosted-glass overlay instead of on the image corner.
- Template selection is a toggle: the first click captures the current right-side image generation state and applies the template; clicking the selected template again restores that snapshot and clears the active template state.
- The compact full-bleed template card target is
132px x 176px; the widened desktop rail should fit three cards per row. - The card footer uses a two-row frosted-glass grid: title spans the first row, while the select/cancel button and edit icon share the second row to avoid cramped text or overlap.
2026-07-02 Create Task Module Findings
- The creation console can reuse existing first-party APIs for a task list:
/api/generations/image,/api/generations/video, and/api/assets. GenerationJobalready has the needed task fields: prompt/name fallback, status, created/updated timestamps, capability, and output asset ids.- Generated task thumbnails can be resolved by mapping
GenerationJob.outputAssetIdsto assets from/api/assets; queued/running tasks need a placeholder when no output asset exists yet. - The existing results page already has a task view and detail panel, so the create-page
查看详情action deep-links to/assets?view=tasks&taskId=<id>instead of creating a separate task page. - Desktop create layout now supports three independent modules: left template rail, center generation console, and right task module. At narrower widths the task module drops below the main modules, and at mobile widths all modules stack without horizontal overflow.
- The right task module now targets
560-640pxon desktop/wide screens so task name, status, elapsed time, and查看详情can stay on one horizontal row. - Queued/running jobs without output assets should render a clear
生成中thumbnail placeholder instead of a generic empty asset icon. - Completed image-task thumbnails are preview actions inside
/create; clicking them opens the same large asset-preview surface while查看详情remains the route to the full task page.