Commit Graph

83 Commits

Author SHA1 Message Date
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 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 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
root 669c9f709a fix(admin-web): replace inline multi-statement @cancel handler
Frontend CI / Frontend (push) Successful in 2m31s
Prettier with semi:false stripped the semicolons that previously separated
the two inline statements, leaving the Vue compiler unable to parse the
expression. Extract closeItemModal() and bind the handler by reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:47:49 +08:00
root 162abdc97c chore(frontend): introduce prettier + eslint and prune unused code
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Failing after 1m39s
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports)
- Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier
- Add root scripts: format, format:check, lint, lint:fix
- Reformat 257 files across admin-web, ops-web, desktop-client, packages
- Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters
- Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex
- Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:39:09 +08:00
root b6281efc16 chore(admin-web): rewrite media view copy without internal table names
Replace developer-facing references to platform_accounts with
user-friendly wording about bound desktop client accounts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:19:21 +08:00
root fb05f07e84 refactor(admin-web): drop eyebrow labels from page heroes
Remove the redundant eyebrow text above page titles in PageHero,
BrandsView and TrackingView, and clean up the now-unused i18n keys.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:19:14 +08:00
root 39ef1a6b7f feat(knowledge): add retry endpoint and 20-char text name limit
Add POST /api/tenant/knowledge/items/retry/:id to re-queue failed parse
tasks, plus a 20-rune cap on text item names with matching frontend
validation. Wires the retry button into the knowledge table with a
colored status tag for clearer state feedback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:19:08 +08:00
root c1f07bfb65 fix(admin-web): add custom popup class for knowledge group tree dropdown
Frontend CI / Frontend (push) Has been cancelled
2026-05-01 18:54:28 +08:00
root 478d49a8d0 fix(ops-web): update placeholder text for phone number input fields
Frontend CI / Frontend (push) Has been cancelled
2026-05-01 18:35:29 +08:00
root c89683862e feat(workspace): replace supported platform count with bound media account count
The "platforms" stat tile was a constant (5) that never reflected what the
tenant actually had set up. Drop SupportedPlatformCount from the workspace
overview API/domain/shared-types and have admin-web compute a bound media
account count from the desktop accounts list, filtered through a new
isMediaPublishAccount helper that excludes deleted rows and AI-only
platforms (yuanbao/kimi/wenxin/deepseek/doubao/qwen).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:01:40 +08:00
root 9727077dfa refactor(admin-web): render citation pie as interactive SVG with hover tooltip
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Has been cancelled
Deployment Config CI / Deployment Config (push) Successful in 21s
Replace the conic-gradient circle with an SVG path-per-slice chart so
slices can lift on hover, dim siblings, and surface a follow-cursor
tooltip with the platform name and share. Falls back to the original
gradient circle when there are no segments to render.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:46:35 +08:00
root b345ee26e4 feat(monitoring): match citations by canonical link and scope summary by brand/keyword/platform/date
Replace the domain+title fuzzy alias scoring with a canonical
candidate-key index built from published-link aliases — only exact
matches now resolve to a SaaS source, eliminating false positives
across articles sharing a host (e.g. m.163.com vs www.163.com).

Surface the summary scoping that already existed on loadCitationRanking
/ loadCitedArticles by accepting brand_id, keyword_id, ai_platform_id
and business_date on CitationSummary, plumbing them through the handler
and admin tracking view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:46:17 +08:00
root 490c6c759d feat(article): expose auto_publish_platforms derived from publish accounts
Replace the freeform `platforms` field on articles/tasks (parsed out of
wizard_state/input_params JSON) with `auto_publish_platforms`, resolved
by joining schedule publish accounts to platform_accounts. The migration
strips the legacy keys from existing rows so the new field is the single
source of truth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:02:21 +08:00
root 9525c1144d feat(admin-web/login): replace default test credentials with remembered login
Why: showing the seed admin account on the login screen is unsafe for production deployments.
How to apply: store identifier/password in localStorage when "记住密码" is checked, restore them on mount, and drop the demo credentials panel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:15:08 +08:00
root fb166fa9fe feat(monitoring): attribute SaaS citations by registrable domain
Persist host/registrable_domain/site_key on monitoring article URL
aliases, populate them on desktop-publish completion, and use them in
the citation pipeline to count how often SaaS-published content
appears as a citation source. Expose a /citation-summary endpoint with
a 7/30-day window switch and surface the new source-share metrics in
the tracking dashboard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 17:12:09 +08:00
root c9267d2fae feat(auth): block disabled user accounts at the subscription guard
RequireActiveTenantSubscription now optionally takes an AuthRepository
and rejects the request with 40311/user_disabled when the actor's user
row is anything other than active. Wire the repo through the tenant
router, surface the new error code in admin-web's
membershipBlockedErrors set, persist a "disabled" membership status when
markStoredMembershipBlocked sees user_disabled, and add localized copy
on the blocked screen and shell membership banner.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 01:31:26 +08:00
root e15806bd91 feat(template-wizard): require library brand before favoriting competitors
Drop the implicit brand-creation path in handleFavoriteCompetitor and
just refuse to save a competitor until the user has explicitly chosen a
library brand; clear saved state on competitor drafts when the brand is
unset. Also enforce the configured custom-outline label length cap and
auto-focus newly added outline nodes for faster keyboard editing. New
i18n strings cover the brand-required and outline-length messages plus
the updated competitor hint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 01:30:29 +08:00
root 4dd8a1bb0e feat(tenant/kol): let KOLs self-subscribe to their own published packages
Add /kol/manage/packages/:id/self-subscription POST/DELETE on the tenant
side so a KOL can grant themselves access to their own published package
without going through the marketplace approval flow. Reject self-subscribe
through the marketplace with a clear error, expose owned_by_current_tenant
on package responses, and surface a self_subscription block on KolPackage
Response. The admin-web KOL workspace gets 订阅自己 / 取消订阅 entries with
matching messaging in the marketplace detail view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 22:06:57 +08:00
root 6a56935fb9 chore(admin-web/login): drop redundant tenant admin login subheading
The 欢迎回来 headline already conveys context; the secondary
"Tenant Admin Login" line added noise on the simplified login card.
Remove the paragraph and the now-unused i18n key.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:02:52 +08:00
root 62b824520c feat(admin-web/auth): support phone-or-email login and dim shell on expiry
Login form takes a phone-or-email identifier; user info now exposes phone
so the shell can fall back through name → phone → email. When membership
expires, the app stays on the current route but renders a minimal blocked
state in the shell instead of redirecting to a dedicated page; an Axios
interceptor flips the local session into the blocked state when the API
returns trial/subscription errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 00:01:47 +08:00
root 27f1850e0e fix(admin-web/tracking): guard optional citations array on platform
部分平台返回的快照里没有 citations 数组,原代码直接 platform.citations[i]
会在内联引文渲染处抛 TypeError。改用可选链兜底空值。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 18:36:05 +08:00
root 9683a53403 refactor(admin-web/ai-points): rework usage page into card layout
把页面改造成两张白底卡片:顶部卡片承载页头 + 概览四宫格,下面卡片承载用量
台账。指标格子改成圆形图标 + 文字两栏布局,排版更接近现有控制台其它视图。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 18:35:58 +08:00
root bf7594ccd8 feat(admin-web): expose AI point balance and usage ledger
Surfaces the new AI point quota in the workspace shell and adds a
Personal Center → AI Point Usage page that shows balance, base-char
rule, and the paginated reservation/refund history. Updates shared
types for the QuotaSummary and ledger payloads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 11:34:07 +08:00
root 412befef53 feat(admin-web): prefer runtime account health when ranking and gating accounts
Surface the new runtime_health/runtime_checked_at fields through a tiny
desktop-account-runtime helper so PublishArticleModal, MediaView, and
TrackingView fall back to the desktop client's last live signal instead of
the slower DB column. This keeps the publishable card and tracking
breakdown in sync with the desktop probe loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:34:05 +08:00
root 93ff3c773f fix(admin-web): set no-referrer policy on cross-origin platform avatars
Platforms like Bilibili refuse to serve avatar images when the
Referer points at our admin origin, so the article publish status
panel and the media account cards now request avatars with a
no-referrer policy to stop the placeholder from showing instead of
the user's real avatar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:00:04 +08:00
root ae63f60def style(admin-web): apply blurred-backdrop cover treatment to KOL cards
Switch KOL package, template, and workspace card covers from object-fit
cover to a blurred backdrop with a contained foreground image so non-16:9
artwork no longer crops awkwardly. Also restyle the package detail back
button, swap the generate-button copy for the canonical key, and rename
"prompts" counts to "refined templates" in i18n.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:17:04 +08:00
root cde70ca5e0 feat(admin-web): trim platform and cover controls from article editor
Remove the right-rail publish platform selector and cover picker from the
in-editor view; those settings now live in the publish modal so the editor
focuses on title and content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:16:45 +08:00
root c0617b70d8 feat(admin-web): add Ctrl/Cmd+S save shortcut to article editor
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 22:45:27 +08:00
root 2846968cf7 feat(kol): add selection-based AI optimize for prompt editor
Trigger an AI optimize panel from a text selection in the KOL prompt
editor, accept a user instruction, and stream a preview before replacing
the selected fragment. Extend the shared editor AI assist panel with
boundary-aware placement so it can be hosted inside scoped surfaces, and
update the backend optimize prompt to honor the user instruction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 22:41:40 +08:00
root 2862aff72b refactor(admin-web): unify page headers with shared title card
Introduce .page-title-card style and migrate Images, Knowledge,
KolDashboard, KolManage, KolProfile views to the shared header layout.
Add subtitle copy for KOL dashboard and manage views.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:38:45 +08:00
root 40d9a6cc63 feat(imitation): add article imitation create flow
Introduce 仿写创作: new list and create views, backend imitation service
and prompt templates, worker task routing for imitation jobs, and one-click
rewrite triggers from question citation sources. Surface source article
URL/title on article list/detail, and restrict failed articles to delete-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:36:44 +08:00
root 46d0a7aea0 feat(admin-web): surface queued publish hint in media view
Restores publish hints for queued and immediate states so operators
know when a task will wait for the desktop client to come back online.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:09:12 +08:00
root 7e78b031d7 chore(admin-web): drop redundant publish hint copy from media view
Remove the immediate/queued publish hint sentences and the explanatory
alert block, and hide the card footer when there's nothing to show.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 17:39:02 +08:00
root 4a7427a7f1 feat(monitoring): exclude qwen from content citation resolution
Skip article alias resolution and content-citation aggregates when the
platform is qwen, and hide the content-citation badge/meta in the
tracking detail view, since qwen's source URLs are not reliable enough
to map to brand articles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:48:28 +08:00
root 4f3c39f5f5 feat(deepseek): normalize model labels and unwrap redirect URLs
- Normalize provider_model so UI shows DeepSeek/DeepSeek-R1 instead of raw toggle text (联网搜索 etc.)
- Unwrap DeepSeek redirect URLs (chat.deepseek.com/api/redirect?url=...) to canonical sources
- Expand reasoning sections and separate reasoning search pages from answer-body citations
- Improve webpages-trigger click heuristics and auxiliary link filtering in answer rendering

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:37:16 +08:00
root 1b1ab7ee0c feat(admin-web): surface monitoring platform authorization status
Dashboard and question-detail views now read platform_authorization_status
from the API. Tracking disables collect-now when the account has no
desktop client, no authorized platforms, or the selected platform is
unauthorized, and keeps the six-platform matrix stable; question-detail
replaces tabs and cards with an explicit unavailable notice when the
account is not authorized for monitoring. Adds the shared type and
en/zh strings covering each status.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 22:21:01 +08:00
root f6e553dcc3 feat(monitoring): add DeepSeek monitoring end-to-end
- desktop: new DeepSeek page adapter and monitor registry
- desktop: extract generic AI auth helpers into shared module and
  skip binding when challenge signals are present
- admin-web: render DeepSeek HTML answers with inline citation anchors
  and surface reference-number badges on source cards
- server: fall back to inline_links/source_panel_links and read
  text/siteName fields when extracting DeepSeek citations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 22:54:56 +08:00
root ae0e4b0209 feat(admin-web): make KOL dashboard trend chart responsive with tooltip
Chart now adapts to container size via useElementSize and adds a hover
tooltip with per-point overlay. Prevents grid/flex blowout with min-width
and layers the SVG absolutely inside its wrapper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:25:52 +08:00
root 4f4f063200 refactor(monitoring): simplify brand dashboard and harden citation rendering
- drop brand_time_buckets and sparkline/coverage UI; dashboard now returns a single day
- compute mention rate from total actual samples instead of averaging per-platform rates
- canonicalize ai_platform_id across services and aggregate platform-overview snapshots
- strip mojibake and non-answer noise from callback payloads and question detail answers
- keep Kimi citations panel-only; still store raw search_results for audit
- render linked [n] inline citations for qwen/yuanbao answers with scroll-to-source behavior
- restrict立即采集 to today's business date with a clear i18n hint
- refresh content-citations into an ant-design table with truncation and hover styling

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:11:53 +08:00
root 4142c53fa6 feat(monitoring): dispatch monitoring tasks to desktop via AMQP outbox
Replace SSE /desktop/events with priority AMQP dispatch for monitoring
runs, and add phase1/phase2 infrastructure so desktop workers can lease,
resume, report, skip, and cancel monitoring tasks over the existing
dispatch WebSocket.

- Add monitoring collect outbox worker and phase2 desktop task fields
- Add /desktop/monitoring/tasks/{lease,resume,result,skip,cancel} routes
- Introduce execution-devtools and network-observer on desktop runtime
- Refactor runtime-controller, LoginView, and doubao adapter for the new flow
- Add channelName column to tracking views

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 00:24:21 +08:00
root 7abac1e9c4 feat: Implement Qwen adapter and enhance AI platform detection
- Added a new Qwen adapter to facilitate monitoring through Playwright, leveraging internal text/chat managers.
- Updated account detection logic to recognize Qwen sessions based on persisted cookies, improving binding reliability.
- Relaxed authentication requirements for monitor tasks, allowing anonymous execution for certain AI platforms.
- Enhanced the generic AI platform detection to include Qwen-specific logic, ensuring accurate session identification.
- Modified the monitoring dashboard to include runtime state indicating if the current user's desktop client is online.
- Updated various files including `account-binder.ts`, `runtime-controller.ts`, and `monitoring_service.go` to support new features and improvements.
2026-04-20 19:10:35 +08:00
root ad9a784e8c fix(accounts): hide AI-platform accounts from publish-only views
After splitting AI platforms into their own catalog, the admin MediaView and
desktop AccountsView still showed yuanbao/kimi/wenxin/deepseek/doubao/qwen
rows alongside publish platforms. Filter by publish catalog membership so
those views stay scoped to publish accounts only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:44:51 +08:00
root 09295d11a1 feat(monitoring): decouple AI platforms from media_platforms and expand catalog to 6
Add ai_platforms table + shared catalog (yuanbao/kimi/wenxin/deepseek/doubao/qwen),
drop FKs from platform_accounts and desktop_tasks to media_platforms, and wire
target_account_id + platform into DesktopTaskEvent so the desktop runtime no
longer has to infer them from local state. Desktop client gains generic AI page
detection for binding, drops stale-business-date monitor tasks at the edge, and
refactors AccountsView/AiPlatformsView around the shared catalog. Admin tracking
view surfaces per-platform sampling status cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:40:18 +08:00
root f5a1cd81b2 style(admin-web): truncate long client status tag with tooltip
Long desktop client status labels overflowed the media card; cap tag width with ellipsis and expose the full text via tooltip on hover.
2026-04-20 12:00:10 +08:00