Skip to content

fix(events): repair day-offs miscategorized as freeform#274

Merged
mindsers merged 2 commits into
mainfrom
fix/repair-orphaned-day-offs
Jul 20, 2026
Merged

fix(events): repair day-offs miscategorized as freeform#274
mindsers merged 2 commits into
mainfrom
fix/repair-orphaned-day-offs

Conversation

@mindsers

Copy link
Copy Markdown
Contributor

Summary

  • Adds app/database/migrations/20260721000000_repair_orphaned_day_offs — data-repair migration that re-links freeform events back onto the day-off template when they carry every day-off signal.
  • Root cause: 20260720100000_drop_event_kind step 2 required the day-off template to already exist per congregation to route off-kind events. In unseeded congregations the JOIN was a no-op, events kept templateId=NULL, and 20260720200000_seed_system_templates step 3 defaulted every orphan to freeform — permanently erasing the classification (kindId was dropped one step earlier).
  • Heuristic: freeform event with no EventPart, no EventServicePart, and endDate - startDate >= interval '20 hours'. createFreeformEvent combines a single date with startTime/endTime so real freeform events fit inside a calendar day; createDayOff from /me/days-off enforces endDate >= startDate + 1 day via the form's min. Idempotent — a second run finds nothing to update.

Symptom fixed: legacy day-offs no longer surface on /programs, and /programs/days-off shows them again.

Test plan

  • Local: fixture check — a 5-day freeform with no parts flipped to day-off; a 2-hour freeform stayed put
  • Idempotent — re-running against the repaired state updated 0 rows and emitted no NOTICE
  • Prod deploy: watch logs for Day-off recovery: re-linked N freeform event(s) …
  • Post-deploy smoke: confirm the recovered rows show on /programs/days-off and are absent from /programs

mindsers added 2 commits July 20, 2026 16:50
The 2026-07-20 EventKind → template migration series routed `off`-kind
events to the day-off template only when that template already existed
per congregation. In unseeded congregations the join was a no-op, the
events kept templateId=NULL, and 20260720200000_seed_system_templates
then defaulted every orphan to freeform — erasing the classification.

Adds a data-repair migration that moves freeform events with no parts,
no service parts, and a span >= 20 hours back onto the day-off template.
No shape createFreeformEvent produces matches (start and end share a
single calendar date), and every shape createDayOff produces does
(endDate >= startDate + 1 day). Idempotent.

Symptom: legacy day-offs surfaced on /programs and were absent from
/programs/days-off.
Addresses PR #274 review:
- Comment now credits both migrations' freeform fallbacks (drop_event_kind
  step 3 and seed_system_templates step 3) and refers to handleFreeformMode
  as the caller that combines date + times.
- Reframes "idempotent" as a one-shot repair — the migration table blocks
  re-execution, but a manual re-run against a DB with new long-freeform
  events would misclassify them.
- Adds a browser-only caveat on the >= 1 day floor (createDayOff only
  rejects startDate > endDate; the min attribute is HTML5).
- Notes the in-flight-import assumption.

Adds a second DO block that flips EventPart.hasConflict and
EventServicePart.hasConflict from false to true wherever an assignment's
event overlaps a day-off owned by the same member. While the day-offs
lived on the freeform template, refreshConflictFlags filtered them out
via template.key = 'day-off', so those overlaps never flipped the flag.
Re-linking (step 1) does not retrigger the refresh, so without this
backfill the phantom greens would persist until the member's next
absence create/delete.

Runs against every day-off (not only the ones re-linked) so any
pre-existing drift also gets repaired. Only false -> true, never
clears a legitimately-set true.

Verified against local fixtures: 5-day orphan freeform re-links to
day-off, 2-hour freeform stays put, overlapping assignment for the
day-off creator flips to hasConflict=true, idempotent on second run.
@mindsers
mindsers merged commit fd0fe52 into main Jul 20, 2026
7 checks passed
@mindsers
mindsers deleted the fix/repair-orphaned-day-offs branch July 20, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant