Commit Graph

166 Commits

Author SHA1 Message Date
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
root 77f3e5ee99 perf(admin-web): relax template wizard assist poll cadence to 3s
Polling analyze/title/outline task results every 1.2s was over-eager
for AI tasks that typically run 15-30s. Bump interval to 3s and lower
max attempts to 40, extending total timeout from 72s to 120s while
roughly halving request volume.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 12:32:06 +08:00
root 51d32fa96d fix(admin-web): invalidate workspace cache after every AI-points-consuming call
Top-nav quota chip (会员到期 / 生成文章 / AI 点数) only refreshes when its
query is invalidated. Several mutations and stream-based flows that debit
points or article quota on the server were not invalidating it, so users
had to refresh the page to see updated balances.

- TemplateWizardView: invalidate `['workspace']` inside `endAssistTask()`,
  covering analyze / title / outline assist tasks in one place.
- FreeCreateView: invalidate after `articlesApi.create` success.
- GenerateTaskDrawer: add `['workspace']` to the instant-generate
  `Promise.all` alongside the existing `articles` / `instantTasks` keys.
- KolPromptEditor: invalidate in the `finally` of both `runAiAssistStream`
  (generate) and `generateSelectionAiPreview` (optimize) so abort / error
  paths also refresh.
- ArticleEditorCanvas: bring in `useQueryClient` and invalidate in the
  selection-optimize stream `finally`.

Together with the existing invalidations in TemplateWizard.generate,
ImitationGenerate, KolGenerate, and article-regenerate, every quota-
debiting call site now feeds the cache refresh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:54:12 +08:00
root b6cc12cefe feat(admin-web): show centered modal in Chinese when AI points are insufficient
- Add `ai_points_insufficient` / `ai_points_unavailable` Chinese mappings in
  errors.ts so the toast copy is localized.
- Add `showAiPointsInsufficientModal()` helper that renders a centered
  `Modal.confirm` with localized title/body and a "查看点数明细" action that
  routes to `/account/ai-points`. The helper is debounced so concurrent
  failed requests do not stack multiple modals.
- Trigger the modal globally from the admin-web response interceptor when
  the backend returns `ai_points_insufficient`, so every AI-generating
  endpoint surfaces the same prominent prompt without per-callsite changes.
- Drop the English `detail` for ai_points_insufficient in `formatError` so
  the secondary toast stays pure Chinese.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:31:02 +08:00
root 635782041a feat(admin-web): preserve template wizard entry source and refresh AI banner
- Carry `from=workspace` query from the workbench into the wizard so cancel
  and post-generate redirects return to the workbench instead of always
  landing on /articles/templates.
- AppShell now resolves an effective navKey from `route.query.from`, so the
  sidebar highlight and breadcrumb track the entry source while inside the
  wizard.
- Redesign the brand-info AI analyze CTA into a standalone banner with
  template-aware copy (default / product_review / research_report) and add
  the matching i18n keys.
- Drop the unused 批量生成文章 button and its styling from the templates
  page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:12:01 +08:00
root 18011a7892 fix(admin-web): auto-reload on stale dynamic-import chunks after deploy
Listen for vite:preloadError and router onError, force a one-shot reload
(10s cooldown via sessionStorage) when a hashed lazy-loaded module 404s
because a new deploy replaced it. Eliminates the user-visible "Failed to
fetch dynamically imported module" error on login and route navigation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 17:47:51 +08:00
root 6fa9a6c052 feat(dongchedi): translate platform "server exception" into actionable copy
Map dongchedi adapter failures (raw "server exception" or
dongchedi_platform_exception) to a Chinese prompt steering the user to
the dongchedi backend, so renderer/admin views and desktop-task error
payloads no longer surface the opaque platform message.
2026-05-11 12:26:38 +08:00
root f34c6f2ceb feat(admin-web): surface generation error message and speed up active polling
Hoists hasActiveGenerationStatus into the shared display helper so all
views agree on what counts as in-flight generation, shows the backend
generation_error_message inline on the imitation list and detail drawer
when status is failed, and drops the workspace/templates/imitation poll
interval from 10s to 3s (with a 5s fallback when streaming is enabled)
plus explicit query-cache invalidation so failed/completed states show
up promptly.
2026-05-11 11:11:40 +08:00
Xu Liang 1082e9010e feat(admin-web): add collapsible metadata section with toggle functionality
Frontend CI / Frontend (push) Successful in 4m9s
2026-05-09 09:40:17 +08:00
root 3102e261ae feat(admin-web): use real platform logos in publish queue table
Frontend CI / Frontend (push) Successful in 9m6s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 23:20:31 +08:00
root 1e6ed77453 fix(yuanbao): track new hunyuan_t1 SSE protocol and align inline citations with DeepSeek
- findInteractiveByText now also accepts elements carrying business
  attributes [dt-button-id]/[data-button-id]. The new yuanbao toolbar
  renders the deep-think toggle as <div dt-button-id="deep_think"> rather
  than a <button>, so the previous text-only locator missed it and probes
  silently ran in the fast model — without inline citations.
- Lower <div data-idx-list="1,2,10"> placeholders to bare "[1][2][10]"
  (previously "[citation:1] [citation:2] [citation:10]") and accept both
  forms in YUANBAO_CITATION_MARKER_PATTERN. Final answer text runs through
  normalizeCitationMarkers so any residual SSE [citation:N] is rewritten
  to [N], matching DeepSeek's chip rendering on the SaaS side.
- searchGuid frames in the new protocol carry every reference inside
  docs[] (each with a 1-based index that mirrors the answer markers) and
  citations is now always null. Promote docs into the citations bucket so
  citations[index-1] aligns with the inline marker, eliminating the
  spurious yuanbao_incomplete_citations failures.
- Update the SaaS detail view: createYuanbaoCitationPattern accepts both
  "[N]" and "[citation:N]" so yuanbao answers render the same clickable
  superscript chips as DeepSeek.

Tests cover the new searchGuid.docs alignment, fast-cache answers (no
markers, no sources -> still succeed), legacy [citation:N] -> [N]
rewriting, and mixed-format marker extraction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 21:51:24 +08:00
root af35301d9b test(desktop): cover deepseek account name extraction for wechat + phone logins
Desktop Client Build / Resolve Build Metadata (push) Successful in 28s
Frontend CI / Frontend (push) Successful in 4m5s
Backend CI / Backend (push) Successful in 17m7s
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Refactor readDeepseekAccountIdentity so the JSON payload parser is a pure
ts function (extractDeepseekIdentityFromPayload). The webContents IIFE now
just polls for userToken and returns the raw API JSON; payload picking lives
in ts and is unit-tested.

Tests lock the contract for both login types we observed in the wild:
  - WeChat-bound account: id_profile.name = '阿白', picture present.
  - Phone-only login: id_profile = null, mobile_number = '177******08',
    email = '' (empty string, not null) — the case that originally regressed.

Plus regressions for the priority order (profile.name > mobile_number > email),
the all-empty fallback, and non-record payloads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:02:57 +08:00
root e54efdacee fix(knowledge): enforce upload type and size limits on client
Why: 添加知识库弹窗只在 hint 文案里写了「docx/pdf/txt/md/xls/xlsx,<=30M」,
beforeUpload 没做校验,用户可以提交任意大小、任意格式的文件后再被后端拒绝。
现在前端按白名单扩展名 + 30MB 阈值拦截,并给 dragger 加 accept 让系统选择器
默认过滤非法格式。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 18:42:14 +08:00
root 0a7b216513 fix(knowledge): refresh inflight items and skip empty chunked groups
Poll the knowledge item list every 5s while any item is still pending
or processing so the UI reflects ingestion progress without manual
refresh, and exclude items that have no active chunks from group
counters so groups with no usable content do not appear populated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:08:03 +08:00
root 7443bb3260 feat(templates): confirm before leaving wizard with draft content
Intercept route changes and tab close when the template wizard has
unsubmitted content so users can save a draft, discard, or stay instead
of silently losing their progress.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:07:51 +08:00
root c1e7c5e90c feat(publish): add tenant publish management with desktop deep-link
Expose tenant-authenticated publish task list and retry endpoints so the
admin web can show desktop publish state without an Electron bridge, and
register a `shengxintui://` deep-link so the page can hand off to the
desktop client workbench.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:07:28 +08:00
root 7d82c5c193 feat(article): support regenerating failed articles 2026-05-07 10:55:44 +08:00
root ff2bb77cdd fix(web): suppress duplicate toasts when auth session expires
Desktop Client Build / Resolve Build Metadata (push) Successful in 32s
Frontend CI / Frontend (push) Successful in 4m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Mark 401/refresh-failure errors as handled so per-view catch blocks fall
through silently while a single global "登录已过期" warning is shown.
Centralize ops-web error rendering via showOpsError.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:12:29 +08:00
root e3c0fe98d7 refactor(admin-web): tighten publish modal status display
Frontend CI / Frontend (push) Successful in 2m29s
Backend CI / Backend (push) Successful in 13m51s
Move publish-state pill next to account name, surface device name in the
client-status tag with truncation + tooltip, and switch the card click
target from disabled to aria-disabled so tooltips remain interactive.
Also disable the keyword selector in the brand question form to prevent
mid-edit reassignment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 13:42:58 +08:00
root f6aed87e44 chore: enable ws proxy in admin-web dev server and log compliance recheck failures
- admin-web vite dev server now proxies websockets on /api so live
  features (e.g. SSE/WS) work in development.
- Tenant desktop publish compliance recheck now logs warnings when the
  query, scan or row iteration fails so the silent 50118 errors can be
  diagnosed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 12:57:03 +08:00
root 3c912949e4 fix client IP handling behind proxies
Deployment Config CI / Deployment Config (push) Successful in 27s
Frontend CI / Frontend (push) Successful in 3m2s
Backend CI / Backend (push) Successful in 14m8s
2026-05-05 23:01:25 +08:00
root 337bb6f9ac feat(publish): enhance compliance feedback and UI elements in PublishArticleModal
Deployment Config CI / Deployment Config (push) Successful in 28s
Backend CI / Backend (push) Successful in 14m8s
Frontend CI / Frontend (push) Failing after 2m1s
2026-05-05 21:01:11 +08:00
root 745cdd79cf feat(compliance): add content compliance detection across tenant, ops, and clients
Implements the Revision 8/9 compliance design: tenant + ops backends, ops-web
content-safety pages, admin-web editor/publish gate integration, desktop publish
block surfacing, and supporting migrations / shared types / config plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:48:14 +08:00