Commit Graph

188 Commits

Author SHA1 Message Date
root 5af98633ca fix(admin-web): default media view to UGC platforms
Frontend CI / Frontend (push) Successful in 2m51s
2026-06-10 13:58:22 +08:00
root c7bad83496 feat(enterprise-site): add WordPress support and scheduled auto-publish to sites
Frontend CI / Frontend (push) Successful in 4m17s
Backend CI / Backend (push) Failing after 6m42s
Add WordPress as an enterprise-site CMS type alongside pbootcms, and let
schedule tasks auto-publish generated articles to enterprise sites.

- WordPress connection/publisher service and tests; register wordpress
  media platform and relax cms_type CHECK constraint
- New publish_enterprise_site_targets JSONB column on schedule_tasks with
  array type constraint; thread targets through scheduler dispatch,
  prompt/KOL generation, and worker
- Admin UI: enterprise-site targets in generate/schedule/publish flows,
  KOL package form, MediaView, and i18n strings

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 19:44:24 +08:00
root 41f5623791 feat: require brand description in create and update operations, add validation messages
Frontend CI / Frontend (push) Successful in 4m25s
Backend CI / Backend (push) Successful in 15m23s
2026-06-09 14:09:05 +08:00
root 7acb11c1ec refactor(enterprise-site): consolidate site panel header and actions
Backend CI / Backend (push) Failing after 13m57s
Desktop Client Build / Resolve Build Metadata (push) Successful in 27s
Deployment Config CI / Deployment Config (push) Successful in 38s
Frontend CI / Frontend (push) Successful in 5m55s
Desktop Client Build / Build Desktop Client (push) Successful in 24m25s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 34s
Merge the standalone enterprise-panel intro into the connector panel
header on the tenant media view: move the "新增站点" action into the
panel head, retitle the panel to 企业自建站点, and refresh the
description copy. Presentation-only restructuring; no logic affected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:56:30 +08:00
root aa96143754 style: format web apps with prettier and sort imports
Apply repo-wide Prettier/lint normalization across admin-web,
desktop-client and ops-web: single quotes, no semicolons, trailing
commas, consistent line wrapping, and import ordering. Also drop an
unused brand-logo import in DesktopShell.vue.

No behavior changes — formatting only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:56:18 +08:00
root a44ed21967 feat(tenant): add brand publish-records list and harden enterprise site management
- Add GET /api/tenant/publish-records: brand-scoped paginated list that merges
  in-flight (queued/publishing) records ahead of history (success/failed/cancelled),
  enriched with article title and latest desktop task id; wire up
  service/handler/router/swagger/router_test
- Rework PublishManagementView to consume publish-records instead of desktop
  publish tasks; add publishRecordsApi + shared-types
  (ListPublishRecordsParams, PublishRecordListResponse)
- Enterprise site Update: distinguish explicit null from missing PATCH fields via
  EnterpriseSitePatchString, dedup site_url before write, verify RowsAffected,
  and map unique-constraint violations to a clear conflict
- MediaView: enterprise site edit/delete flows with favicon fallback handling
- Localize enterprise site / PBootCMS error messages to Chinese across the
  backend and the admin-web error map, plus legacy raw-message translation
- deploy: gate migration-coupled service rollouts behind RUN_MIGRATIONS unless
  ALLOW_SKIP_MIGRATIONS_FOR_APP_ROLLOUT=true; handle empty SERVICES safely

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 11:40:46 +08:00
root 67be43319e feat(desktop&tenant): Enhance desktop account and task consumer presence management
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s
- Added new fields to DesktopAccountInfo for tracking account session and task consumer online status, along with queued publish task count and oldest queued publish task timestamp.
- Updated DesktopDispatchEvent to include server time for better synchronization.
- Implemented separate presence management for task consumers, including marking presence and loading presence state.
- Enhanced DesktopAccountService to apply publish queue summaries and manage task consumer presence.
- Introduced new methods for replaying queued publish tasks in DesktopDispatchHandler.
- Updated tests to cover new presence management logic and ensure correct behavior of account session and task consumer online status.
2026-06-07 19:15:20 +08:00
root 88c37e50b2 feat(enterprise-site): add PbootCMS enterprise site publisher
Frontend CI / Frontend (push) Successful in 3m57s
Backend CI / Backend (push) Failing after 6m43s
Introduce a new enterprise-site publishing channel that lets tenants push
articles to self-hosted PbootCMS sites alongside the existing media supply
flow.

Backend (server/internal/tenant):
- enterprise_site_service: CRUD, ping, category sync, and article publish
- enterprise_site_pbootcms: PbootCMS API client integration
- enterprise_site_crypto: encrypt/decrypt stored site credentials
- enterprise_site_handler + routes under /enterprise-sites
- migrations for the enterprise site publisher tables
- config: add SERVER_PUBLIC_BASE_URL (Server.PublicBaseURL) for callbacks
- article/media services adjusted to support the publish flow

Frontend (apps/admin-web):
- PublishArticleModal & ArticlePublishStatus: enterprise-site publish UI
- MediaView: manage enterprise sites and categories
- api + shared-types: enterprise site endpoints and types
- http-client: add PATCH method support

Integrations:
- pbootcms GeoPublisher controller plugin + install guide
- docs/enterprise-site-publisher-v1.md design doc
2026-06-06 13:06:14 +08:00
root d098633a67 feat(media-supply): add image upload functionality and enhance HTML handling in article processing
Frontend CI / Frontend (push) Successful in 2m51s
Backend CI / Backend (push) Successful in 19m11s
2026-06-03 15:49:01 +08:00
root 723c3ffb86 feat(media-supply): resource cache sync and order flow refinements
Frontend CI / Frontend (push) Successful in 3m38s
Backend CI / Backend (push) Failing after 26m59s
Add a resource cache sync entrypoint (RunMediaResourceSyncOnce) driven
by the new scheduler job, and rework the backlink/sync worker around it.
Tune the meijiequan client and slow the default backlink sync interval
from 10m to 30m to reduce upstream pressure.

Trim unused public/transport surface (handler + router + swagger) and
simplify admin-web order management and ops-web media-supply views,
dropping stale shared-types fields.
2026-06-02 14:50:36 +08:00
root e07a87224d feat: add new brand logos
Desktop Client Build / Resolve Build Metadata (push) Successful in 26s
Frontend CI / Frontend (push) Successful in 3m23s
Backend CI / Backend (push) Successful in 16m58s
Desktop Client Build / Build Desktop Client (push) Successful in 24m56s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 36s
- Introduced icon-color.svg featuring a colorful gradient design.
- Added icon-with-title.svg that includes a title and multiple gradient elements.
2026-05-31 23:05:27 +08:00
root d6866cd85b feat: add downloadable release management for desktop client
Frontend CI / Frontend (push) Successful in 4m1s
Backend CI / Backend (push) Failing after 8m51s
- Extend DesktopClientReleaseCheckResponse with platform, arch, and channel fields.
- Introduce DesktopClientDownloadableRelease and DesktopClientDownloadableReleaseListResponse interfaces for managing downloadable releases.
- Implement ListDownloadable method in DesktopClientReleaseService to retrieve downloadable releases based on the specified channel.
- Update DesktopClientReleaseCheckResult to include platform, arch, and channel information.
- Add resolveInstallerDownloadURL method to handle download URL resolution for releases.
- Create new endpoint in DesktopReleaseHandler for listing downloadable releases.
- Update router to include the new downloadable releases route.
- Enhance tests to cover the new functionality for resolving download URLs and listing downloadable releases.
2026-05-31 19:28:35 +08:00
root 9d6181260a feat(media-supply): add media resource supply marketplace
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
Introduce an end-to-end media-supply feature: tenant-side resource sync
service/worker backed by a Meijiequan supplier client, ops-side management
APIs, and admin/ops web views for resources, orders, favorites and
submission. Adds a shared digitocr helper, MediaSupply config blocks for
tenant and ops, shared types, and migrations for supplier media resources,
price overrides, customer visibility and order refunds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 23:17:01 +08:00
root fa52d4ca60 feat(publish): unify image fetch failure message across adapters
Deployment Config CI / Deployment Config (push) Successful in 30s
Desktop Client Build / Resolve Build Metadata (push) Successful in 17s
Frontend CI / Frontend (push) Successful in 3m35s
Backend CI / Backend (push) Successful in 16m50s
Desktop Client Build / Build Desktop Client (push) Successful in 24m2s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 30s
Consolidate per-platform cover/image fetch failure prompts into a single
PUBLISH_IMAGE_FETCH_FAILED_MESSAGE constant shared by baijiahao, bilibili,
dongchedi, qiehao, smzdm, and zol adapters, and generalize the normalizer
to match any *_image_fetch_failed / *_cover_fetch_failed code. Also split
desktop publish list loading into initial vs manual-refresh states so the
refresh button no longer blanks the table, and fix admin-web active-task
detection to cover all pending statuses.
2026-05-26 18:53:36 +08:00
root aff2c5f6ea feat(publish-dedup): disable already-published accounts and rework retry UX
In the admin publish modal, fetch the article's publish records, disable
accounts that already succeeded for the same article/platform, label
queued/publishing accounts inline, and route the success notification by
created vs existing task counts (with a dedicated warning for the
`desktop_publish_duplicate` server error).

Replace the "再次发送" mutation/popconfirm on both admin and desktop publish
management views with a "重新创建发布任务" action that calls the same Create
endpoint, only enables on failed/aborted/unknown rows, and reports created
vs existing task counts (with a tailored warning for `unknown` results
that may have already succeeded).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:43:42 +08:00
root 28e4059d66 feat(smzdm): require 1:1 cover and surface image fetch failure prompt
Add SMZDM to the cover-required platform list on both client and server,
register a 800x800 native cover spec in the admin cover catalog, and
normalize the desktop-client `smzdm_image_fetch_failed` adapter error to a
user-friendly Chinese prompt across the publisher error pipeline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:43:07 +08:00
root 05aa982f76 style(tracking-questions): normalize loose markdown in answer content
Repair detached headings, missing list/heading spaces, and pipe-only tables in
answer text before rendering, and style the markdown preview so headings,
lists, tables, and emphasis match the rest of the detail view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:18:35 +08:00
root 2c4f7d6fcf fix(brand-questions): surface seed topic min length as actionable error
Reject AI seed topics shorter than 2 characters on both client and server with
a dedicated invalid_seed_topic error code, and render an inline hint listing
the offending terms so users know exactly what to fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:18:28 +08:00
root 0b5d8d72f2 fix(brand-questions): accept generic search terms in lexicon validation
Deployment Config CI / Deployment Config (push) Successful in 27s
Frontend CI / Frontend (push) Successful in 2m53s
Backend CI / Backend (push) Successful in 16m53s
Desktop Client Build / Resolve Build Metadata (push) Waiting to run
Desktop Client Build / Build Desktop Client (push) Blocked by required conditions
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Search terms like "全屋定制" or "GEO排名优化" were rejected as invalid because
both the Vue candidate validator and the Go question_metadata classifier
required interrogative cues (什么/如何/为什么/...). Lexicon entries are search
terms, not questions, so require only letters or digits plus the existing
4-char minimum. Rename helpers to searchTermLooksValid/questionLooksValid
to reflect the looser semantics, and relabel the navigation entry from
"公司和词库" to "品牌和词库" to match the actual domain.
2026-05-24 22:19:57 +08:00
root 52997e36fe fix(content-gen): strip URLs and site-list sections from generated content
Forbid URLs/domains/markdown links across prompt rules (runtime, platform
templates, outline/imitation/title flows) and rename "官网" placeholder to
"官网信息" with explicit instructions that links are background only.
Add sanitizeGeneratedArticleMarkdown to strip URLs, HTML images, and
"网站列表/官网列表" labels from LLM output, wired into article, prompt-rule,
template, and outline generation. Drop the site_list outline section seed
and filter blocked outline keys in the wizard so stored drafts cannot
resurrect it.
2026-05-24 22:19:43 +08:00
root 946a084c77 style(admin-web): drop unused min-width on templates desktop table
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 20:24:36 +08:00
root a078dab687 fix(admin-web): remove unnecessary execution time tag from schedule section
Frontend CI / Frontend (push) Successful in 2m44s
2026-05-24 10:10:04 +08:00
root f02be451a5 fix(article-export): improve type safety for global scope in withWordExportScheduler
Frontend CI / Frontend (push) Successful in 4m0s
2026-05-24 02:09:08 +08:00
root 520cde5637 feat(word-export): enhance Word document generation with alignment options and normalization for CJK text
Frontend CI / Frontend (push) Has been cancelled
2026-05-24 02:08:52 +08:00
root 8991edabb5 feat(kol): support multiple platform hints with shared tag renderer
Frontend CI / Frontend (push) Successful in 2m47s
Backend CI / Backend (push) Failing after 6m50s
Turn the KOL prompt platform hint into a multi-select backed by the
media platforms API, persist hints as a 、-joined string, and add a
reusable KolPlatformTags component so manage/generate/package/template/
workspace views and the generate-task drawer all render the hints
consistently with truncation and overflow handling.

Also auto-select the first available subscription prompt in
GenerateTaskDrawer when switching to the subscription-prompt target so
users land on a usable option without an extra click.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 01:48:04 +08:00
root 075e282c76 feat(tracking): pass question hash/text via history state and follow URL business date
Frontend CI / Frontend (push) Successful in 3m11s
Move question_hash and question_text out of the URL query into router
history state to keep tracking question links clean, and make the
tracking dashboard's business date follow the URL/today instead of the
previously persisted localStorage value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 00:27:32 +08:00
root 0d690371d2 feat(article-copy): copy articles as rich HTML with plain-text fallback
Render markdown to sanitized HTML and write both text/html and text/plain
to the clipboard so pasted articles preserve formatting in rich editors,
falling back to selection-based copy and then plain text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 00:27:24 +08:00
root 0d2cedb1e8 feat(article-export): render PDF with embedded CJK font instead of canvas
Frontend CI / Frontend (push) Successful in 3m2s
Embed SourceHanSansSC and use native jsPDF text rendering for crisp,
selectable PDF output, replacing the canvas rasterization approach.
Also fix download menu item alignment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 00:09:38 +08:00
root c28c4f1419 feat(schedule): support KOL subscription targets and random time windows
Frontend CI / Frontend (push) Successful in 3m37s
Backend CI / Backend (push) Failing after 6m47s
Extend schedule tasks to dispatch KOL subscription prompts in addition
to prompt rules, add daily/weekly scheduling with fixed or random time
windows, and track dispatch outcomes (last run, status, consecutive
failures).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:51:45 +08:00
root 9cc6537e68 feat(article-export): enhance Word document generation with async image handling and brand ID support 2026-05-22 11:11:36 +08:00
root 56400805f4 Add article export to Word, PDF, and Markdown
Desktop Client Build / Resolve Build Metadata (push) Successful in 24s
Frontend CI / Frontend (push) Successful in 5m26s
Desktop Client Build / Build Desktop Client (push) Successful in 22m50s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 30s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 23:59:19 +08:00
root 509f9e0c71 Add AI point usage cycle cleanup
Frontend CI / Frontend (push) Successful in 2m52s
Backend CI / Backend (push) Successful in 14m11s
2026-05-20 21:59:36 +08:00
root e045e00fbf feat(auth,prompt-rule): add password change with session revocation and scope prompt rules by brand
Frontend CI / Frontend (push) Successful in 3m8s
Backend CI / Backend (push) Successful in 14m48s
Add self-service password change that re-hashes the credential and bumps a
per-user session version so all existing access/refresh tokens are rejected.
Session version is tracked in Redis with an in-memory fallback and enforced in
middleware and refresh.

Scope prompt rules and rule groups to a brand: new brand_id column (migrated to
a "未归属" fallback brand for existing rows), brand-filtered queries/indexes, and
brand-aware admin-web tabs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:09:53 +08:00
root eda90ea1e4 fix(admin-web): make article copy robust
Frontend CI / Frontend (push) Successful in 2m54s
2026-05-20 17:00:57 +08:00
root dd082e2ed1 feat: scope articles by brand 2026-05-20 15:37:25 +08:00
root 00eb514efc feat(imitation): simplify form fields and make brand_name required
Deployment Config CI / Deployment Config (push) Successful in 25s
Frontend CI / Frontend (push) Successful in 2m51s
Backend CI / Backend (push) Successful in 14m47s
Remove industry, target_audience, content_goal, tone, and length_goal from the imitation form; brand_name is now mandatory with autocomplete from brand library, keywords are pre-populated from the selected brand's search keywords, and output length is hardcoded to ~2000 characters in the prompt.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 02:16:45 +08:00
root c89cad6643 feat(keywords): rename brand-question terminology to search-keyword + add entity exclusion
- Rename UI/prompt labels: "品牌主问题" → "优化关键词", "搜索问题" → "搜索词"
- Add brand/competitor entity exclusion filter in question expansion (AI distill path)
- Refactor combination question text normalization, remove manual question-mark appending
- Update prompts to emphasize commercial-intent search queries over editorial phrasing
- Sync prompt changes across server/configs, deploy, and k3s configs
- Update i18n, frontend views (BrandQuestionCreate, TemplateWizard), and test fixtures

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 01:27:14 +08:00
root 75b407ec6b fix free create clipboard copy 2026-05-14 21:20:15 +08:00
root 765dae4bf1 fix task article link drawer
Frontend CI / Frontend (push) Successful in 5m6s
Backend CI / Backend (push) Successful in 16m45s
2026-05-14 21:14:27 +08:00
root 34dda524d7 fix(admin-web): use verb form for schedule action tooltip
Frontend CI / Frontend (push) Successful in 3m34s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:23:41 +08:00
root 01dbb9c8d3 fix(styles): increase z-index for message and notification components
Deployment Config CI / Deployment Config (push) Successful in 13s
Frontend CI / Frontend (push) Successful in 3m38s
2026-05-14 13:16:47 +08:00
root 09e3db5b34 fix(web): self-heal SPA chunk 404 after deploys
Frontend CI / Frontend (push) Has been cancelled
Port admin-web's chunk-reload guard to ops-web (vite:preloadError +
router.onError) so a stale tab landing on a lazy-loaded route triggers
a single reload instead of a hard 404. Also force index.html through
revalidation on both apps so the reload actually fetches a fresh entry
referencing the new chunk hashes; hashed asset URLs keep their long
immutable cache.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:12:42 +08:00
root 036377f02e feat(admin-web): add 404 page for unknown routes
Unknown URLs previously rendered a blank page. Add a catch-all route
under AppShell that shows the requested path plus back / workspace
actions, with zh-CN and en-US copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 11:15:09 +08:00
root 879677516f fix: harden login for MLPS requirements 2026-05-14 11:05:20 +08:00
root b3bd23e238 feat(admin-web): improve responsive admin layout
Frontend CI / Frontend (push) Has been cancelled
2026-05-13 22:29:46 +08:00
root 8890cd1ca4 style(admin-web): refine edit button hover and card shadow polish
Frontend CI / Frontend (push) Successful in 4m21s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 20:12:36 +08:00
root 0823e47d46 feat: tighten desktop presence loop and refine admin-web UX
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m46s
Backend CI / Backend (push) Failing after 7m52s
Desktop Client Build / Build Desktop Client (push) Successful in 27m13s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 59s
- Shrink desktop presence TTL to 30s and heartbeat to 15s so unexpected
  client exits surface within one TTL even if the explicit offline call
  is missed; keep migration default aligned.
- Trust a known presence miss in resolveDesktopClientOnline instead of
  falling back to the recent-heartbeat heuristic, so a still-cached
  LastSeenAt cannot mask an offline client.
- Release the runtime session before clearing renderer desktop sessions
  on shutdown to avoid leaving stale leases behind.
- Auto-refresh the MediaView account list every 5s and revamp card
  layout (inline platform badge, status tags, UID row, meta box).
- Let the brand-question AI wizard accept multiple seed topics via a
  tag-style input; candidates from each topic are merged and deduped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 19:36:24 +08:00
root 7aa786fbf4 feat(template-wizard): enhance competitor management and update UI messages
Frontend CI / Frontend (push) Successful in 3m27s
2026-05-13 17:10:31 +08:00
root 1eae6fb6d4 feat(questions): make brand questions the primary monitoring & template axis
Deployment Config CI / Deployment Config (push) Successful in 29s
Frontend CI / Frontend (push) Successful in 4m4s
Backend CI / Backend (push) Failing after 7m12s
- add /questions/combination-fill endpoint with AI-driven, IP-region-aware matrix fill
- extract ip2region resolver from ops/app into shared/ipregion for cross-service use
- thread question_id filter through dashboard composite, citation summary, and collect-now
- switch template wizard from keyword inputs to brand-question selection (primary + supplemental)
- pass brand_question and supplemental_questions through assist/title/outline prompts
- add AiWaitingModal + 45s client timeout and request_timeout error mapping for long AI flows

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:59:39 +08:00
root 37b0b32327 feat(admin-brand): add question expansion service and related functionality
- Implemented QuestionExpansionService for generating and materializing questions based on combinations and AI distillation.
- Added question metadata classification logic to infer intent and layer of questions.
- Created API handlers for question expansion operations including combination preview, AI distillation, metadata classification, and materialization.
- Introduced database migrations to support new question-related fields and constraints in brand_questions and brand_keywords tables.
- Added caching mechanism for AI distillation results to improve performance.
- Defined JSON schemas for question distillation responses to ensure data integrity.
2026-05-12 21:53:36 +08:00