This graph maps how modules interact with each other — events, shared tables, data flows, and cascading changes. It answers: "If I change X, what else breaks?"
---
## Core Entity: `members` Table
The `members` table is the central hub. Nearly every module in the ERP references it.
Manages annual subscription billing for all active members and their dependents. Generates subscription records per financial year, tracks payment status, calculates late fines, and enforces the 5-year drop rule.
## System Responsibilities
1.**Annual Generation** — Create subscription rows for all active members + dependents each July
2.**Rate Resolution** — Look up year-specific rates from ServiceCatalog with RuleEngine fallback
3.**Payment Tracking** — Link subscriptions to payments when collected
4.**Overdue Management** — Mark unpaid past-FY subscriptions as overdue
5.**Late Fine Calculation** — Progressive fines for consecutive unpaid years
6.**Membership Drop** — Auto-drop members with 5+ consecutive unpaid years
7.**Reinstatement Window** — Track 12-month window for dropped member recovery
8.**Sync on Activation** — Auto-create subscription when member/dependent activated mid-year
4.**First-year members have NO subscription rows** — membership fee covers current FY; no rows created until next July
5.**First-year dependents have NO subscription rows** — addition fee covers current FY; no rows created until next July
6.**Waiver-acquired members skip initial sync** — their subscriptions handled separately
7.**All-or-nothing family payment** — subscription payment always covers ALL family members for the year (no individual row payment)
8.**Validation bypass for first-year** — MembershipValidationService, canPrintCarnet, checkSubscriptionBlock all bypass for members activated in current FY
9.**Grace period** — SUB_GRACE_MONTHS (default 3) before overdue fines start
10.**Progressive fines** — increase per consecutive unpaid year
11.**5-year drop rule** — 5 consecutive unpaid years = membership dropped
12.**Reinstatement window** — 12 months after drop to recover (requires board + full payment)
13.**Transfer handling** — target member gets current year marked paid; separated dependents' unpaid rows deleted
---
## Risk Areas
1.**SubscriptionGeneratorJob only runs July 1-7** — if missed, no subscriptions for the year until manual batch
2.**Dedup relies on unique index** — catches races but logs warnings
3.**fine_amount on subscription row** — not in a separate fines table, harder to audit
4.**syncForMember skips waiver-acquired** — potential gap if waiver logic doesn't create subs
5.**refreshForMember deletes unpaid rows** — if a dependent was incorrectly removed, subscription data is lost
6.**No partial payment** — paid_amount is either 0 or full amount