fix(subscriptions): trial 14 dagar konsekvent i UI/docs/legal/butik
TRIAL_DAYS var redan 14 i koden men auth.trialNote (12 sprak), butiksmetadata, juridik-utkast, API-ref, exec-summary och UX-doc sa 7. Nu 14 overallt. Rorde EJ icke-trial 7-dagar (inbjudningslank, backup, S3-lifecycle, grace, retention). Beslut: Johan (battre onboarding).
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Skift adgangskode",
|
||||
"auth.resetTitle": "Vælg en ny adgangskode",
|
||||
"auth.resetTokenPlaceholder": "Indsæt koden fra e-mailen",
|
||||
"auth.trialNote": "7 dages fuld adgang – uden kort.",
|
||||
"auth.trialNote": "14 dages fuld adgang – uden kort.",
|
||||
"auth.verifyDoneBody": "Tak! Din konto er nu verificeret.",
|
||||
"auth.verifyDoneTitle": "E-mail bekræftet",
|
||||
"auth.verifyFailedBody": "Linket er ugyldigt eller udløbet. Anmod om et nyt fra profilen.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Passwort ändern",
|
||||
"auth.resetTitle": "Neues Passwort wählen",
|
||||
"auth.resetTokenPlaceholder": "Code aus der E-Mail einfügen",
|
||||
"auth.trialNote": "7 Tage voller Zugriff – ohne Karte.",
|
||||
"auth.trialNote": "14 Tage voller Zugriff – ohne Karte.",
|
||||
"auth.verifyDoneBody": "Danke! Dein Konto ist jetzt verifiziert.",
|
||||
"auth.verifyDoneTitle": "E-Mail bestätigt",
|
||||
"auth.verifyFailedBody": "Der Link ist ungültig oder abgelaufen. Fordere im Profil einen neuen an.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Change password",
|
||||
"auth.resetTitle": "Choose a new password",
|
||||
"auth.resetTokenPlaceholder": "Paste the code from the email",
|
||||
"auth.trialNote": "7 days of full access – no card required.",
|
||||
"auth.trialNote": "14 days of full access – no card required.",
|
||||
"auth.verifyDoneBody": "Thanks! Your account is now verified.",
|
||||
"auth.verifyDoneTitle": "Email confirmed",
|
||||
"auth.verifyFailedBody": "The link is invalid or has expired. Request a new one from your profile.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Cambiar contraseña",
|
||||
"auth.resetTitle": "Elige una nueva contraseña",
|
||||
"auth.resetTokenPlaceholder": "Pega el código del correo",
|
||||
"auth.trialNote": "7 días de acceso completo – sin tarjeta.",
|
||||
"auth.trialNote": "14 días de acceso completo – sin tarjeta.",
|
||||
"auth.verifyDoneBody": "¡Gracias! Tu cuenta está verificada.",
|
||||
"auth.verifyDoneTitle": "Correo confirmado",
|
||||
"auth.verifyFailedBody": "El enlace no es válido o ha caducado. Solicita uno nuevo desde tu perfil.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Vaihda salasana",
|
||||
"auth.resetTitle": "Valitse uusi salasana",
|
||||
"auth.resetTokenPlaceholder": "Liitä koodi sähköpostista",
|
||||
"auth.trialNote": "7 päivää täyttä käyttöä – ilman korttia.",
|
||||
"auth.trialNote": "14 päivää täyttä käyttöä – ilman korttia.",
|
||||
"auth.verifyDoneBody": "Kiitos! Tilisi on nyt vahvistettu.",
|
||||
"auth.verifyDoneTitle": "Sähköposti vahvistettu",
|
||||
"auth.verifyFailedBody": "Linkki on virheellinen tai vanhentunut. Pyydä uusi profiilista.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Changer le mot de passe",
|
||||
"auth.resetTitle": "Choisissez un nouveau mot de passe",
|
||||
"auth.resetTokenPlaceholder": "Collez le code reçu par e-mail",
|
||||
"auth.trialNote": "7 jours d'accès complet – sans carte.",
|
||||
"auth.trialNote": "14 jours d'accès complet – sans carte.",
|
||||
"auth.verifyDoneBody": "Merci ! Votre compte est vérifié.",
|
||||
"auth.verifyDoneTitle": "E-mail confirmé",
|
||||
"auth.verifyFailedBody": "Le lien est invalide ou expiré. Demandez-en un nouveau depuis votre profil.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Cambia password",
|
||||
"auth.resetTitle": "Scegli una nuova password",
|
||||
"auth.resetTokenPlaceholder": "Incolla il codice dall'email",
|
||||
"auth.trialNote": "7 giorni di accesso completo – senza carta.",
|
||||
"auth.trialNote": "14 giorni di accesso completo – senza carta.",
|
||||
"auth.verifyDoneBody": "Grazie! Il tuo account è verificato.",
|
||||
"auth.verifyDoneTitle": "Email confermata",
|
||||
"auth.verifyFailedBody": "Il link non è valido o è scaduto. Richiedine uno nuovo dal profilo.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Bytt passord",
|
||||
"auth.resetTitle": "Velg et nytt passord",
|
||||
"auth.resetTokenPlaceholder": "Lim inn koden fra e-posten",
|
||||
"auth.trialNote": "7 dager full tilgang – uten kort.",
|
||||
"auth.trialNote": "14 dager full tilgang – uten kort.",
|
||||
"auth.verifyDoneBody": "Takk! Kontoen din er verifisert.",
|
||||
"auth.verifyDoneTitle": "E-post bekreftet",
|
||||
"auth.verifyFailedBody": "Lenken er ugyldig eller utløpt. Be om en ny fra profilen.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Wachtwoord wijzigen",
|
||||
"auth.resetTitle": "Kies een nieuw wachtwoord",
|
||||
"auth.resetTokenPlaceholder": "Plak de code uit de e-mail",
|
||||
"auth.trialNote": "7 dagen volledige toegang – zonder kaart.",
|
||||
"auth.trialNote": "14 dagen volledige toegang – zonder kaart.",
|
||||
"auth.verifyDoneBody": "Bedankt! Je account is geverifieerd.",
|
||||
"auth.verifyDoneTitle": "E-mail bevestigd",
|
||||
"auth.verifyFailedBody": "De link is ongeldig of verlopen. Vraag een nieuwe aan via je profiel.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Zmień hasło",
|
||||
"auth.resetTitle": "Wybierz nowe hasło",
|
||||
"auth.resetTokenPlaceholder": "Wklej kod z e-maila",
|
||||
"auth.trialNote": "7 dni pełnego dostępu – bez karty.",
|
||||
"auth.trialNote": "14 dni pełnego dostępu – bez karty.",
|
||||
"auth.verifyDoneBody": "Dziękujemy! Twoje konto jest zweryfikowane.",
|
||||
"auth.verifyDoneTitle": "E-mail potwierdzony",
|
||||
"auth.verifyFailedBody": "Link jest nieprawidłowy lub wygasł. Poproś o nowy w profilu.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Alterar palavra-passe",
|
||||
"auth.resetTitle": "Escolha uma nova palavra-passe",
|
||||
"auth.resetTokenPlaceholder": "Cole o código do e-mail",
|
||||
"auth.trialNote": "7 dias de acesso completo – sem cartão.",
|
||||
"auth.trialNote": "14 dias de acesso completo – sem cartão.",
|
||||
"auth.verifyDoneBody": "Obrigado! A sua conta está verificada.",
|
||||
"auth.verifyDoneTitle": "E-mail confirmado",
|
||||
"auth.verifyFailedBody": "O link é inválido ou expirou. Peça um novo no perfil.",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"auth.resetSubmit": "Byt lösenord",
|
||||
"auth.resetTitle": "Välj nytt lösenord",
|
||||
"auth.resetTokenPlaceholder": "Klistra in koden från mejlet",
|
||||
"auth.trialNote": "7 dagars full tillgång – inget kort behövs.",
|
||||
"auth.trialNote": "14 dagars full tillgång – inget kort behövs.",
|
||||
"auth.verifyDoneBody": "Tack! Ditt konto är nu verifierat.",
|
||||
"auth.verifyDoneTitle": "E-postadressen är bekräftad",
|
||||
"auth.verifyFailedBody": "Länken är ogiltig eller har gått ut. Begär en ny från profilen.",
|
||||
|
||||
@@ -46,7 +46,7 @@ och tolkar men hittar aldrig på – vilket gör produkten trovärdig nog för a
|
||||
## Affärsvärde
|
||||
|
||||
Prenumeration via App Store/Google Play: **Household 79 kr**, **Family 129 kr**,
|
||||
**Large Household 169 kr** per månad, 7 dagars fri provperiod utan kort, användbar
|
||||
**Large Household 169 kr** per månad, 14 dagars fri provperiod utan kort, användbar
|
||||
gratisnivå (10 AI-skanningar/mån) som behåller användare i tratten.
|
||||
|
||||
Ett genomsnittligt svenskt barnhushåll slänger mat för tusenlappar per år och lägger
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ tryck bort. Svenska först. Stora tryckytor (min 48 pt). Grön/varm palett (`src
|
||||
5 steg, allt frivilligt, progressindikator: (1) primärt mål → (2) kosthållning +
|
||||
allergier (med löftet "rätter med dina allergener visas aldrig") → (3) kroppsdata för
|
||||
kalorimål, med icke-medicinsk-disclaimer → (4) hushåll: skapa/gå med via kod/hoppa över →
|
||||
(5) enkelt vs exakt läge (§5), kombinerbart. Registrering startar 7-dagars trial utan kort.
|
||||
(5) enkelt vs exakt läge (§5), kombinerbart. Registrering startar 14-dagars trial utan kort.
|
||||
|
||||
## Flikarna
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Fel: `{ "error": { code, message, details?, correlationId } }`. Rate limit 300/m
|
||||
|
||||
| Metod | Path | Beskrivning |
|
||||
| ----- | ------------------------ | --------------------------------------------------------------- |
|
||||
| POST | /v1/auth/register | Skapa konto; startar 7-dagars trial; returnerar tokens |
|
||||
| POST | /v1/auth/register | Skapa konto; startar 14-dagars trial; returnerar tokens |
|
||||
| POST | /v1/auth/login | Logga in |
|
||||
| POST | /v1/auth/refresh | Rotera refresh-token (återanvändning → hela familjen revokeras) |
|
||||
| POST | /v1/auth/logout | Revokera alla sessioner |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Del 13 – Subscriptions
|
||||
|
||||
Planer (spec §45): Household 79 kr (3 pers), Family 129 kr (6), Large Household 169 kr (12).
|
||||
Fair use-kvoter för AI: 300/600/1000 skanningar/mån. Gratis: 10. Trial: 7 dagar full
|
||||
Fair use-kvoter för AI: 300/600/1000 skanningar/mån. Gratis: 10. Trial: 14 dagar full
|
||||
tillgång (Family-nivå) utan kort, startar vid registrering (spec §46).
|
||||
|
||||
## Arkitekturprincip
|
||||
|
||||
@@ -27,7 +27,7 @@ utifrån det ni faktiskt har hemma, vad som bör användas snart och vad ni gill
|
||||
• Full insyn: "Vad {NAMN} vet om mig" går att rätta, pausa och radera
|
||||
|
||||
Gratis: 10 AI-skanningar/månad, manuellt lager, sparade recept och enkel loggning.
|
||||
Premium (7 dagar gratis, inget kort): obegränsat lager, veckoplan, delning och
|
||||
Premium (14 dagar gratis, inget kort): obegränsat lager, veckoplan, delning och
|
||||
fler AI-skanningar.
|
||||
|
||||
**Nyckelord (100, App Store):**
|
||||
@@ -58,7 +58,7 @@ what you like.
|
||||
• Full transparency: "What {NAME} knows about me" can be corrected, paused and deleted
|
||||
|
||||
Free: 10 AI scans/month, manual inventory, saved recipes and simple logging.
|
||||
Premium (7-day free trial, no card): unlimited inventory, week planning, sharing
|
||||
Premium (14-day free trial, no card): unlimited inventory, week planning, sharing
|
||||
and more AI scans.
|
||||
|
||||
**Keywords:**
|
||||
|
||||
@@ -110,7 +110,7 @@ personuppgiftsbiträdesavtal. Inga uppgifter säljs eller delas för marknadsfö
|
||||
5. **Användarinnehåll**: recept du publicerar modereras. Du garanterar att du
|
||||
har rätt till innehåll du laddar upp; upphovsrättsintrång tas bort.
|
||||
6. **Prenumerationer**: köp och förnyelser hanteras av App Store/Google Play
|
||||
enligt deras villkor; provperioden är 7 dagar utan kort.
|
||||
enligt deras villkor; provperioden är 14 dagar utan kort.
|
||||
7. **Ansvarsbegränsning**: tjänsten tillhandahålls "i befintligt skick";
|
||||
ansvar begränsas till vad tvingande lag medger.
|
||||
8. **Ändringar**: väsentliga villkorsändringar meddelas i appen minst 30 dagar
|
||||
|
||||
@@ -61,7 +61,7 @@ export function computeEntitlements(
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Trial: 7 dagar full tillgång utan kort (spec §46). Family-nivå under trial.
|
||||
// 2. Trial: 14 dagar full tillgång utan kort (spec §46). Family-nivå under trial.
|
||||
if (trial && trial.endsAt > now) {
|
||||
const def = PLAN_DEFINITIONS.family;
|
||||
return {
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("entitlements (spec §45–47)", () => {
|
||||
);
|
||||
expect(ent.plan).toBe("free");
|
||||
});
|
||||
it("trial ger full tillgång i 7 dagar (spec §46)", () => {
|
||||
it("trial ger full tillgång i 14 dagar (spec §46)", () => {
|
||||
const start = new Date("2026-08-01T00:00:00Z");
|
||||
const ent = computeEntitlements(
|
||||
null,
|
||||
|
||||
Reference in New Issue
Block a user