Adds a permanent, non-consumable premium unlock (EstadoEntitlement + PuertoCompras/ServicioComprasPlayBilling) that removes ads and unlocks alarm vacations, alarms past a 5-alarm free cap, recording start, and full Android Auto browsing. The phone equalizer stays free for everyone. - Entitlement is prefs-backed (compra_premium_v1), fail-open, and resolvable headlessly via esPremiumPersistido() for the Android Auto audio handler, which registers before runApp. - Android Auto reduced mode keeps the real root folder labels for free users; browsing into any of them (and playFromMediaId/playFromSearch/ skipToNext/skipToPrevious) is blocked at the getChildren/servicio_audio choke points, with a locked "Función Premium" item as the backstop. Current-station play/pause/stop stays untouched. A free -> premium transition actively invalidates the head unit's cached browse tree. - Ads (top banner + capped interstitial before adding a station or an alarm) are gated behind entitlement via ServicioAnuncios, using official Google test ad unit IDs pending AdMob provisioning. - Alarm cap UX shows an explanatory message with a secondary unlock action rather than a bare paywall jump; existing data is grandfathered. - 4 new localization keys translated across all 13 supported locales. Co-located tests use strict TDD (RED test before implementation) for every new pure-logic unit; full existing suite passes unchanged.
89 lines
4.2 KiB
Markdown
89 lines
4.2 KiB
Markdown
# Freemium Gating Specification
|
|
|
|
## Purpose
|
|
|
|
Define which features require premium entitlement, the free-tier alarm cap, grandfathering of existing content, and the non-punitive UX for hitting a limit. The equalizer on the phone is explicitly out of scope — it MUST stay free.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Gated Feature Set (Exactly 4)
|
|
|
|
The system MUST require premium entitlement for exactly: (1) creating alarm vacations, (2) starting a new station recording, (3) creating an alarm beyond the 5-alarm cap, and (4) full Android Auto browsing (see `android-auto-media`). The phone equalizer MUST NOT be gated under any circumstance.
|
|
|
|
#### Scenario: Free user uses the phone equalizer
|
|
- GIVEN a free-tier user
|
|
- WHEN they open and use the equalizer screen on the phone
|
|
- THEN it works fully, with no entitlement check and no upsell
|
|
|
|
#### Scenario: Free user attempts a gated action
|
|
- GIVEN a free-tier user
|
|
- WHEN they tap "add vacation range" or "start recording"
|
|
- THEN they see the paywall/upsell instead of the action completing
|
|
|
|
### Requirement: Alarm Count Cap At 5 (Free Tier)
|
|
|
|
`EstadoAlarmas.guardarAlarma` MUST count all alarms, enabled or not, and MUST reject creating a 6th alarm for a free-tier user via a distinct "limit reached" signal, separate from the existing `_error` field used for native scheduling failures.
|
|
|
|
#### Scenario: 6th alarm creation is blocked
|
|
- GIVEN a free-tier user already has 5 alarms (any enabled state)
|
|
- WHEN they attempt to create a 6th
|
|
- THEN `guardarAlarma` rejects it via the distinct limit signal, and no native scheduling is attempted
|
|
|
|
#### Scenario: Editing an existing alarm is unaffected
|
|
- GIVEN a free-tier user has exactly 5 alarms
|
|
- WHEN they edit one of those 5 (not create a new one)
|
|
- THEN the edit succeeds normally
|
|
|
|
#### Scenario: Premium user has no cap
|
|
- GIVEN a premium user
|
|
- WHEN they create a 6th or later alarm
|
|
- THEN it succeeds with no limit check
|
|
|
|
### Requirement: Alarm Cap UX Never Bare-Jumps To Paywall
|
|
|
|
Hitting the alarm cap MUST show an explanatory message with a secondary "unlock" action; it MUST NOT navigate directly to the paywall as the sole response to the attempt.
|
|
|
|
#### Scenario: Cap message with secondary action
|
|
- GIVEN a free-tier user hits the 5-alarm cap
|
|
- WHEN the limit signal is raised
|
|
- THEN the UI shows an explanatory message (e.g. "Has alcanzado el límite de 5 alarmas gratuitas") with a secondary button (e.g. "Desbloquear Premium")
|
|
- AND only tapping that secondary button navigates to the paywall
|
|
|
|
### Requirement: Grandfathering Of Existing Content
|
|
|
|
Alarms, vacations, and recordings created before the gate existed, or already exceeding the cap, MUST remain visible, usable, and editable-in-place. Only NEW creation past a limit or gate is blocked.
|
|
(Previously: no cap or gate existed, so this distinction did not apply.)
|
|
|
|
#### Scenario: Pre-existing alarms above the cap keep working
|
|
- GIVEN a device already has 7 alarms before this change ships
|
|
- WHEN the free-tier gate is active
|
|
- THEN all 7 alarms keep ringing and can be toggled/edited, and only a new 8th creation is blocked
|
|
|
|
### Requirement: Recording Start Gated, Management Stays Free
|
|
|
|
`EstadoGrabacion.iniciar` MUST require premium entitlement. Screens that view, play, or delete already-existing recordings MUST remain accessible regardless of entitlement.
|
|
|
|
#### Scenario: Free user starts a new recording
|
|
- GIVEN a free-tier user
|
|
- WHEN they tap the record action
|
|
- THEN they see the paywall instead of recording starting
|
|
|
|
#### Scenario: Free user manages existing recordings
|
|
- GIVEN a free-tier user with previously recorded files
|
|
- WHEN they open the recordings list
|
|
- THEN they can view, play, and delete those recordings normally
|
|
|
|
### Requirement: Purchase Entry Points At Every Gate Plus Settings
|
|
|
|
Every gated entry point MUST show a contextual upsell. Settings MUST additionally expose a persistent purchase/restore row.
|
|
|
|
#### Scenario: Contextual upsell at a gate
|
|
- GIVEN a free-tier user reaches any of the 4 gated entry points
|
|
- WHEN the gate blocks the action
|
|
- THEN a contextual purchase CTA is shown at that point
|
|
|
|
#### Scenario: Settings always shows a premium row
|
|
- GIVEN any user opens Settings
|
|
- WHEN the screen renders
|
|
- THEN it shows either a "buy premium" row (free tier) or a "premium active" state with restore access (premium tier)
|