Files
Stirling-PDF/app
Connor Yoh 9f5153f272 payg(c6): real PaygWalletController + WalletCategorySummaryDao + tests
GET /api/v1/payg/wallet returns the snapshot the FE useWallet hook
consumes — derived from EntitlementService (spend / cap / period),
PaygTeamExtensions (subscription state), and the wallet_category_summary
view (per-category breakdown). Leader callers get the team roster +
per-member sub-caps; member callers see an empty roster.

PATCH /api/v1/payg/cap updates wallet_policy.cap_units (no Stripe call —
cap is application-layer, enforced via the entitlement guard) and
invalidates the team's snapshot cache so the next read reflects the
change immediately. Leader-only — authorised inside the method since the
team is derived from the caller, not a path variable.

Adds findPrimaryMembership(userId) to TeamMembershipRepository so the
wallet endpoint can resolve the caller's team + role in a single query.

Tests: 11-case pure-Mockito slice covering free vs subscribed, leader vs
member, no-cap, anonymous → 401, teamless → empty free snapshot, plus
the cap update endpoint's leader-only enforcement and cache invalidation.

Known dependency on PR #6532: stripeSubscriptionId stays null until the
payg_subscription_id column lands; "subscribed" derived from
stripe_customer_id presence as a stand-in. billableLimit fallback of 500
units mirrors EntitlementService.DEFAULT_FREE_TIER_UNITS until
pricing_policy.free_tier_units_per_cycle ships.
2026-06-09 14:14:32 +01:00
..
2026-06-08 10:50:55 +00:00
2026-06-08 10:50:55 +00:00
2026-06-08 10:50:55 +00:00