Skip to content

wallet-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-017

Current implementation: foundation scaffold exists under services/wallet-service.

Owns: AZ Credits, wallet balances, immutable ledger, grants, debits, refunds.

Must read:

  • legacy wallet/AZ Credit modules and admin wallet review flows: /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet.service.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet.controller.ts, /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/wallet-topup-create.spec.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/wallet/wallet-course-purchase.spec.ts.
  • docs/migration/legacy-database-inventory.md wallet rows.
  • 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/**
  • wallet/AZ Credit Prisma rows in /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma.

Writable files:

  • services/wallet-service/**
  • contracts/openapi/services/wallet-service.yaml
  • docs/api/wallet-service.md

Orchestrator-owned files:

  • payment provider reconciliation, billing subscription contracts, usage quota policy, gateway route cutovers, and shared deploy manifests unless delegated.

Delegated gateway verification scope:

  • Agents may maintain only the non-default admin review read rehearsal in deploy/gateway/routes.wallet-admin-review-native-example.json and deploy/gateway/routes.wallet-admin-review-native-localhost-example.json; public wallet routes, admin wallet mutations, and the default gateway route table remain orchestrator-owned.
  • Route proof must cover GET /api/admin/wallet/reviews to /v1/admin/wallet/reviews through scripts/test/monetization-route-guard-coverage.sh and scripts/test/wallet-admin-review-live-smoke.sh, with QA evidence in docs/qa/wallet-admin-review-live-smoke.md.
  • Makefile targets: test-monetization-routes for static/self-test coverage and test-wallet-admin-review-live for explicit local gateway proof. Browser/API parity still uses /wallet?tab=billing plus admin wallet review evidence before promotion.

Initial tasks:

  • Audit credit debit/refund rules for AI/OCR/import/storage. Started from legacy shared wallet statuses/schemas and wallet.service.ts ledger calls.
  • Design immutable ledger schema and idempotency keys. Done in services/wallet-service/migrations/000001_wallet_service.sql.
  • Define APIs for usage/import/AI services to request debits without direct DB access. Started with POST /v1/wallets/{walletId}/ledger-entries.
  • Model user overview, ledger, top-up, withdrawal, admin review, and payment evidence workflows from legacy wallet routes. Ledger/adjustment foundation and native top-up/withdrawal/admin review state machines are done for the internal /v1/* surface.
  • Added payment.order.paid.v1 consumer adapter for purpose=WALLET_TOP_UP. It creates/loads the account wallet and writes one TOPUP_CREDIT ledger entry keyed by the source payment event id. The adapter requires explicit amountCredits; it does not convert VND to AZ Credits.
  • Added billing.subscription.activated.v1 consumer adapter. It creates/loads the account wallet and writes one SUBSCRIPTION_CREDIT ledger entry keyed by the source-scoped billing event id when monthlyCredits is positive.
  • Hardened subscription credit grants so positive monthlyCredits events must include sourcePaymentEventId; zero-credit events remain no-op deliveries and do not create wallets or ledger rows.
  • Exposed POST /v1/events/payment-order-paid for the internal payment-service HTTP fanout rehearsal path. Public wallet/admin wallet routes remain legacy-proxied.
  • Exposed POST /v1/events/billing-subscription-activated for the internal billing-service outbox sink. Public billing routes remain legacy-proxied.
  • Both internal HTTP event receivers require the shared X-Internal-Token and their expected sender: payment-service for paid top-ups and billing-service for subscription credits. Missing or invalid credentials are rejected before JSON decoding or a ledger mutation; a missing token configuration returns a fail-closed service-unavailable response.
  • Added optional best-effort audit-service producer projection for successful wallet ledger entries. AUDIT_SERVICE_URL/AUDIT_SERVICE_BASE_URL enables posting to /v1/audit-events with sourceService=wallet-service, sourceEventId=<ledger entry id>, category=DOMAIN, severity=INFO, outcome=SUCCESS, metadataSchemaVersion=1, retentionPolicy=wallet-ledger, and createdAt -> occurredAt; publish failures do not block wallet balance movements.
  • Added terminal-status guards for top-up approve/reject and withdrawal review. Top-up review accepts only PENDING_REVIEW and NEEDS_REVIEW; withdrawal paid/reject accepts only PENDING_REVIEW; approval, hold, paid, and reject ledger effects use fixed replay-safe idempotency keys. Public route cutover remains blocked on legacy response parity and gateway/browser evidence.
  • Added wallet-owned admin review read queue: GET /v1/admin/wallet/reviews lists top-up and withdrawal review summaries with kind, status, accountId, organizationId, limit, and offset filters. This closes the admin-service source-map gap for wallet.reviews; admin-service may aggregate the route later, but the review state remains wallet-owned.
  • Added non-default gateway route-table rehearsal for GET /api/admin/wallet/reviews to wallet-service /v1/admin/wallet/reviews in deploy/gateway/routes.wallet-admin-review-native-example.json and deploy/gateway/routes.wallet-admin-review-native-localhost-example.json. The default gateway table, public wallet routes, admin wallet mutations, and nested admin wallet routes remain legacy-proxied.

Acceptance:

  • Wallet does not own subscriptions or payment provider webhooks. Done for the foundation.
  • Ledger is append-only and reconstructs balance. Done for memory and Postgres stores.
  • Refund/debit paths are idempotent. Debit/credit/adjustment and fixed-key top-up/withdrawal review ledger effects are covered; any future public refund route must add route-specific parity tests before promotion.
  • Paid top-up event replay is idempotent and does not move the balance twice.
  • Subscription activation event replay is idempotent and does not grant monthly credits twice.
  • Positive subscription credit grants require payment evidence via sourcePaymentEventId; zero-credit subscription events are ignored without balance movement.
  • Top-up approve/reject and withdrawal review workflows have terminal-status guards, admin actor evidence, replay-safe ledger effects, and named tests before any admin wallet route promotion.
  • Wallet-owned admin review queue reads are implemented and test-covered before any admin-service aggregation or public route promotion.
  • First admin review route-table rehearsal is non-default, ADMIN-only, guarded by make test-monetization-routes plus the opt-in test-wallet-admin-review-live gateway smoke, and rollback is the default route table.
  • Refund workflows are replay-safe by source event/idempotency key and have focused tests before wallet balance or history routes move native.
  • Public/admin wallet route promotion requires legacy response parity, route rehearsal, browser/runtime proof, and rollback evidence.

Verification:

  • GOTOOLCHAIN=go1.25.11 go test ./services/wallet-service/... -count=1
  • WALLET_SERVICE_POSTGRES_TEST_DATABASE_URL='postgres://hoctapaz:hoctapaz@localhost:5433/hoctapaz_platform?sslmode=disable' GOTOOLCHAIN=go1.25.11 go test ./services/wallet-service/internal/repository -run TestPostgresWalletLedgerReplayIntegration -count=1 -v
  • make test-monetization-event-chain
  • make test-monetization-routes
  • WALLET_ADMIN_REVIEW_SELF_TEST=1 bash scripts/test/wallet-admin-review-live-smoke.sh
  • GATEWAY_ROUTE_TABLE=deploy/gateway/routes.wallet-admin-review-native-localhost-example.json GATEWAY_BASE_URL=http://localhost:18091 WALLET_ADMIN_REVIEW_LIVE_CONFIRM=wallet-admin-review-native make test-wallet-admin-review-live
  • Browser/API parity targets after scaffold: /wallet?tab=billing, admin wallet review, top-up approve/reject terminal states, and usage history.

Next tasks:

  • Add legacy-compatible public/admin wallet response adapters and browser/API runtime proof before promoting any wallet route into the default route table.
  • Broker subscriber foundation is present for successful top-up and subscription-credit events through the shared NATS transport. Broker live smoke and replay/dead-letter tooling now exist; remaining wallet promotion work is public wallet/admin adapter parity, browser proof, and default route rollback evidence.
  • Add usage-service debit API integration once usage-service exists.
  • Extend gateway route-table rehearsal only after legacy response parity is documented for the next wallet route.

Go-platform documentation is generated from repository Markdown.