50 lines
2.0 KiB
Markdown
50 lines
2.0 KiB
Markdown
Great—time-accurate historical data is exactly what the “effective-dated assignment” approach is for.
|
||
|
||
## Recommended flow (historical accuracy)
|
||
### 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 user’s 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 you’ll 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 user’s 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. |