Ensure numeric facts present in retrieved knowledge (especially company
founding dates) cannot be silently contradicted in generated articles.
- Add a typed fact guard that extracts constraints (dates, experience
years, etc.) from precise facts, detects source conflicts, and
validates generated content before persistence with a bounded repair
retry.
- Surface fact constraints through KnowledgeContext and render them as
a canonical, non-derivable fact block in the knowledge prompt section.
- Tighten prompt intro lines to forbid rewriting, mixing old values,
or deriving service years from founding dates.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the article locale is en-US, Chinese prompt templates could leak
Chinese wording into generated titles, outlines, and article bodies.
Add high-priority language-consistency guards so the model treats the
Chinese template text as internal instructions and emits English only.
- Append per-artifact locale guards (analyze/title/outline) in template
assist prompts and an article-body guard in the generation prompt,
only when locale is en-US
- Reinforce locale consistency in the title/outline runtime prompts and
drop retained images from the rewrite prompt
- Cover the new guards with unit tests
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previously AI point cost was computed from request (input) characters at
reservation time. Switch to reserving a single point up front and
settling the final cost from the generated output length on completion.
- Reserve 1 point (or FixedPoints) instead of pricing on request chars
- On completion, recompute points from output chars vs base chars,
update the reservation amounts, and post a ledger delta for the
top-up/refund; invalidate the workspace quota summary cache
- MarkCompleted now persists final request_chars/base_chars/points
- Use ceil division in calculateAIPointCost so an exact base boundary
charges one point instead of rolling over
- Thread output text through all CompleteAIPoints callers (article
selection, KOL assist, question expansion, template assist, compliance
judge) and return the settled reservation
- Add unit tests plus an integration test gated on TEST_DATABASE_URL
- Update the user manual: billing is by output characters
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hardcoded doubao-lite model used for monitoring answer
parsing and compliance LLM judging with configurable values, resolved
from config with env overrides and a legacy default fallback.
- Add llm.monitoring_answer_parse_model and compliance.llm_judge_model
to config struct, env overrides, and all config files
- Thread the resolved model through MonitoringCallbackService via a
ConfigProvider and into parseMonitoringAnswerWithLLM
- Pass compliance.llm_judge_model into the review-job LLM request
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Aggregate publish status from the latest record per publishing target
using a shared target-identity expression, so retries and multi-record
targets no longer inflate the status buckets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add CancelStaleQueuedPublishTasks to abort publish tasks that sit in the
queue past a configurable timeout (default 3 days) without being claimed by
a desktop client, so they no longer linger indefinitely as 'queued'. The
lease recovery worker runs the cleanup each cycle and reports a
cancelled_queued count; the timeout is configurable via job run config.
Aborted tasks carry a publish_queue_timeout error payload with a readable
Chinese duration, and the admin-web publish summary surfaces it as an
auto-cancelled queue-timeout message.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add normalizeDesktopTaskCompletionStatusForTask so an "unknown" publish
completion is downgraded to "failed" when the payload is a manual retry or
the error matches a definitive publish failure, instead of leaving it
stuck as unknown.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the in-place requeue of submit-uncertain unknown publish tasks
with an explicit supersede-and-create-new flow: manual retries mark the
old unknown task failed (manual_retry_superseded) and create a fresh task
carrying manual_retry / superseded_unknown_task_ids in its payload.
Also fold title-length validation into definitivePublishFailurePattern and
check the pattern before the publish_submit_uncertain guard so those
failures are released from the dedup set.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a sort_order column to brands with a migration, expose a
PUT /api/tenant/brands/order reorder endpoint, and wire the
admin-web BrandsView with drag-and-drop reordering plus i18n.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Added classification for `doubao_challenge_required` as a challenge in platform-auth-adapters.
- Enhanced account action summaries to include specific messages for Doubao human verification.
- Introduced monitoring functions to filter out blocked platforms based on account health.
- Updated task leasing to support platform-specific filtering for monitor tasks.
- Refined issue aggregation in HomeView to consolidate Doubao challenge failures into a single actionable item.
- Improved backend logic to handle platform IDs in task leasing requests and responses.
- Added tests for new functionality, ensuring proper handling of Doubao challenges and task leasing logic.
- Added new endpoints for initiating and completing direct uploads of desktop client packages.
- Introduced request and response structures for direct upload operations.
- Enhanced the upload process to support SHA256 and Content-MD5 validation.
- Updated the frontend to reflect changes in upload button states and progress indicators.
- Modified object storage clients to support presigned PUT URLs with content type and MD5 headers.
- Added tests for direct upload functionality and ensured existing upload processes remain intact.
- Implemented a new BrandAssetCleanupWorker to handle the cleanup of brand-related assets after a brand is deleted.
- Added SQL queries for cleaning up articles, keywords, questions, competitors, and monitoring data associated with a brand.
- Introduced a new API endpoint to delete publish records.
- Updated the router to include the new delete publish record endpoint.
- Added tests for the BrandAssetCleanupWorker to ensure proper functionality.
- Created migration scripts to support soft deletion of publish records and to add the brand asset cleanup scheduler job.
Make GET /api/tenant/brands/:id/questions return a paginated
QuestionListResponse (items/total/page/page_size) with optional `q`
full-text filter, validated page/page_size query params, and per-params
cache keys. Add a usePaginatedBrandQuestions composable backing the
imitation, template-wizard, and tracking question selects with
search-as-you-type and infinite scroll, plus ensure-loaded-by-id so a
deep-linked or pre-selected question is fetched even when off the first
page. Brands view now drives its questions table via server pagination.
Also redesign the Tracking hot-questions and cited-articles lists
(mention-rate badges/bars, metric groups, refreshed styling) and fall
back to citation-fact article_id/title when no high-confidence URL alias
matches, so cited articles surface even without an alias row.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stale publish jobs for deleted or invalid articles previously lingered in the
queue and kept failing compliance rechecks. Now they are cancelled cleanly and
batch/article publish status is recalculated.
- cancel queued desktop tasks, jobs and publish records on article delete
- detect deleted articles and invalid-article-version compliance errors during
the client publish recheck and cancel the affected tasks
- add cancelQueuedPublishTasksForUnavailableArticle helper and a unit test for
the compliance-error classifier
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a cover mode to schedule tasks so auto-publish can pick a random cover
image instead of a fixed one, scoped to all images or a specific folder.
- migration: add cover_mode / cover_random_scope / cover_random_folder_id
columns and check constraints on schedule_tasks
- backend: validate cover mode/scope/folder on create & update; the dispatch
worker resolves a random active image (signed asset URL) at enqueue time
- frontend: new CoverSourceSelector component wired into GenerateTaskDrawer
and PublishArticleModal, plus coverSource i18n strings
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>