Test Plan: Dues Management

♻️ Reconciled against current code — 2026-07-01. Confirmed still accurate: the dues amount is a single global value (TenantDuesSettings.annualAmountCents) for ANNUAL members, NOT per-membership-type; there is no "Billing Cycle" (Monthly/Quarterly/Annual) field in dues settings itself (billing period lives on MembershipType.period); the bulk-dues endpoint is POST /api/billing/internal/dues/run (the old /admin/dues/generate-bulk does not exist); dues settings live on the "Finance & Billing" page at /admin/settings/finance?tab=dues; POST /dues/runs and GET /dues/summary are still 501 stubs. New correction: QUARTERLY membership types DO have a per-type dues amount — the type's own amountCents is billed as-is every quarter, it does not derive from the global annual amount (see the green banner below, #504).
🆕 New on stage — 2026-06-19 → 2026-07-01.
🎉 New on stage — 2026-06-15 (accounting milestone, !136). The late-fee engine + config is live and testable — reconfirmed unchanged as of 2026-07-01: late-fee config (#178) persists on save (it previously got stripped), and overdue invoices generate a late-fee child invoice once (#153/#158, unique-index guarded). Config UI is on the live DuesSettingsTab (#261). See the Jun 15 release note for the full regression scope. Payment gateway remains inert — use manual "Record Payment", not a live charge.

1. The dues amount model (read this first)

There are two separate amount fields that can diverge: Do not test a "per-membership-type dues amount in Dues Settings" — it doesn't exist there. The old guide's per-type dues table (Regular/Associate/Student/Corporate/Founding in Dues Settings) is wrong.

Exception as of #504: a member on a QUARTERLY membership type is billed the type's own amountCents every quarter (not the global annual amount, not annual÷4) — the global setting only governs ANNUAL members without a type override. A LIFETIME type's amountCents is a one-time join charge and is never touched by the recurring dues job at all. See the green banner above and TC-DUES-004.

2. Dues settings UI & fields

Route: /admin/settings/finance?tab=dues — page title "Finance & Billing", tab "Dues Settings". (Legacy /admin/settings/dues and the Settings-Hub "Dues Settings" card redirect here.) Fields:

FieldUI label
annualAmountCentsAnnual Dues Amount (whole units, e.g. 15000)
fiscalYearStartMonthFiscal Year Starts (month dropdown; RCME seeded = July)
prorationEnabledEnable proration for mid-year joins (checkbox)
gracePeriodDaysPayment Grace Period (days, 0–365; seeded 30)

No "Billing Cycle" selector exists in dues settings. A Monthly/Annual Billing Period exists only per-type on Member Settings → Membership Types (/admin/members/settings?tab=types).

3. Dues generation (bulk)

UI: /admin/reports/dues-summary — page "Dues & Billing Summary" (ADMIN only). A "Create dues run" form (Label, Period key, Amount, Currency, Due date) generates invoices for applicable members; the page also shows a per-period collection table.

ActionEndpointGuard
Bulk dues run (real)POST /api/billing/internal/dues/run — body { period, dryRun?, memberIds? }logged in (handler checks user)
Per-member: previewGET /api/billing/admin/members/:memberId/dues/calculateFINANCE:VIEW:dues
Per-member: create dues invoicePOST /api/billing/admin/members/:memberId/dues — body { period, overrideAmountCents?, dueAt? }FINANCE:EDIT:dues
Per-member: historyGET /api/billing/admin/members/:memberId/duesFINANCE:VIEW:dues
Dues settings get/saveGET /api/billing/admin/settings/dues · save via the Finance & Billing pageFINANCE:VIEW/EDIT:dues
Do not use: POST /api/billing/admin/dues/generate-bulk (never existed). Also note POST /api/billing/dues/runs and GET /api/billing/dues/summary are 501 stubs — not usable.
#504 — the bulk dues-run member query silently excludes LIFETIME members (membershipType: { period: { not: 'LIFETIME' } } in duesJob.service.ts) — this is by design, not a bug: they never owe recurring dues. QUARTERLY members are included and billed their type's own amount (§1). See TC-DUES-004.

4. Seeded data

5. Test Cases

TCTopicDetailed
TC-DUES-001Dues Settings Configurationdetailed
TC-DUES-002Dues Invoice Generationdetailed
TC-DUES-003Dues Payment & Renewaldetailed
TC-DUES-004🆕 Quarterly / Lifetime Dues Generation (QUARTERLY cadence, LIFETIME exclusion + null-date safety, #527 manual-dues activation)detailed