fix(bienvenida): wire the welcome screen into the first-launch flow

This commit is contained in:
2026-07-29 15:49:44 +02:00
parent f3d744aeed
commit 2959941485
6 changed files with 265 additions and 8 deletions
@@ -16,6 +16,11 @@
> **WU15b was added mid-apply, not planned upfront** — WU15 shipped `PantallaGrabaciones` (the recordings library)
> fully tested but reachable from nowhere in the app. WU15b (below, after WU15's section) is the coordinator-ruled fix
> that wires it into Settings navigation. It is small and does not change the 18-commit delivery model's shape.
> **WU17b was added mid-apply, not planned upfront — same shape as WU15b.** WU17 shipped `PantallaBienvenida` (the
> welcome screen) fully tested but reachable from nowhere in the app (`rg "PantallaBienvenida" lib/app.dart lib/main.dart`
> found nothing). WU17b (below, after WU17's section) wires it into the genuine first-launch flow and establishes how
> it coexists with the pre-existing, unrelated `PluriOnboardingDialog` ("what's new" modal). It is small and does not
> change the 18-commit delivery model's shape.
> Strict TDD is ON. Runner: `flutter test`. `flutter analyze` and a **scoped** `dart format` gate every commit.
> **`flutter build` is never run.**
>
@@ -1058,6 +1063,61 @@ real capability living in the header, not decorative chrome).
`lib/l10n/app_*.arb` or `lib/`.
- [x] 17.7 Verify — all 3 scenario tests green; grep scan clean.
## WU17b — Wire the welcome screen into the first-launch flow
**Not in the original plan — added to close the WU17 gap noted above, same shape as WU15/WU15b.** WU17 built
`PantallaBienvenida` fully tested and committed, but left it unreachable from the app: `rg "PantallaBienvenida"
lib/app.dart lib/main.dart` found nothing. This work unit exists solely to fix that.
**Commit**: `fix(bienvenida): wire the welcome screen into the first-launch flow`
**Depends on**: WU17
**Spec refs**: `onboarding-welcome` — Full-Screen Welcome Route (reachability; the render/content/no-monetization/CTA
scenarios stay WU17's own, unmodified)
**Verify**: `flutter test test/servicios/servicio_bienvenida_test.dart test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart test/pantallas/pantalla_bienvenida_test.dart test/widget_test.dart && flutter analyze && dart format --set-exit-if-changed $(git diff --cached --name-only --diff-filter=ACM HEAD -- '*.dart')`
**New tests**: `test/servicios/servicio_bienvenida_test.dart`, `test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart`
**Modified tests**: none (WU17's own `pantalla_bienvenida_test.dart` re-run unmodified as a regression check)
**Coexistence ruling applied.** `PluriOnboardingDialog` (an unrelated, pre-existing "what's new"/help-content modal
loaded from markdown assets) is NOT deleted, merged, or replaced — first-launch welcome and a what's-new modal are
different things, confirmed by reading `assets/content/onboarding/en.md`: it is a detailed feature-reference
walkthrough plus per-version update notes, structurally different content from the welcome screen's 3-bullet
marketing intro. Both now run from `app.dart`'s `_PaginaPrincipalState`, in this order on every cold start: the
welcome screen's once-ever check resolves FIRST, then the pre-existing what's-new dialog's own independent
per-version due-or-not check runs exactly as it did before this WU. Sequencing (not two independent fire-and-forget
calls) is what prevents the two from ever racing onto the screen at the same time.
- [x] 17b.1 RED — `test/servicios/servicio_bienvenida_test.dart`: a new `ServicioBienvenida` (mirroring
`ServicioContenidoApp`'s injectable-`SharedPreferences`, versioned-key convention, S3-R4) is due before it has
ever been marked seen, is not due after `marcarBienvenidaVista()`, and respects a seen flag already persisted
by a prior launch (`SharedPreferences.setMockInitialValues`).
- [x] 17b.2 RED — `test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart`: a new
`PantallaBienvenida.mostrarSiProcede(context)` static method (mirroring `PluriOnboardingDialog.mostrarSiProcede`'s
check-then-show-then-mark-seen shape) pushes the welcome screen on a first launch (no seen flag persisted), does
NOT push it when the seen flag is already persisted, and — in one continuous session — persists the flag after
being shown once so a later check in the same run skips it.
- [x] 17b.3 GREEN — created `lib/servicios/servicio_bienvenida.dart` (`ServicioBienvenida`, key
`pluri_bienvenida_vista_v1`, plain one-time boolean — no version comparison needed, unlike
`ServicioContenidoApp`, since this welcome is a single first-impression surface, not a per-version one).
- [x] 17b.4 GREEN — added the static `PantallaBienvenida.mostrarSiProcede(BuildContext)` method to the existing
`pantalla_bienvenida.dart` file (no new wrapper class needed — unlike `PluriOnboardingDialog`, there is only one
call shape here); updated the class doc comment to describe how it coexists with `PluriOnboardingDialog`.
- [x] 17b.5 GREEN — wired `app.dart`: imported `pantalla_bienvenida.dart`; renamed the existing
`_onboardingInicialSolicitado` guard flag to `_flujoPrimerLanzamientoSolicitado` (it now covers the combined
sequence, not only the dialog); added `_mostrarFlujoPrimerLanzamiento()`, which awaits
`PantallaBienvenida.mostrarSiProcede(context)` then calls the pre-existing, untouched
`_mostrarOnboardingInicial()` — replacing the single `unawaited(_mostrarOnboardingInicial())` call site with
`unawaited(_mostrarFlujoPrimerLanzamiento())`.
- [x] 17b.6 REFACTOR — confirmed `_mostrarOnboardingInicial()`'s own body (900ms delay, `_alarmaSonandoActiva` guard,
`PluriOnboardingDialog.mostrarSiProcede` call) is byte-for-byte unchanged — only its call site moved one level
deeper into the new sequencing method. No scenario in `PantallaBienvenida`'s own WU17 test file needed to
change (all 3 pass unmodified, confirming the CTA/content/no-monetization behavior is untouched).
- [x] 17b.7 Verify — scoped suite green: 13/13 (3 `servicio_bienvenida_test.dart` + 3
`pantalla_bienvenida_primer_lanzamiento_test.dart` + 3 `pantalla_bienvenida_test.dart` [byte-identical,
unmodified] + 4 `widget_test.dart`). `flutter analyze`: 1 issue, identical to baseline. Scoped `dart format`:
reformatted 1 of 5 touched files (whitespace-only string-literal wrapping), stable on re-run. Literal-encoding
scan: one console-rendering false positive on the pre-existing "días" string (verified byte-correct UTF-8 via a
direct file read with the encoding pinned), zero real corruption.
## WU18 — i18n batch (all 13 locales)
**Commit**: `feat(i18n): add redesign strings and translate Escuchar rename to 11 locales`