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>
Cover onboarding, workspace, article creation, brand library, media
publishing, knowledge base, image library, GEO tracking, desktop client,
KOL marketplace, AI points, and FAQ — sourced from actual views and i18n
rather than the v1 PRD.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>