Commit c0da96c3 authored by Mahmoud Aglan's avatar Mahmoud Aglan

docs(subscriptions): add data migration section to architecture map

Documents the SubscriptionDataMigration service: phases, rate table,
production results, and root cause of orphaned person_ids.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent cc929837
...@@ -380,6 +380,40 @@ Financial year runs July to June: ...@@ -380,6 +380,40 @@ Financial year runs July to June:
--- ---
## 15. Data Migration (SubscriptionDataMigration) — Added 2026-07-03
A one-time migration service (`app/Modules/Subscriptions/Services/SubscriptionDataMigration.php`) that ensures complete subscription coverage for all members from their join date to present.
**CLI Commands:**
```bash
php cli.php subscriptions:migrate # Run the full migration
php cli.php subscriptions:migrate --dry-run # Preview without changes
php cli.php subscriptions:validate # Verify data integrity
```
**What it does (5 phases):**
1. **Fix orphaned person_ids**: Subscriptions with wrong `person_id` (e.g., member_id used instead of spouse_id). Matches by name, including archived records.
2. **Remove duplicates**: Exact (member_id + financial_year + person_type + person_id) duplicates — keeps lowest ID.
3. **Fix incorrect amounts**: Zero-amount non-exempt rows get corrected using historical rate table.
4. **Create missing subscriptions**: For each active member + all dependents, ensures subscription exists for every FY from join date to present. Past FYs get `status='overdue'`.
5. **Apply fines**: Uses `SubscriptionCalculator::calculateLateFine()` then distributes proportionally per row.
**Historical rate table (hardcoded in migration):**
| FY | Member/Spouse | Child/Temp |
|----|-------------|-----------|
| 2023/2024 | 410.00 | 185.00 |
| 2024/2025 | 410.00 | 185.00 |
| All other years | 492.00 | 222.00 |
**Results from first production run (2026-07-03):**
- 568 subscriptions created, 93 orphaned IDs fixed, 32 duplicates removed, 230 fines applied
- Final count: 1,140 total subscriptions across all FYs
- Validation: ALL CLEAN — no issues found
**Known limitation**: The `RetroactiveMembershipService` (line 714) has a fallback `$sub['person_id'] ?? $memberId` that can create orphaned records when person_index doesn't map correctly. This is the root cause of orphaned IDs. The data migration service cleans these up.
---
## Appendix: Files to Check Before Modifying Subscriptions ## Appendix: Files to Check Before Modifying Subscriptions
1. `app/Modules/Accounting/bootstrap.php` — Listens to `subscription.paid` for journal entries 1. `app/Modules/Accounting/bootstrap.php` — Listens to `subscription.paid` for journal entries
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment