Commit Graph

499 Commits

Author SHA1 Message Date
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 24dd832218 feat(publish-dedup): reject duplicate publish jobs and expose target task ids
Build a per-target dedup_key (tenant/workspace/article/platform/account) on
publish job creation, take an xact advisory lock on the keys, look up
already-active publish_records via the payload index, and skip creating
duplicate desktop_tasks. Surface created vs existing task ids on
CreatePublishJobResponse (and shared-types) so callers can tell the
difference, return `desktop_publish_duplicate` on unique-constraint races,
and expose desktop_account_id on PublishRecordResponse so the modal can
disable already-published accounts. Make the compliance ack consumer
accept a nullable job id since the dedup short-circuit no longer creates
one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:43:27 +08:00
root e5d94f961e feat(publish-dedup): add indexes for publish task dedup and lookup
Add a unique index on desktop_tasks.dedup_key for active publish kinds
(queued/in_progress/succeeded/unknown) so duplicate publish submissions can
be rejected at the DB layer, plus supporting indexes on publish_records and
the desktop_tasks publish_record_id payload expression used by the new
dedup lookup query.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:43:15 +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 6b710c8919 refactor(desktop-task): extract recovery select query and scan task status
Pull the recovered-task SELECT into a dedicated helper so the column list and
lease-expiry filter are testable, add a status column to the scan so logs
report the real task state, and log scan/iterate failures with the client and
recovery mode for observability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:19:00 +08:00
root 513e71f9f1 fix(doubao): submit only verified SSE answers and harden source extraction
Rework the Doubao monitor adapter so success answers come exclusively from
CHUNK_DELTA SSE text and require an SSE_REPLY_END finish event — DOM fallbacks
and FULL_MSG_NOTIFY user echoes can no longer pose as the model reply. Also
auto-switch to the 思考 answer mode, repair mixed-mojibake fragments per run,
unwrap Doubao redirect URLs, scrub "unknown" source metadata, recover from
mid-query navigation by returning unknown for retry, and surface stream/finish
counters in diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:18:53 +08:00
root 2fd6267632 fix(deepseek): fall back to reasoning "搜索到 XX 个网页" panel for citations
When the standard search-results panel never opens, click the reasoning-chain
"搜索到 N 个网页" affordance to reveal the citation source list, and prefer the
revealed panel links over stale snapshot links so citations point at the right
URLs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:18:44 +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 7d8e82c69f feat(ops): add object storage management and site-mapping CSV import/export
Ship the Ops backstage 对象存储 page (browse / upload / move / delete /
folder ops) backed by a new object-storage service + handler, with the
shared storage client extended with List/Stat/Copy/Usage/DownloadURL so
both MinIO and Aliyun providers cover the new surface. Add
ForcePathStyle to the object-storage config and treat r2/s3/custom_s3
as external providers so Cloudflare R2 and other S3-compatibles can
share the MinIO client path without spinning up the bundled MinIO.

Also add CSV import/export + template download to the site-domain
mappings page, raise gin MaxMultipartMemory to 8 MiB for the new
multipart endpoints, register Ops swagger routes, and extend the
descriptions-parity test to cover the ops router.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 01:19:01 +08:00
root 5f6e9f11da feat(desktop): add client release updater
Desktop Client Build / Resolve Build Metadata (push) Successful in 19s
Frontend CI / Frontend (push) Successful in 3m20s
Backend CI / Backend (push) Successful in 16m48s
Desktop Client Build / Build Desktop Client (push) Successful in 24m46s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 37s
2026-05-25 19:23:49 +08:00
root 41b4a765ac fix(sohuhao): update infoResource value in submitArticle function
Desktop Client Build / Resolve Build Metadata (push) Successful in 20s
Desktop Client Build / Build Desktop Client (push) Successful in 22m39s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
2026-05-24 22:49:05 +08:00
root c28f8218a3 feat(desktop-client): add web context menu for bound and workbench windows
Desktop Client Build / Resolve Build Metadata (push) Has been cancelled
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:39:01 +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 a9591143e8 fix(toutiao): fail publish when body images fail to upload
Route content/cover images through the desktop media-image asset
pipeline and abort before submitting when any body image was not
replaced with a Toutiao-hosted URL, so we don't publish articles
that reference our own private asset endpoints.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 20:24:28 +08:00
root 8761e47f78 feat(kol): cache marketplace and generation reads with singleflight
Add cache-aside + singleflight to KOL marketplace list/detail, my-subscription
prompts, and generation schema lookups. Invalidate the shared public-facing
caches when subscriptions are added/revoked (ops) or KOL profile is updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 11:33:17 +08:00
root 09c8fe1e56 fix desktop operator name fallback 2026-05-24 10:23:50 +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 4a2df0435a feat(kol): add prompt_content field to KolPrompt and KolPromptRevision models
Backend CI / Backend (push) Successful in 16m17s
2026-05-24 02:01:27 +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 db95b8e4ee feat(kol): store KOL prompt content in database with object storage fallback
Add prompt_content columns to kol_prompts and kol_prompt_revisions so
prompt bodies live alongside their metadata, eliminating an extra round
trip to object storage for the common read path while keeping the old
asset key as a fallback for legacy rows.

Reads go through a singleflight-deduped, cache-backed loader that
prefers the database column, falls back to the asset key, and tolerates
missing objects via a new objectstorage.ErrObjectNotFound returned by
both the Aliyun OSS and MinIO clients on 404/NoSuchKey responses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 01:47:51 +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 3e806a5a02 feat(schedule): update PromptRuleID type to pgtype.Int8 in schedule task models
Backend CI / Backend (push) Successful in 15m13s
2026-05-23 00:18:57 +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 53ba8ff4cf Add browser toolbar to auth windows 2026-05-21 23:57:20 +08:00
root 49b1ccc961 Reduce scheduler polling noise
Backend CI / Backend (push) Successful in 14m44s
2026-05-21 00:56:43 +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 9f9e4f8e19 feat(object-storage): switch from Aliyun to MinIO for object storage configuration
Deployment Config CI / Deployment Config (push) Successful in 10s
2026-05-20 17:05:23 +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 6359a2ddd3 feat(workbench): implement workbench window management and navigation state
Deployment Config CI / Deployment Config (push) Successful in 24s
Desktop Client Build / Resolve Build Metadata (push) Successful in 39s
Frontend CI / Frontend (push) Successful in 3m3s
Backend CI / Backend (push) Successful in 16m18s
Desktop Client Build / Build Desktop Client (push) Successful in 24m1s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 35s
2026-05-20 15:44:26 +08:00
root dd082e2ed1 feat: scope articles by brand 2026-05-20 15:37:25 +08:00
root 5fb9d0b0dd perf(scheduler): harden jobs for scalable execution 2026-05-20 12:19:27 +08:00
root 4b09a34748 refactor(knowledge): migrate deleted-item cleanup from polling scheduler to event-driven worker
Replaces the scheduler-polled KnowledgeDeletedCleanupWorker with an
event-driven KnowledgeDeletedCleanupEventWorker in tenant-api; cleanup
events are now enqueued transactionally at delete time instead of swept
periodically. Also fixes statement_timeout parameterization in
MonitoringRetentionWorker and propagates errors from cleanupDeletedKnowledgeItem.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 11:22:37 +08:00
root e82ae56236 feat: add ops scheduler control center 2026-05-20 10:46:49 +08:00
root 98f73c5bea feat(objectstorage): add Aliyun OSS support and auto-detect provider in deploy workflows
Introduces Aliyun OSS as an alternative to MinIO; deploy scripts and CI
workflows now read object_storage.provider from config and conditionally
include or skip MinIO resources in both Docker Compose and k3s paths.
Also adds ops scheduler domain and its migration tables.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 10:25:02 +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 c44ddc55a6 feat(doc):add command docx to docs
Deployment Config CI / Deployment Config (push) Successful in 27s
Frontend CI / Frontend (push) Successful in 2m28s
Backend CI / Backend (push) Successful in 15m2s
2026-05-20 01:28:42 +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 28633cf570 feat(monitoring): fail same-client queued tasks on desktop authorization failure
Desktop Client Build / Resolve Build Metadata (push) Successful in 44s
Backend CI / Backend (push) Successful in 17m5s
Desktop Client Build / Build Desktop Client (push) Successful in 25m13s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 42s
When a desktop monitoring task fails with a non-retryable authorization failure
(login expired, challenge required, risk control), all pending same-client/same-platform
tasks for the same business day are immediately bulk-failed as non-retryable, avoiding
wasted execution attempts. Adds preflight authorization checks before task execution,
enriches failure payloads with disposition metadata (code, category, retryable flags),
and triggers account health reports on auth state degradation.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 23:50:50 +08:00
root 5bbbbc5cf1 feat(desktop): remember login credentials
Desktop Client Build / Resolve Build Metadata (push) Successful in 49s
Frontend CI / Frontend (push) Successful in 5m47s
Desktop Client Build / Build Desktop Client (push) Successful in 42m28s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 2m38s
2026-05-14 21:49:27 +08:00
root 639516f374 fix desktop account status display 2026-05-14 21:43:25 +08:00