afterhours-shift-manager/tests/shared
Adam Moussa eedbdfd8d1 Add swap-acceptance (verified-swap) flow
/oncall swap no longer reassigns immediately. It now writes a pending SWAP
record and DMs the target Accept/Decline buttons; the shift only moves once
they accept.

- schedule.py: create_pending_swap / get_swap / mark_swap_verified /
  clear_swap (PK=SWAP, date/shift SK mirroring OVERRIDE, status + timestamps
  + expires_at for TTL). A new request supersedes a prior pending one.
- app.py: _handle_swap creates the pending swap + DMs the target (requires the
  target be Slack-linked; rejects self-swap). New module-level
  handle_swap_accept / handle_swap_decline + two @app.action registrations.
  Accept writes the override, repoints 3CX when it's the active shift, marks
  the swap verified, notifies the channel + requester. Decline clears it and
  DMs the requester. Lazy expiry: accept is rejected once the shift has started
  (_shift_start/_shift_started).
- blocks.py: build_swap_request_blocks (Accept/Decline) + build_swap_resolved_blocks.
- template.yaml: enable DynamoDB TTL on expires_at so abandoned pending swaps
  self-clean.
- tests: swap schedule methods, swap blocks, rewritten test_handle_swap
  (pending + DM, no immediate override), new test_swap_accept_decline. 174 passed.
- README: swap behavior + SWAP item type + TTL.

The verified SWAP status is what #84 (24h drop guard) will query.

Closes #83
2026-06-01 19:19:00 -04:00
..
test_blocks.py Add swap-acceptance (verified-swap) flow 2026-06-01 19:19:00 -04:00
test_ring_scheduler.py Add pytest suite and wire it into CI (#85) (#86) 2026-06-01 19:07:08 -04:00
test_schedule.py Add swap-acceptance (verified-swap) flow 2026-06-01 19:19:00 -04:00
test_secrets.py Add pytest suite and wire it into CI (#85) (#86) 2026-06-01 19:07:08 -04:00
test_three_cx_client.py Add pytest suite and wire it into CI (#85) (#86) 2026-06-01 19:07:08 -04:00