# Cyclos Migration Verification Report

Last run: 2026-03-19
Source DB: `timebank_2026_03_16`
Target DB: `timebank_cc_2`
Command: `php artisan verify:cyclos-migration`

---

## Script Output

```
--- 1. Member counts ---
  PASS Active users: 2197
  PASS Inactive users: 995
  PASS Removed/deleted users: 51
  PASS Banks (L1+L2): 7
  PASS Active organizations: 55
  PASS Inactive organizations: 9

--- 2. Transaction counts ---
  PASS Imported transactions match Cyclos transfers: 32869
       (Total Laravel: 32913 = 32869 imported + 44 gift migrations + 0 currency removals)
  PASS No transactions with NULL account IDs: 0

--- 3. Account balances ---
  PASS Laravel system is balanced (net = 0): 0
  PASS Debit account: -7025.00h (diff: 0.0000h)
  PASS Community account: 4.47h (diff: 0.0167h)
  PASS Voucher account: 0.00h (diff: 0.0000h)
  PASS Organization account: 0.00h (diff: 0.0000h)
  PASS Gift accounts: 65.38h (diff: -0.0167h)
  PASS Work + Project accounts combined (remappings allowed): 6955.15h (diff: 0.0167h)

--- 4. Gift account cleanup ---
  PASS All gift accounts marked inactive: 0
  PASS All gift account balances are zero after migration: 0
  PASS Gift migration transactions go from gift → work account: 44

--- 5. Deleted profile cleanup ---
  PASS Removed Cyclos users are soft-deleted in Laravel: 51
  PASS Deleted users have zero remaining balance (tolerance: 6min): 0
  WARN Deleted users still have 8 account records (expected — kept for transaction history)
  INFO Currency removal transactions: 0

Summary: 20 PASS, 1 WARN
All checks passed!
```

---

## Notes

### WARN — Deleted users have account records
Expected behaviour. Accounts of deleted users are retained for transaction history integrity.
The balance check (check 5) confirms these accounts have zero balance.

### Small balance diffs in check 3 (~0.0167h = 1 min)
The Community, Gift, and Work+Project accounts show a ~1 minute diff. This is rounding
accumulation from `ROUND(amount * 60)` applied per transaction during import — Cyclos stores
amounts as decimal hours. The diffs are within the 0.1h tolerance and the overall system
balance is exactly 0. Per-account rounding errors exist on ~300 accounts (ranging from ±1 min
to +1158 min for Lekkernassuh with 29,222 transactions). This is a known open issue — see
next steps.

### Gift accounts
`migrate:cyclos-gift-accounts` was run after import. It transfers each gift account balance
to the owner's personal account and closes the gift account. All gift checks pass.

### Work + Project accounts combined
Some profiles were remapped between Cyclos account types 5 (work) and 7 (project) during
migration. The verify script checks these combined to allow for intentional remappings.

---

## Open Issue — Per-account rounding errors

Individual account balances can differ from Cyclos by a few minutes due to `ROUND(amount * 60)`
being applied per transaction. The aggregate balance checks pass because errors partially cancel
out across accounts, but individual users may see discrepancies.

Proposed fix: after import, adjust the largest transaction per affected account by the exact
difference. Every stored amount stays an integer; balances match Cyclos exactly.
