docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Persist the exploration, proposal, spec, design, tasks, and verify/archive reports produced during the multi-device EQ, alarm-countdown, and notification-visual-polish SDD cycles.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# Proposal: Alarm Live Countdown
|
||||
|
||||
## Intent
|
||||
|
||||
Pre-notice notifications show hardcoded Spanish text ("Empieza en 30 minutos") regardless of locale or actual remaining time. Additionally, snooze dismissal silently fails when the alarm screen launches from a dead-app state via full-screen intent, leaving the modal visible after the user taps snooze.
|
||||
|
||||
These are user-facing quality issues: incorrect language breaks trust for non-Spanish users, and a stuck alarm screen is a blocking UX defect.
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- Compute actual remaining minutes at pre-notice fire time and display in notification
|
||||
- Use existing translated `durationMinutesOnly` ARB key pattern for l10n-ready text
|
||||
- Add a new ARB key for the pre-notice message with minute placeholder
|
||||
- Fix snooze dismissal on cold-start (dead-app) Navigator edge case
|
||||
|
||||
### Out of Scope
|
||||
- Per-minute live-updating notifications (AlarmManager chain, foreground service, WorkManager)
|
||||
- iOS notification changes (pre-notice is Android-only)
|
||||
- Snooze duration configuration
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `alarm-pre-notice-l10n`: Localized pre-notice notification text with computed remaining minutes
|
||||
|
||||
### Modified Capabilities
|
||||
- `alarm-snooze-dismiss`: Fix Navigator.pop() no-op on dead-app launch path
|
||||
|
||||
## Approach
|
||||
|
||||
**Feature 1 (Countdown text):** In `PluriWaveAlarmReceiver.showPreNoticeNotification()`, compute `(triggerAtMillis - System.currentTimeMillis()) / 60_000` to get remaining minutes. Replace the hardcoded string with a new ARB key (`preNoticeCountdown`) that accepts a `{minutes}` placeholder. Reuse the existing `durationMinutesOnly` pattern already translated across all 13 locales. Single notification, no update chain, no new services.
|
||||
|
||||
**Feature 2 (Snooze dismiss):** In `_posponer()`, replace `navigator.pop()` with `if (navigator.canPop()) navigator.pop() else SystemNavigator.pop()`. Two-line fix.
|
||||
|
||||
## Affected Areas
|
||||
|
||||
| Area | Impact | Description |
|
||||
|------|--------|-------------|
|
||||
| `android/.../PluriWaveAlarmReceiver.kt` | Modified | Compute remaining minutes, use l10n string |
|
||||
| `lib/pantallas/pantalla_alarma_sonando.dart` | Modified | canPop guard in `_posponer()` |
|
||||
| `lib/l10n/app_*.arb` (13 files) | Modified | New `preNoticeCountdown` key |
|
||||
|
||||
## Risks
|
||||
|
||||
| Risk | Likelihood | Mitigation |
|
||||
|------|------------|------------|
|
||||
| Kotlin code cannot access Flutter ARB strings directly | Med | Use Android string resources or pass formatted string via MethodChannel |
|
||||
| `SystemNavigator.pop()` closes entire app unexpectedly | Low | Only used when canPop is false (dead-app launch); app was not user-opened |
|
||||
| Negative remaining minutes if system clock drifts | Low | Clamp to minimum 1 minute |
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
Both changes are isolated. Revert the two commits (one per feature). Pre-notice reverts to hardcoded string; snooze reverts to current `pop()` behavior. No data migration, no schema changes.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- None. All affected APIs and keys already exist in the codebase.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] Pre-notice notification displays remaining minutes in the device locale
|
||||
- [ ] No hardcoded Spanish text in notification path
|
||||
- [ ] Snooze dismisses the alarm screen when launched from dead-app state
|
||||
- [ ] All 13 locale ARB files contain the new key
|
||||
- [ ] Existing tests pass; new tests cover both features
|
||||
Reference in New Issue
Block a user