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>
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>
Replace the labeled cover button + meta column with a compact preview
tile and an overlaid remove button, dropping the now-unused cover-meta
typography rules.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Promote the header to z-index 100 and create an isolated stacking
context on the main layout so sticky/positioned content (drawers,
overlays) no longer sits above the topbar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Update server titles, web/desktop window/tray/document titles, login
copy, and electron build metadata to use the Chinese product name 省心推.
Drop the runtime locale switcher and en-US import — the app now ships
zh-CN only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The target-platform supplement only fed legacy prompt builders that read
the now-removed wizard_state platforms field. Drop the YAML entry,
loader struct field, and runtime helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
新增登录态失效与微信公众号外链缺失两类发布错误归一化,
将原本散落在适配器里的中文提示集中到 shared/publisher-errors,
让渲染层与 main 进程共用同一份用户可读文案。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduce a self-contained kustomize stack under deploy/k3s covering
namespace, config, placeholder secrets, infra StatefulSets, app
Deployments/Services, migration and minio-init Jobs, and Traefik
Ingress for both tenant and ops hosts. Add Dockerfile.ops-web so the
operations frontend can ship as an nginx image, and extend the offline
package script to build and bundle ops-api, kol-assist-worker, and
ops-web alongside the k3s manifests. Wire the new ops/security knobs
through .env.example and the compose stack.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an in-process Swagger UI and OpenAPI JSON under /swagger,
registered automatically when the Gin mode is not release. The
admin-web Vite dev server and production nginx config now proxy
/swagger to the tenant API so the docs are reachable from the
existing admin host.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Open a dedicated settings BrowserWindow with general / login / diagnostics / about tabs
- Persist openAtLogin and keepRunningInBackground via desktop-settings.json; hide main window instead of quitting when background mode is on
- Default API base URL now points to api.shengxintui.com; LoginView and SettingsView share a single constant
- Restore wangyihao session cookies on probe and silent refresh, and accept the legacy http://mp.163.com console origin
- Drop the standalone diagnostics view in favor of the settings tab
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the media-platforms nav entry to "媒体账号", switch the Accounts hero eyebrow to MEDIA ACCOUNTS, drop the redundant AI platforms intro paragraph, and trim the publish list to use a generic external-link tooltip plus a slightly wider table to fit the renamed columns.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spawn a separate window per mode keyed by a ?window= query param so each surface keeps its size, devtools, and renderer state independently. Logout now persists the cleared session and switches windows before awaiting the runtime release, avoiding a stale main-window flash on the way out.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Build https://www.163.com/dy/article/<docId>.html when wangyihao tasks finish, and normalize publish-record responses + monitoring alias inputs to surface the same public URL when the doc id is known.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Scheduled probes and reportAccountFailure now request a silent refresh
before marking an account expired, and a missing wangyihao publish
token is classified as ok instead of auth_failure so the cookie-based
refresh path can recover the session.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Snapshot 163.com/126.net cookies on bind/refresh to a userData vault and
restore them when reattaching a session, recover orphan partitions by
matching the detected mediaInfo, verify the bind window via the console
state instead of a generic profile probe, and route token/draft fetches
through the https API origin while opening console pages over http to
match the live editor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Track an authRevision per local record so a fresh bind cancels in-flight
probes, sync server-confirmed health back into the desktop cache via
reconcileTrackedAccountRemoteState, include verified_at in the upsert
signature, and drop runtime health reports older than the stored
verified_at on the server side.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Inject the YiDun guardian client to obtain ursToken without relying on
window.neg, fetch the publish detail (wemediaId/onlineState/...) before
saving drafts so 100002 "参数错误" stops blocking submit, downgrade
markdown tables to paragraph rows like Baijiahao, and surface friendlier
errors for token, draft and publish-click failures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Reduce image_storage_bytes from 500MB to 25MB on free and from 1GB to
500MB on pro to align quotas with current storage cost expectations.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Split the home dashboard runtime panel into a combined issue feed that
lists failed/unknown tasks alongside blocked accounts, with per-kind
counts and per-row detail/badges so operators can triage both classes
of breakage from one place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Raise the response capture body limit, parse siteName and source
indexes from yuanbao DOM links, merge ordered DOM sources with the
streamed list, and reject runtime/build-diagnostic strings from being
treated as a question.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Replace the legacy target_platform string on schedule tasks with a
workspace-aware auto-publish payload (auto_publish + publish_account_ids
JSONB + cover_asset_url + cover_image_asset_id) and migrate the schema,
sqlc queries, generated models, domain struct, ScheduleTaskService DTOs,
and dispatch worker to round-trip the new fields. PromptRuleGeneration
gains a WithPublishJobService hook so executeGeneration can enqueue an
auto-publish job once the article is ready, and worker-generate wires
the publish-job service in. On the admin-web side, extract
PublishArticleModal's account-card builders into a shared
publish-account-cards module, rebuild GenerateTaskDrawer's schedule
mode around account selection plus a CoverPickerModal, and surface the
new "auto publish" column on ScheduleTaskTab. Shared types and i18n
strings cover the new fields.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
Tighten the analyze prompts (runtime + recommendation platform) so the
model returns 8-10 question-style search queries (哪家好/有哪些/怎么选/
价格/排名/避坑 …) instead of generic tag words, and lift the keyword cap
in normalizeAnalyzeResult from 5 to 10 to keep them. Add tests covering
the new ten-keyword window and the question-like guidance in the seeded
analyze prompt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 企鹅号 console returns 200 even when the session is silently expired,
so probe/silent-refresh/console-open now require detect() to return an
account whose identity matches the bound one. Surface a localized
"授权已过期" prompt in the renderer when the new
desktop_account_session_expired error bubbles up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
懂车帝 has the same cover-mandatory rule as 百家号; treat them the same
when deciding whether a publish batch must carry a cover.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Logging the full candidate and selected snippet bodies per resolve was
inflating log volume without adding signal we use.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapse rapid double-submits into a single in-flight request across
admin-web, ops-web and the desktop client so users cannot fire parallel
login attempts and trip the new in-progress guard. Map the new
login_rate_limited / login_locked / login_in_progress / login_guard_unavailable
error codes to localized messages in every login surface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire LoginGuard into tenant-api and ops-api login flows: acquire a
permit before checking credentials, record a failure on every invalid
attempt to drive lockouts, and clear counters on success. Tenant-api
now also forwards the request IP into the service so per-IP and
IP+identifier limits actually fire under real traffic.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduce a Redis-backed LoginGuard that combines per-IP, per-identifier
and IP+identifier rate limits, exponential lockout on consecutive failures,
and a concurrent-attempt lock so a single subject cannot pile up parallel
brute-force tries. The guard ships with an in-memory fallback when Redis
is unreachable so login protection keeps working under degraded mode.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a lazy Redis client constructor and an in-memory fallback for the
refresh-session store, plus tenant-api and ops-api bootstrap that warns
and continues with the lazy client instead of failing. Refresh and
blacklist operations now silently fall back to the in-memory store while
Redis is down so existing sessions stay valid until it recovers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verify approve/revoke/manual-bind delete the right tenant-scoped keys via
a recording cache double, so the prompt cache stays consistent with the
KOL subscription state changes shipped in the previous commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the mixed text-link / button action lists in Accounts,
AdminUsers, and SiteDomainMappings with a shared .table-actions-row +
.action-* class set in styles.css. Each row now renders compact icon
buttons (edit/delete/approve/revoke/key/kol/reset/play) tinted by intent,
matching the new KolSubscriptions console look.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New /kol-subscriptions page lists pending and active subscriptions, lets
operators approve / revoke / manually bind packages to tenants, and links
into the AppShell nav under 订阅包审批. Register Alert globally so the
view's status banners render.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>