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,60 @@
# Tasks: Notification Visual Polish
## Review Workload Forecast
| Field | Value |
|-------|-------|
| Estimated changed lines | ~90-120 (1 new XML ~6 lines, 1 new Kotlin object ~6 lines, 3x 2-line Kotlin edits, 2-line Dart edit, ~8-line Dart test) |
| 400-line budget risk | Low |
| Chained PRs recommended | No |
| Suggested split | Single PR |
| Delivery strategy | ask-on-risk |
| Chain strategy | pending |
Decision needed before apply: No
Chained PRs recommended: No
Chain strategy: pending
400-line budget risk: Low
### Suggested Work Units
| Unit | Goal | Likely PR | Notes |
|------|------|-----------|-------|
| 1 | Full change (drawable + brand const + 3 Kotlin wire-ups + Dart wire-up + Dart test + QA) | PR 1 | Single PR, well under 400-line budget; presentation-only, low blast radius |
## Phase 1: Foundation (drawable + brand constant)
- [ ] 1.1 Create `android/app/src/main/res/drawable/ic_stat_pluriwave.xml` — 24x24dp `<vector>`, Material `graphic_eq` pathData, `#FFFFFF` fill (exact content per design doc). *Satisfies: proposal "New monochrome vector drawable"; design File Changes.*
- [ ] 1.2 Create `android/app/src/main/kotlin/es/freetimelab/pluriwave/NotificationBrand.kt``object NotificationBrand { @ColorInt const val CYAN: Int = 0xFF21D4D9.toInt() }`, package `es.freetimelab.pluriwave`, import `androidx.annotation.ColorInt`. *Satisfies: design "Kotlin color constant" decision; proposal ".setColor() cyan #21D4D9".*
## Phase 2: Dart Wiring (TDD — RED-GREEN-REFACTOR)
- [ ] 2.1 **RED**: Add test to `test/tema/notification_color_test.dart` asserting `configuracionAudioService.androidNotificationIcon == 'drawable/ic_stat_pluriwave'`, mirroring existing `notificationColor` test style. Run `flutter test test/tema/notification_color_test.dart` — confirm it fails (field doesn't exist yet). *Satisfies: spec Scenario "Audio notification config declares the branded monochrome icon".*
- [ ] 2.2 **GREEN**: In `lib/main.dart`, add `const androidNotificationIconResource = 'drawable/ic_stat_pluriwave';` near `configuracionAudioService` (L13-17 region), then add `androidNotificationIcon: androidNotificationIconResource,` field to the `AudioServiceConfig(...)` constant (L17-23). Run `flutter test test/tema/notification_color_test.dart` — confirm it passes. *Satisfies: spec Requirement "Audio Notification Icon Resource".*
- [ ] 2.3 **REFACTOR**: Run `flutter analyze` — confirm clean, no unused-const or formatting warnings on the touched lines.
- [ ] 2.4 Add second assertion to the same test verifying `androidNotificationIcon` differs from `'mipmap/ic_launcher'`. Run full test file again — confirm both assertions pass. *Satisfies: spec Scenario "Audio notification icon is distinct from the default launcher fallback".*
## Phase 3: Kotlin Wiring (code-inspection only — no test harness)
> No JVM/Robolectric/instrumented test infra exists in this repo for `NotificationCompat.Builder` chains. These tasks are verified by code inspection + Kotlin compile, NOT by automated tests. Functional correctness is confirmed exclusively in Phase 4 (manual/on-device QA).
- [ ] 3.1 In `PluriWaveAlarmReceiver.kt:184`, replace `.setSmallIcon(android.R.drawable.ic_dialog_info)` with `.setSmallIcon(R.drawable.ic_stat_pluriwave)`; add `.setColor(NotificationBrand.CYAN)` immediately after. *Satisfies: design "MODIFY PluriWaveAlarmReceiver.kt L184".*
- [ ] 3.2 In `AlarmScheduler.kt:580`, replace `.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)` with `.setSmallIcon(R.drawable.ic_stat_pluriwave)`; add `.setColor(NotificationBrand.CYAN)` immediately after. *Satisfies: design "MODIFY AlarmScheduler.kt L580".*
- [ ] 3.3 In `PluriWaveAlarmService.kt:390`, replace `.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)` with `.setSmallIcon(R.drawable.ic_stat_pluriwave)`; add `.setColor(NotificationBrand.CYAN)` immediately after. *Satisfies: design "MODIFY PluriWaveAlarmService.kt L390".*
- [ ] 3.4 Code-inspect all 3 edits: confirm no new imports needed (same-package unqualified `R` access, `NotificationBrand` same-package), confirm each builder chain still compiles logically (no dangling `.` chain breaks). Run `./gradlew :app:compileDebugKotlin` (or project's Kotlin compile task) — confirm success.
## Phase 4: Manual / On-Device QA (mandatory — no automated coverage for Kotlin builders)
- [ ] 4.1 Build and install debug APK on a physical device or emulator (Android 8.0+ recommended, matches `setColor` advisory behavior range).
- [ ] 4.2 Trigger pre-notice alarm notification (`PluriWaveAlarmReceiver`, channel `pluriwave_alarm_pre_notice`) — confirm status bar icon renders as legible equalizer glyph, NOT a solid blob/silhouette.
- [ ] 4.3 Trigger snooze countdown notification (`AlarmScheduler`, same channel) — confirm same icon + cyan tint where OS honors `setColor`.
- [ ] 4.4 Trigger alarm-fire/ringing notification (`PluriWaveAlarmService`, channel `pluriwave_alarm_fire_v2`) — confirm same icon + cyan tint.
- [ ] 4.5 Start radio playback to trigger the audio/media notification — confirm `drawable/ic_stat_pluriwave` renders (not `mipmap/ic_launcher` silhouette) and cyan brand color is applied.
- [ ] 4.6 Cross-check all 4 notifications side-by-side in the notification shade — confirm consistent icon glyph and consistent cyan `#21D4D9` across all of them.
- [ ] 4.7 Record QA result (pass/fail + device/OS version) in the PR description before merge.
## Phase 5: Verification
- [ ] 5.1 Run full Dart test suite (`flutter test`) — confirm no regressions outside the 2 new assertions.
- [ ] 5.2 Run `flutter analyze` on the full project — confirm clean.
- [ ] 5.3 Confirm all 4 success criteria from the proposal are checked off: valid vector XML, all 4 builders reference the drawable, 3 Kotlin builders apply cyan, Dart test passes.