main-backend/php_code/user-transfer-logic.md
2026-06-21 14:00:47 +00:00

2.0 KiB
Raw Blame History

Great—time-accurate historical data is exactly what the “effective-dated assignment” approach is for.

1) Model “which branch the user belonged to when”

Use a history table, e.g. user_branch_assignments:

  • user_id
  • branch_id
  • starts_at
  • ends_at (nullable; null = current)
  • timestamps

Your rule for history:

  • For any user_id, at a given timestamp, exactly one assignment row is “active” (starts_at <= t and (ends_at is null or t < ends_at)).

2) Model branch-specific activities against the assignment

For any activity that should be tied to the users branch “at the time it happened”, store:

  • user_branch_assignment_id (FK)
  • occurred_at (the activity time)
  • activity fields

When creating an activity at time occurred_at, you must pick the assignment row that was active at that time.

Transfer logic (what happens at transfer time)

At transfer time T:

  1. Close current assignment (branch A):
    • set ends_at = T
  2. Create new assignment (branch B):
    • set starts_at = T
    • ends_at = null

From then on:

  • old activities remain linked to the old assignment
  • new activities link to the new assignment

Query pattern youll use

  • “Current branch for a user”:
    • assignment where ends_at is null
  • “Activities for a user in branch X at time range” (historical):
    • join activities → user_branch_assignments and filter by branch_id

Laravel-specific implementation note (important)

When inserting an activity with occurred_at, do this in a transaction:

  • read the assignment active at occurred_at
  • create the activity pointing to user_branch_assignment_id

Optionally lock the users assignment rows to avoid edge-case races around the transfer timestamp.

If you share your current activity table name + the column you use for the activity time (e.g. created_at vs occurred_at), I can sketch the exact Laravel query/transaction structure.