Appearance
usage-service Agent Tasks
Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; keep this pack's writable scope and verification commands authoritative.
Dispatch type: per-service
Dispatch ID: SVC-018
Current implementation: services/usage-service foundation.
Canonical name: usage-service. entitlement-service is a planning alias only; do not create a separate entitlement-service scaffold.
Owns: usage counters, quota periods, feature entitlements, check/consume APIs.
Must read:
- legacy feature/package limit code:
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/az-credit.service.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/az-credit-business.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/exams/exam-core.service.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/questions/question-generation.service.ts,/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/questions/question-solution.service.ts. - billing and wallet task packs.
- monetization broker handoff:
docs/agents/service-tasks/monetization-broker-transport.md. - shared event contracts in
contracts/events/README.md.
Legacy source evidence:
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/az-credit*.ts- AI/import/question usage callers under
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/**.
Writable files:
services/usage-service/**contracts/openapi/services/usage-service.yamldocs/api/usage-service.mddocs/agents/service-tasks/usage-service.md
Orchestrator-owned files:
- billing entitlement event contracts, wallet debit/grant orchestration, workload service integrations, gateway route cutovers, and shared deploy manifests.
Completed foundation:
- Mirrors the legacy quota keys:
credits_monthly,credits_hourly,credits_weekly,tokens_monthly,questions,storage_bytes,ocr_pages_monthly,batch_import_pages, andconcurrent_jobs. - Accepts billing-service entitlement snapshots through
PUT /v1/entitlements/sync. - Added
billing.entitlements.updated.v1consumer adapter. It maps billinglimitsinto usage entitlements, records processed billing events by(source,eventId), returns duplicates without replacing rows, and rejects stale older snapshots for the same account. - Hardened the billing entitlement event contract so
sourceSubscriptionEventIdis required before usage materializes a snapshot; the consumer now covers zero-priceFREE_TRIALentitlement fanout and paid plan entitlement snapshots with the same audit link. - Exposed
POST /v1/events/billing-entitlements-updatedfor the internal billing-service HTTP fanout rehearsal path. - The HTTP entitlement receiver requires
X-Internal-Service: billing-serviceand the sharedX-Internal-Token; missing or invalid credentials are rejected before decoding or replacing an entitlement snapshot, and missing production token configuration fails closed. - Exposes check-only and idempotent consume APIs so AI/import/file/question services do not embed plan logic locally.
- Stores counters and consume events with a service-owned Postgres migration.
- Supports account-level override precedence over plan-level overrides, then entitlement limits.
- Rechecks a finite limit while the usage counter is locked, so concurrent unique consume requests cannot write usage above the owner quota.
- Provides deterministic period rows and explicit reset APIs instead of moving money or running workload jobs.
- Locks current native period behavior as UTC bucketed windows: top-of-hour, Monday-start week, first-of-month, and lifetime epoch buckets. This is not a rolling-window implementation.
- Covers real HocTapAZ quota caller fixtures for AI credits/tokens, OCR/import pages, storage bytes, question bank counts, course/import concurrency, and admin limit overrides.
Next tasks:
- Broker subscriber foundation is present for billing entitlement events through the shared NATS transport. Remaining broker work is live smoke, replay/dead-letter tooling, and route rollback evidence in
docs/agents/service-tasks/monetization-broker-transport.md. - Re-evaluate rolling-window parity only during a route cutover that requires exact legacy hourly/weekly AI lookback behavior. Current native behavior is documented and tested as UTC buckets.
- AI generation and OCR/import callers already use explicit usage-service and wallet-service owner APIs. Do not add file/question callers unless their workload owner and debit source are explicitly defined.
- Attach route-specific live/browser and rollback evidence to the existing AI generation and OCR/import caller rehearsals before changing default public routes.
Acceptance:
- Usage-service does not move money or run AI/import jobs.
- Entitlement checks and billing entitlement event delivery can be replayed and audited.
- Billing entitlement events without
sourceSubscriptionEventIdare rejected; duplicate or stale events with the source link remain replay-safe. - Monthly reset behavior is deterministic.
Verification:
GOTOOLCHAIN=go1.25.11 go test ./services/usage-service/... -count=1make test-monetization-event-chain- Isolated Postgres entitlement/replay integration:
USAGE_ENTITLEMENT_REPLAY_POSTGRES_CONFIRM=disposable-postgres ./scripts/test/usage-entitlement-replay-postgres-isolated.sh. The runner owns a dynamic-loopbackpostgres:16-alpinedatabase, ignores caller DSNs, and runs the group^TestPostgresUsage.*(Entitlement|Replay).*$. It establishes repository persistence evidence only, not broker delivery, route promotion, browser, production, or rolling-window parity proof. The current group includes advisory-lock proof that concurrent old/new billing entitlement snapshots serialize with the newer limit as the final state. - Feature-key fixture tests must cover AI, OCR, import, storage, question bank, course, and admin override cases.