v0.12.1 — Unit Swap wizard, editable timeline, roster/tz fixes #54
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Each assignment row in the timeline now gets an inline edit (pencil) that opens a modal with `assigned_at`, `assigned_until`, and notes. Save calls the existing `PATCH /api/projects/{pid}/assignments/{aid}`; delete (for misclicks) calls the existing `DELETE`. Open-ended checkbox clears `assigned_until` and the endpoint flips status back to "active". Adds an "+ Add deployment record" button at the top of the timeline for backfilling historical windows when orphan events sit outside any assignment. Modal: project → location → assigned_at → assigned_until (optional open-ended) → notes. Backend: the `/locations/{loc}/assign` endpoint now accepts an `assigned_at` form field and a closed-window assignment. The previous blanket "location already has an active assignment" check is replaced with same-location overlap detection — closed historical windows that don't overlap an existing assignment are accepted (which is exactly the backfill case). After any save/delete the timeline reloads and the SFM-events list re-fetches so previously-orphaned events flip to "attributed" when their timestamp now falls inside an assignment window. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>The legacy RosterUnit.deployed flag drives heartbeat polling and benched-vs-deployed roster filters. Three workflows ended an assignment without flipping it, so the outgoing unit kept being polled and showed up as "deployed" forever: - swap endpoint (POST /locations/{loc}/swap) - unassign endpoint (POST /assignments/{aid}/unassign) - promote-pending endpoint (POST /deployments/pending/{id}/promote) All three now: close the previous active assignment, break the outgoing unit's modem pairing (both directions), and set `deployed = False` on the outgoing unit. Unassign and swap also clear the modem's back-reference. The promote-pending path additionally handles the case where the target location already has an active assignment — that previously silently created two active assignments at the same location. Now the old one is closed (assigned_until = pending capture time, status = completed), the old unit is benched and unpaired, and an "assignment_swapped" history row is written. Incoming unit gets `deployed = True` if it was on the bench. Verified live: triggered a swap via the existing endpoint and saw the outgoing unit flip True → False while the incoming flipped False → True. Test mutations rolled back. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Deployment timestamps were stored correctly as UTC but rendered raw — a 1:30 PM EDT swap displayed as "5:30" because the frontend sliced the naive UTC ISO string straight to the screen. Display side: deployment_timeline.py now converts every emitted timestamp (starts_at, ends_at, event_overlay.peak_pvs_at and last_event) through `utc_to_local()` using the user's configured timezone from UserPreferences before serializing. Frontend slice keeps working — it just slices a local-time string now. Write side (so the new edit / add-historical-assignment modals stay consistent): - PATCH /api/projects/{pid}/assignments/{aid} - POST /api/projects/{pid}/locations/{loc}/assign both now interpret a *naive* assigned_at / assigned_until ISO string as the user's local time and convert to UTC for storage via `local_to_utc()`. Explicit tz-aware strings ("...Z" or "...+00:00") skip the conversion so programmatic callers that already speak UTC keep working. Verified live: BE13121's stored 2026-01-28 18:06:29 UTC now serializes as 2026-01-28 13:06:29 in the timeline endpoint; PATCHing "2026-01-28T13:06:29" round-trips back to the same UTC value. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>CHANGELOG entry for the five commits that landed after the v0.12.0 tag: two features (Unit Swap wizard at /tools/unit-swap, editable deployment timeline on /unit/{id}) and two correctness fixes (RosterUnit.deployed now flips on swap/unassign/promote; deployment timeline now respects user timezone for both display and edits). No schema migrations. README bumped to v0.12.1 with new bullets for the post-v0.12.0 features and several already-shipped items that were missing from the list (SFM Event DB Manager, Deployment-History calendar + Gantt tabs, reusable location-map partial). backend/main.py VERSION constant bumped too.