docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s

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:
2026-07-04 12:42:11 +02:00
parent e5b6d8acb3
commit bccc5c48b8
64 changed files with 6020 additions and 0 deletions
@@ -0,0 +1,69 @@
# Proposal: Notification Visual Polish
## Intent
PluriWave's 3 native alarm notifications use generic Android system drawables (`ic_dialog_info`, `ic_lock_idle_alarm`) and carry no brand color, so they look unbranded in the status bar and shade. The audio/media notification sets the brand color but no explicit icon, so Android auto-silhouettes the full-color `mipmap/ic_launcher` into an illegible status-bar blob. This change gives all 4 notifications a single, legible, on-brand identity.
## Scope
### In Scope
- One new monochrome vector drawable: `android/app/src/main/res/drawable/ic_stat_pluriwave.xml` (equalizer-bars glyph, 24x24dp, white fill on transparent).
- Wire the icon into all 4 notification builders (3 Kotlin `setSmallIcon`, 1 Dart `androidNotificationIcon`).
- Add `.setColor()` with the shared cyan brand value `#21D4D9` to the 3 Kotlin alarm builders (audio notification already has it).
- Dart test asserting the new `androidNotificationIcon` config field.
### Out of Scope (deferred follow-up candidates)
- Action-button icons (snooze/stop/skip currently pass `0`).
- BigTextStyle / expanded layouts.
- Fallback artwork / large icon.
- NotificationChannelGroup topology changes.
## Capabilities
### New Capabilities
- None. This is presentation-only wiring; no new user-facing capability requirement is introduced.
### Modified Capabilities
- None. No spec-level behavior of `alarm-pre-notice-countdown` changes — timing, scheduling, and countdown text are untouched. Only icon/color presentation is altered.
## Approach
Hand-author one `<vector>` drawable (equalizer bars adapted from Material's Apache-2.0 `graphic_eq`, bold enough to read at status-bar size) since no image-generation tooling is available and vector XML is density-independent (no mipmap variants needed). Reference it from all 4 call sites via generic `drawable/ic_stat_pluriwave` resolution. Define the color literal once per Kotlin file (or a shared `@ColorInt` constant) and reuse across the 3 builders rather than duplicating. Extract the Dart icon string to a named top-level const so the existing `notification_color_test.dart` pattern extends cleanly.
Single shared cyan across all 3 alarm builders (not a second coral "meaning"): pre-notice and snooze already share one channel, and matching the shipped audio-notification cyan keeps the whole shade coherent. `setColor` edits are applied per-file (builders differ: `setSilent` vs `setFullScreenIntent`, distinct priorities) — no shared helper.
## Affected Areas
| Area | Impact | Description |
|------|--------|-------------|
| `android/app/src/main/res/drawable/ic_stat_pluriwave.xml` | New | Monochrome equalizer-bars vector, white fill, transparent bg. |
| `.../PluriWaveAlarmReceiver.kt:184` | Modified | Swap `ic_dialog_info``R.drawable.ic_stat_pluriwave`; add `.setColor()`. |
| `.../AlarmScheduler.kt:580` | Modified | Swap `ic_lock_idle_alarm` → new icon; add `.setColor()`. |
| `.../PluriWaveAlarmService.kt:390` | Modified | Swap `ic_lock_idle_alarm` → new icon; add `.setColor()`. |
| `lib/main.dart:17-23` | Modified | Add `androidNotificationIcon: 'drawable/ic_stat_pluriwave'` (via named const). |
| `test/tema/notification_color_test.dart` | Modified/New sibling | Assert new `androidNotificationIcon` field. |
## Risks
| Risk | Likelihood | Mitigation |
|------|------------|------------|
| Hand-authored glyph looks poor at small/low-DPI status-bar size | Med | On-device/emulator status-bar QA before ship; use bold bars, avoid thin strokes. |
| `setColor()` is advisory — OS may not fully tint | Med | Set expectation: best-effort branding, not pixel-exact across OS versions. |
| `R.drawable.ic_stat_pluriwave` not in scope in a Kotlin file | Low | All 3 files already use package-local `R`; confirm at apply (no `flutter build`). |
| No Kotlin test harness — native change unverifiable by unit test | High | Manual/on-device QA for the 3 Kotlin call sites; Dart test covers only config field. |
## Rollback Plan
Fully reversible via `git revert` of the change commit. Icon asset is a single additive file (deleting it restores prior state). Each Kotlin edit restores the original system drawable + removes `.setColor()`. The Dart edit removes one config field + its const. No migrations, no persisted state, no schema changes — nothing to undo beyond source reversion.
## Dependencies
- None external. Glyph derived from Material Design open-source icon (Apache 2.0), hand-transcribed as XML path data — no new package or asset dependency.
## Success Criteria
- [ ] `ic_stat_pluriwave.xml` exists and is a valid monochrome vector drawable.
- [ ] All 4 notification builders reference `drawable/ic_stat_pluriwave`.
- [ ] The 3 Kotlin alarm builders apply cyan `#21D4D9` via `.setColor()`.
- [ ] Dart test asserts `configuracionAudioService.androidNotificationIcon` equals the expected resource string; `flutter test` passes.
- [ ] `flutter analyze` clean; on-device QA confirms legible branded icons in status bar and shade.