Files
TX/artifacts/api-server/tests
riyadhafraa 0a7acd683f Task #312: auto-sort executive-meetings schedule by start_time
User report (AR): "اريدها ترتيبها تلقائيا" — after a non-drag write
(typing 13:00 into a row sitting above a 12:00 row, creating a meeting
with an explicit start time, etc.) the schedule's daily_number stayed
frozen at the row's prior position, so the visible list was no longer
chronological. Fix: extend the existing `renumberDayByStartTime` helper
to every write path that touches start_time / meeting_date / status /
daily_number, so the day is always renumbered 1..N by start_time
(NULLS LAST, cancelled rows at the tail).

Server (artifacts/api-server/src/routes/executive-meetings.ts):
  - POST  /executive-meetings           — renumber after insert.
  - PATCH /executive-meetings/:id       — renumber when an order- or
    visibility-affecting field (startTime/endTime/meetingDate/status/
    dailyNumber) is in the payload. Cross-day moves renumber BOTH the
    source and destination day. Pre-allocates a fresh dailyNumber on
    the destination via nextDailyNumber(tx, newDate) before the UPDATE
    so the (meeting_date, daily_number) unique index does not collide
    when the row arrives on a day with existing meetings.
  - DELETE /executive-meetings/:id      — renumber so the day's `#`
    sequence stays gap-free.
  - POST  /executive-meetings/:id/duplicate — renumber the target day.
Existing postpone-minutes / reschedule / cancel paths already called
renumber and were left alone. Reorder POST is also untouched (its
slot-swap is the explicit user-driven order, not auto-sort).

Tests (artifacts/api-server/tests/executive-meetings.test.mjs, +9):
  - assertDayChronological() helper asserts 1..N + non-decreasing
    start_time + no duplicate dailyNumbers.
  - PATCH startTime later → row demoted (the user's exact scenario).
  - PATCH startTime earlier → row promoted to the top.
  - POST create with middle startTime slots between existing rows.
  - PATCH startTime=null sinks to the tail of visible rows.
  - Cancel pushes out / uncancel re-slots chronologically.
  - Cross-day PATCH meetingDate renumbers BOTH days.
  - DELETE leaves no `#` gap.
  - POST /duplicate slots clone at chronological position.
All 55 tests in executive-meetings.test.mjs pass.

Architect review (advisory, scope-bounded):
  - Concurrency: PATCH/DELETE read `existing` outside the transaction.
    Pre-existing convention in this file — only the cascade-bearing
    postpone-minutes/reschedule paths use SELECT FOR UPDATE. Matching
    existing pattern; tightening locking is a separate refactor.
  - Audit: renumber side-effect not echoed back into the audit row.
    Per task plan (`.local/tasks/auto-sort-schedule-by-time.md`),
    audit shape was intentionally kept minimal — the user-intent
    fields already capture the change.
2026-05-02 09:47:12 +00:00
..