Skip to content

Memos: add tag-alarms, a one-morning alarm armed by tapping an NFC tag - #130

Merged
mapgie merged 4 commits into
mainfrom
claude/nfc-alarm-scheduling-0m9cre
Sep 11, 2026
Merged

Memos: add tag-alarms, a one-morning alarm armed by tapping an NFC tag#130
mapgie merged 4 commits into
mainfrom
claude/nfc-alarm-scheduling-0m9cre

Conversation

@mapgie

@mapgie mapgie commented Sep 11, 2026

Copy link
Copy Markdown
Owner

What

A tag-alarm is a third kind of memo, for mornings with no fixed pattern: a dormant alarm with a linked NFC tag, a first ring and optional follow-ups later the same day (Office A: 5:15, 5:30, 5:45).

  • A tap on its tag (or Set for next in the sheet) arms the next time the first ring comes round: today if it is still ahead, tomorrow otherwise. The weekday is never consulted.
  • A tap never removes a ring. Tapping again is a no-op; tapping during a morning in progress leaves the pending follow-ups alone.
  • The morning plays out ring by ring. Snooze works as today and keeps the sequence. After the last ring the alarm is dormant again.
  • Feedback is a toast: "Office A: tomorrow 5:15 AM". If another tag-alarm is already set for the same morning, a dialog asks whether to turn it off. The tapped alarm is armed before the question, so a missed dialog never costs tomorrow's alarm.
  • Turning off is manual: Turn off in the sheet, swipe left on the card, or Stop for today on the ring screen while follow-ups are pending (Done only dismisses the ring on screen).
  • A tag has one job. Linking is by scanning in the sheet; an id a chore or another tag-alarm owns is refused, and the chore sheet refuses a tag-alarm's id in return. A background tap on a tag-alarm's tag no longer writes a Supabase scan row.

How

  • data/model/TagAlarm.kt: every rule as pure functions. Reminder.kt's needsScheduling / isDone / afterRing / afterDone / withScheduleAligned branch on isTagAlarm, so the alarm scheduler, AlarmReceiver, BootWorker and the snooze paths need no new alarm code. The morning advances through remindAt under a single alarm identity (LESSONS.md Visual refresh: typography hierarchy, 8pt spacing, and component polish #57).
  • tagalarm/TagAlarmService: the one place arming and turning off happen; reports same-morning conflicts for the dialog.
  • MainActivity resolves a scanned tag against tag-alarms first, on-device, before the chore path. A capture request for the sheet's "scan a tag" flow is plumbed through DashNavGraph.
  • AddReminderSheet: Tag-alarm switch, Follow-ups row, Tag row, Set for next / Turn off links, "Off · tap the tag to set" banner. Card badge reads "off" while dormant; a dormant alarm sorts last and never shows as Next Up.
  • Records are on-device (DataStore); new fields are all defaulted, so existing memos load unchanged. No Supabase or manifest changes.

Tests

TagAlarmModelTest pins the arming table (Tue 22:00 rings Wed, Tue 05:00 rings Tue, Sat 22:00 rings Sun), idempotence, the follow-up sequence, the snoozed re-ring, the dormant state, editing an armed alarm, conflicts and the toast/dialog wording. ReminderUiStateTest and ReminderDraftTest gain the list-state and draft cases.

Changelog

changelog/unreleased/tag-alarms.json, minor bump.

🤖 Generated with Claude Code

https://claude.ai/code/session_016rWgRBgBaGjrH7iWGmUeSv


Generated by Claude Code

A tag-alarm is a third kind of memo for mornings with no fixed pattern: a
dormant alarm with a linked NFC tag, a first ring and optional follow-ups
later the same day. A tap on the tag (or Set for next in the sheet) arms
the next time the first ring comes round, today or tomorrow, weekday
ignored; the morning plays out through remindAt and the alarm goes dormant
again after its last ring. A tap never removes a ring, so tapping repeatedly
is idempotent.

- data/model/TagAlarm.kt holds every rule as pure functions; Reminder.kt's
  needsScheduling / isDone / afterRing / afterDone / withScheduleAligned
  branch on it, so the existing alarm, boot and snooze paths need no new
  alarm code (LESSONS.md #57).
- tagalarm/TagAlarmService is the one place arming and turning off happen,
  and reports other tag-alarms set for the same morning so the caller can
  ask "Turn it off?" (TagAlarmConflictDialog).
- MainActivity resolves a scanned tag against tag-alarms first, on-device,
  before the chore path, and shows a toast with the alarm's first ring. The
  sheet links a tag by scanning (a capture request plumbed through the nav
  graph) and refuses ids a chore or another tag-alarm owns; the chore sheet
  refuses a tag-alarm's id in return.
- The sheet gains the Tag-alarm switch, a Follow-ups row, a Tag row and
  Set for next / Turn off links; the card says "off" while dormant; a swipe
  turns it off; the ring screen offers Stop for today while follow-ups are
  pending.
- Unit tests pin the arming table, idempotence, the follow-up sequence, the
  dormant state, conflicts and the wording.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016rWgRBgBaGjrH7iWGmUeSv
@mapgie
mapgie marked this pull request as ready for review September 11, 2026 08:24
… on the page ground

The Memos list gained a permission banner on main (#129) in the same rows
the tag-alarm capture plumbing touched; both are kept. The sub-screen
header is a Scaffold top bar the scroll column slides under, so it now
carries the page background instead of letting rows show through it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016rWgRBgBaGjrH7iWGmUeSv
… dump

supabase-kt's REST exception message carries the Postgres error on its
first line and then the URL, every header (apikey and bearer included) and
the HTTP method. The list screens and snackbars showed all of it. A
userFacingMessage() helper keeps the first line; every view model error
now goes through it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016rWgRBgBaGjrH7iWGmUeSv
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016rWgRBgBaGjrH7iWGmUeSv
@mapgie
mapgie merged commit 1685dee into main Sep 11, 2026
6 checks passed
@mapgie
mapgie deleted the claude/nfc-alarm-scheduling-0m9cre branch September 11, 2026 08:52
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.

2 participants