# Legacy Data Migration Plan

The supplied database should be migrated in a controlled ETL step, not imported directly into the new Laravel schema.

## Identifier mapping
1. Preserve each existing `users.user_id` when valid and unique. Generate `USR-*` only for users without one.
2. Build an in-memory/database mapping from legacy numeric `users.id` => public `users.user_id`.
3. Convert legacy `products.merchant_id` to `products.merchant_user_id` and generate a new `product_id` for every product.
4. Generate `investment_id`, `resale_id`, `ticket_id`, `message_id`, wallet transaction IDs and lifecycle event IDs.
5. Convert investment/resale references to public business IDs using the mapping table.

## Wallet reconciliation
The legacy database has more than one wallet row for some numeric users. Do not blindly sum, select newest, or overwrite balances. Reconcile each affected user against transaction evidence and operational records, then create exactly one wallet row per public `user_id`. Import the opening balance as an explicit `wallet_transactions` opening-balance entry so the migrated amount is auditable.

## Historical snapshots
For every migrated investment, store a JSON snapshot containing the product, investor and merchant information available at migration time. This prevents historical lifecycle pages from breaking if a product/user table is later removed.

## Support migration
Map `supporttickets.user_id` to public user IDs where possible. Keep the existing human-facing ticket number where unique; otherwise generate a new `TKT-*` ID and store the legacy number in metadata during the ETL process. Move `chatmessages` into `support_messages` and retain sender, message, timestamps and attachments.

## Validation before cutover
- Every user has one unique `user_id`.
- Every product has one unique `product_id`.
- Every wallet has one unique `user_id`.
- Sum of reconciled wallet opening balances equals the approved migration control total.
- Product available quantities reconcile with purchased/resold quantities.
- All active investments resolve to an investor, merchant and product snapshot.
- Support ticket message counts match the legacy system.
