Privacy Policy for Mëso Shqip
This page is the privacy policy exactly as it sits in the project's own source folder, reproduced word for word. It is written in one place and shown here — the two cannot drift apart.
Source: docs/juridisk/01-personvernerklaering.en.md · Version 1.0 · Draft of 10 August 2026 · Applies to app version 3.15.0 and later
This is a draft
The text below has not been reviewed by a lawyer, and it contains fields the owner still has to fill in — they are marked in red. This site must not go live, and no store listing may point here, until the fields are filled in and the text has been reviewed.
The build tool counts them: 0 fields are still open.
Version 1.0 · Draft of 10 August 2026 · Applies to app version 3.15.0 and later
⚠️ This is a draft that must be reviewed by a qualified lawyer before publication. It was written by a non-lawyer, grounded in what the code actually does. See
docs/juridisk/00-LES-FORST.mdfor the open questions and for the gaps between this text and the code as it stands today. The Norwegian version governs if the two ever disagree.
The short answer
If you use the app for free, we send nothing anywhere. There is no account, no sign-in and no server to send anything to. Everything your child does — every word, every medal, every streak — stays on the device. We cannot see it, because we never receive it.
That is not an accident or a temporary state. It is the single most important design decision in the app, and it was made because the app is used by children aged three to twelve. A child under 13 (16 in Germany, 14 in Austria) cannot consent to anything on their own, and the simplest way to handle a child's personal data correctly is not to have any.
If you buy the full version, you create one account — yours, not your child's. We need your email address to link the purchase to you and to sync progress across your family's devices. The child still has only a nickname that you choose. We never ask for a child's full name, date of birth, age, email address or location.
The rest of this document is the detail.
1. Who the controller is
| Controller | Arleal AS |
| Company registration number | 934 556 534 |
| Address | Nådlandsberget 31, 4034 Stavanger, Norge |
| Privacy email | personvern@mesoshqip.eu |
| Telephone | +47 458 09 350 |
| Data Protection Officer | Vi har vurdert kravet i GDPR artikkel 37 og har ikke plikt til å utpeke personvernombud. Vurderingen er dokumentert og kan utleveres på forespørsel. |
| UK representative (UK GDPR Art. 27) | Ikke aktuelt — appen selges ikke i Storbritannia |
Write to us about anything in this document. We answer in Norwegian, German, English and Albanian, within one working day for ordinary questions and within 30 days at the latest for formal requests under Chapter III of the GDPR.
2. The free tier: no personal data leaves the device
Without a purchase, the app makes no network calls to us at all — not at startup, not during use, not in the background.
All content — 999 words, 186 sentences, 36 letters, 1,216 audio clips and 999 illustrations — ships inside the app. Nothing is downloaded. The app is complete in aeroplane mode.
The following is stored locally on the device, in the browser's localStorage and — in the packaged app — mirrored into the operating system's own key-value store so that progress survives the system reclaiming space:
| What | Example |
|---|---|
| Nickname and animal symbol per child | "Alba", 🦅 |
| Progress | XP, streak, medals, mastery level per category, the repetition cards, which words the child has met |
| Optional four-digit PIN per profile | Locks one profile against a sibling in the same room |
| Settings | Language, sound on/off, "does not read yet", whether the sentence section is unlocked |
| Whether the first-run tour has been shown | One flag |
We are not the controller of this data, because we have neither access to it nor any say over it. It is yours, on your device, in the same way a photo you took is. Uninstall the app and it is gone.
The four-digit PIN never leaves the device, not even when you buy the full version. See section 5.
3. On purchase: one account, and it is yours
The account appears in one place, once: after an adult has solved the arithmetic problem in the parental gate and chosen to buy. There is no sign-in button on the start screen, no "register", and nothing about accounts or prices anywhere in the child's interface.
Sign-in is by magic link. You give your email address, receive a link, tap it. No passwords. No "Sign in with Google", "with Facebook" or "with Apple" — we have no third-party sign-in at all, and therefore share nothing with any identity provider.
3.1 What we process, why, and on what basis
| # | Data | Why | Legal basis |
|---|---|---|---|
| 1 | The parent's email address | Create and restore access to the account, send the sign-in link, answer enquiries | Art. 6(1)(b) — necessary to perform the contract |
| 2 | Account record: created, last seen, chosen language (nb/de/en/sq), when you accepted the terms and this policy, and if applicable when deletion was requested | Run the account, and be able to evidence what you accepted and when | Art. 6(1)(b), and Art. 6(1)(c) for the evidence |
| 3 | Child profile: nickname, animal symbol, whether the profile is hidden, "does not read yet", whether the sentence section is unlocked, whether a PIN exists (never the code), plus XP, streak, medal count, mastery level per category, days active and rounds played | Show the right profile on a new device and give the child their progress back there | Art. 6(1)(b) |
| 4 | Progress, stored in nine parts: core counters, quiz percentages for words and for sentences, the repetition cards for words and for sentences, which words and sentences the child has met, the seasonal campaign and the daily mission | The very thing you bought: progress that follows the child across iPad, phone and PC | Art. 6(1)(b) |
| 5 | Entitlement: which product, which state (trial, active, cancelled, grace, expired, refunded), expiry date, which store the purchase came from | Know whether you have paid, without asking the store every time | Art. 6(1)(b) |
| 6 | Receipt: store, the store's transaction id, product id, sandbox or production, status, expiry, and the store's raw response | Verify the purchase, handle renewal and refund, and stop one receipt being used on many accounts | Art. 6(1)(b), and Art. 6(1)(f) — our legitimate interest in preventing abuse |
| 7 | Store notifications from the App Store and Google Play: event id, type, time and payload | Keep the entitlement correct when a subscription renews, is cancelled or refunded | Art. 6(1)(b) and 6(1)(f) |
| 8 | Rate-limit counters: a key built from the operation and the account id, a time window, a count | Prevent one account hammering the service or extracting everyone's data | Art. 6(1)(f) — security |
| 9 | Deletion log: a SHA-256 hash of the account id, when deletion was requested, when it completed, and how many rows were removed. The account id itself is nulled out once deletion finishes. | Be able to prove a deletion actually happened, without keeping who it was | Art. 6(1)(c) — evidencing compliance with Art. 17 |
| 10 | Technical server logs at our providers: IP address, timestamp, which call | Operations and troubleshooting | Art. 6(1)(f) |
3.2 No automated decisions, no profiling in the legal sense
The app adapts to the child: words that stick come back less often, words that do not come back more often, and the daily goal moves a little up or down with how much the child manages. That entire calculation runs on the device, in engine/srs.js and engine/mastery.js, from numbers held in the profile. We use no central model, no comparison between children, and no data from any other source. It produces no decision with legal or similarly significant effect for the child under Article 22.
4. What we never collect
This is not a courtesy. Every line below is a field that does not exist in the database, and the app shows you the same list inside the parent area.
- The child's PIN. See section 5.
- Date of birth or age. Nowhere in the schema.
- The child's full name. We ask for a nickname and say so in plain words when the profile is created. The field is free text, at most 14 characters; we cannot stop someone typing something else, but we do not ask for it and do not need it.
- The child's email address. Children have no account here.
- Location. The app never asks for location services. The web version additionally blocks it with
Permissions-Policy: geolocation=(). - Microphone, camera, photos or contacts. The "Say it out loud" mode asks the child to speak — but the app does not listen. There is no recording and no speech recognition. The child says the word to the room; the app hears nothing.
- Advertising identifiers (IDFA/AAID) or cross-app tracking. We never request App Tracking Transparency permission, because we have nothing to request it for.
- Third-party analytics. No Firebase Analytics, Google Analytics, Mixpanel, Amplitude, PostHog, Segment or attribution SDK. No third-party crash reporting.
- Advertising. No ad SDK, no adverts, ever.
- Tracking cookies. The app sets none. The web version's
Content-Security-Policyusesconnect-src 'self', which makes it practically impossible for the app to call a third party even if someone tried.
5. The PIN is never stored on our servers — not even hashed
You can give a child's profile a four-digit PIN. It protects against one thing: an older sibling picking up the iPad and messing with the younger one's profile. The threat is in the room, and it is solved by the device knowing the code.
So we do not store it. Not in the clear, not as a hash. The server knows only that a PIN exists, so that the app can tell you on a new device that one should be set there too.
Why not simply hash it: the key space is 10,000. A hash buys delay against an attacker who already has the database, not security — and it has to run every time a child mistypes and tries again. Storing the code would add an attack surface on children's data without improving the thing it exists for. GDPR Article 5(1)(c) on data minimisation points the same way.
This is enforced in four layers, not one: the client omits the field when it splits the profile up, the server's save function strips it, a database trigger rejects any row containing pin, pinHash or pin_hash — including from our own administrative role — and the import from the old system does not carry it. Automated tests assert the word appears in no row in the database.
The honest cost: a new iPad shows the profile unlocked until an adult sets a PIN there. We think that is the right trade.
6. Where the data lives, and who processes it
All data is stored in the EU — Frankfurt, Germany (eu-central-1). The region is fixed when the project is created and cannot be changed without moving everything by hand. The app shows you the region in the parent area, read from the server, so no stale text can be left behind.
Processors — named
| Name | What they do for us | Where | Note |
|---|---|---|---|
| Supabase, Inc. (USA) | Database, sign-in, server functions | Data stored in AWS eu-central-1, Frankfurt | Data processing agreement in place. The company is US-based and its personnel may access data during support — see section 7 |
| Amazon Web Services (Amazon Web Services, Inc.) | Sub-processor to Supabase: the machines the database runs on | Frankfurt | |
| Resend | Sends the sign-in link to your email | EU-region | Processes your email address and the time the link was sent |
| Cloudflare, Inc. | Serves the web version of the app | globalt kantnett — forespørselen behandles på nærmeste kantnode, og tjenerloggene ligger i Cloudflares eget nett | Processes IP addresses in server logs |
| Apple Inc. / Apple Distribution International Ltd. | Sells the subscription in its own name and gives us the receipt and renewal notifications | Ireland/USA | See 6.1 |
| Google Ireland Ltd. / Google LLC | The same, for Google Play | Ireland/USA | See 6.1 |
Supabase's current list of its own sub-processors forms part of their data processing agreement. supabase.com/legal/customer-resources/subprocessor-list — sist oppdatert av Supabase 1. juni 2026, kontrollert av oss 11. august 2026 We check it every time this policy is republished.
6.1 Apple and Google are the seller, not us
If you buy through the App Store or Google Play, Apple or Google is the seller (merchant of record). They take the payment, collect and remit VAT, and own the billing relationship.
We never receive your card number, your bank details or your billing address. We receive a receipt with a transaction id, a product name and an expiry date.
How Apple and Google handle your data as the seller is their responsibility and governed by their own privacy policies.
6.2 Microsoft is not a processor for us
The audio in the app was produced in advance, using Microsoft Azure AI Speech, before the app was published. What was sent to Microsoft was the Albanian word list — no user data, because there were no users yet.
The app contains no speech service and makes no calls to Microsoft during use. The clips are files inside the app.
The narrating voice is synthetic speech, not a human. We say so because Microsoft's terms require the disclosure — and because they expressly ask that it be given to parents when the product is aimed at children, so that you can make an informed decision on your child's behalf. The voice is clear, friendly and machine-generated.
7. Transfers outside the EEA
The data is stored in the EU. But two of our providers are US companies, and their personnel may, in support situations, access data held in Frankfurt. That counts as a transfer.
The transfer relies on EUs standard personvernbestemmelser (SCC), modul to og tre, slik de er inntatt i Supabase sin databehandleravtale versjon 1 av 1. august 2026 We have also assessed the need for supplementary measures; those in place are described in docs/juridisk/07-informasjonssikkerhet.md.
You may ask us for a copy of the safeguards.
8. How long we keep things
GDPR Article 5(1)(e) and the US COPPA Rule as amended in 2025 both require specific periods. "As long as necessary" is not an answer. Here are the numbers.
| What | How long | What happens then |
|---|---|---|
| Your account, the child profiles and all progress | While the account is in use, and for up to 730 days (24 months) after the last sign-in or sync | Deleted automatically. We email you 30 days beforehand, i.e. at 23 months |
| All of it, if you ask | Immediately — app data is deleted in the same transaction as the request | Your sign-in (the email address) is removed from the authentication system within 30 days |
| Your email address | While the account exists | Deleted with the account |
| Receipts | While the account exists | Deleted with the account. The store's own settlement is not ours and is governed by Apple and Google |
| Store notifications (renewal, cancellation, refund) | 180 days | Deleted automatically by a scheduled maintenance call |
| Rate-limit counters | 1 hour | Deleted automatically |
| Deletion log (hash + two timestamps, no account id) | 5 years after the deletion was carried out | Deleted |
| Backups | Ingen. Supabase sin gratisplan har ikke automatisk sikkerhetskopi | A deletion propagates into backups once that window has passed |
| Server logs | 1 dag | Deleted |
| Local data on your device | Until you delete it or uninstall the app | We never had it |
9. What happens when a subscription lapses
Nothing the child achieved disappears.
There is no link in the database from the entitlement to the progress — a deliberate separation, not an accident. A subscription that expires closes a door; it does not steal.
- Medals, XP, streak, repetition and mastery levels stay exactly as they are.
- The free categories keep working, indefinitely.
- Categories outside the free tier become unavailable. They are not shown with a padlock in the child's interface — they are simply not there, because the Norwegian Marketing Control Act § 20 forbids purchase invitations directed at children.
- Your account remains, so a new purchase restores access immediately and so that syncing between devices keeps working.
- After 730 days without a sign-in the account is deleted automatically, as described in section 8. You can delete it yourself at any time before that.
The app also has a 14-day grace window for devices that cannot reach us — aeroplane mode, mountains, the road to Kosovo without coverage. In that case the app trusts the last answer it received. A no from the server, on the other hand, takes effect immediately.
10. Your rights, and how you actually use them
You have the right of access (Art. 15), rectification (16), erasure (17), restriction (18), data portability (20) and to object (21). Where we rely on legitimate interests — rows 6, 7, 8 and 10 in the table above — you may object, and we must then show that our grounds outweigh yours.
You exercise the rights on your child's behalf for anything concerning the child.
How to do it in the app
- Tap For foreldre (For parents) on the start screen.
- Solve the arithmetic problem. (The gate exists so a child cannot do this. It is regenerated every time, and the answer is never present in the screen.)
- Tap 🔐 Your data. The screen shows two things, and it keeps them apart:
- This is on this device — and it is, whether or not you have an account: each child's nickname and animal, how many words and sentences have been practised, XP and medals, whether the child has a four-digit code, the device's settings, and how many kilobytes that adds up to.
- Your account, if you have one: your email address, when the account was created, each child's nickname and animal, when the profile was last changed, how many bytes the progress occupies, which subscription you have, which region the data is in, and the server's own list of what it does not store.
The buttons, by the name they actually carry on screen:
- ⬇️ Download your data gives you one file with everything the app has stored on the device and — if you have an account — the server's copy beside it. The format is the same one the app itself uses, so the file doubles as a backup. The children's four-digit codes are not included.
- 🗑️ Delete everything on this device removes every single thing the app has stored here and restarts the app as a fresh installation. If you have no account — and on the free tier you do not — this is the deletion that applies to you, and it is complete: there is no copy anywhere else.
- 🗑️ Delete the account and everything in it appears only when you are signed in. It removes the account, all child profiles, all progress, entitlement and receipts in a single operation, on every device. The sign-in disappears within 30 days. It cannot be undone.
Both deletions require you to type the word DELETE into a field. A button can be pressed by accident, and "are you sure?" with two buttons is exactly the dialogue people click through without reading.
The same screen holds the privacy policy as text inside the app (📄 Privacy policy) and the child's own privacy notice (🧒 For the child: what the app knows about you). Both work offline.
⚠️ Note to the draft, remove before publication: the screen is built (
js/minedata.js), and both states are live. Without an account — which is what the free tier is — it shows what is stored on the device and offers export and local deletion, without a single network call. With an account it asks the server the same three questions throughjs/sky.js:konto_innsyn,konto_eksport,konto_slett. Account deletion has been proven against the real project — seebackend/README.md§ 13.
How to do it by email
Write to personvern@mesoshqip.eu from the address the account is registered to. We answer within 30 days. If the request is complex we may extend by two months and will tell you within the first month. If we cannot confirm it is you, we must ask for more — we never ask a child for identification.
If you are unhappy with how we handled it, you can complain:
Norway — Datatilsynet Postboks 458 Sentrum, 0105 Oslo postkasse@datatilsynet.no · +47 22 39 69 00 · datatilsynet.no
United Kingdom — Information Commissioner's Office (ICO) Wycliffe House, Water Lane, Wilmslow, Cheshire SK9 5AF +44 303 123 1113 · ico.org.uk
If you live in another EEA country you may complain to your local authority. For Germany that is your state data protection authority; for Austria, the Datenschutzbehörde.
11. Security
The short version. The full, written security programme is in docs/juridisk/07-informasjonssikkerhet.md.
- No application server between the app and the database. Access is governed by row-level security in the database: a signed-in parent sees their own account and nothing else. The rules are written once and tested by a test file written as an attacker — raw SQL, guessed ids, calls on other people's children, an entirely unauthenticated session. 43 assertions, and every one of them is an attempt that must fail.
- Nobody can write their own entitlement. Anything touching payment goes through the server.
- Rate limits per account, including on reads, so that one account cannot extract data indefinitely or lock another family out.
- Everything over HTTPS. The web version has a strict
Content-Security-Policythat blocks third-party calls entirely. - PINs do not exist on the server. See section 5.
- Backups ingen sikkerhetskopi på gjeldende plan.
If a breach nevertheless occurs that is likely to result in a risk to the child's rights, we report it to Datatilsynet within 72 hours, and to you directly if the risk is high.
12. Children and consent
The app is made for children from roughly three to twelve, and sold to parents.
The age at which a child can consent to a digital service is 13 in Norway, 16 in Germany, 14 in Austria. Every child using this app is below the threshold in their own country.
We therefore build so that consent from the child is never needed. The account is the parent's, the contract is with the parent, and the only thing the child contributes is a nickname the family chose and progress in a practice app. Our basis is the contract with the parent, not consent from the child, in line with GDPR Article 8.
We have written a separate privacy notice for the child, in short sentences with pictures, that can be read aloud. It is not a summary of this document — it is written for a different reader. The UK Age Appropriate Design Code (Children's Code) requires exactly that.
And: there is nothing about money anywhere in the child's interface. No prices, no padlocks with a price behind them, no "ask your mum". Content outside the free tier is not hidden — it is not there. This is stricter than Apple requires, and it is because the Norwegian Marketing Control Act § 20 forbids both purchase invitations directed at children and encouraging a child to pester an adult.
13. Printing, paper and the daily mission
The progress report, the word cards, the word list and the diploma are produced in the browser on your own device, from data already there. Nothing is sent to a server and we use no PDF service. If you print a diploma with your child's nickname on it, your printer gets it, not us.
The daily mission — "say a word to grandma" — is chosen by the device from the date and the words the child has met. Nobody checks the tick box, and it is not sent anywhere.
14. Changes to this policy
If we change something that matters we update the version number at the top and tell you in the app the next time you open the parent area. If a change requires your consent, we ask before it takes effect. Earlier versions are available on request.
Annex: the rights in the code, with technical names
For anyone who wants to verify this, or who is drafting a data processing agreement with us:
| Right | Function | File |
|---|---|---|
| Access, Art. 15 | konto_innsyn() | backend/migrations/0008_personvern.sql |
| Portability, Art. 20 | konto_eksport() | same |
| Erasure, Art. 17 | konto_slett('SLETT') | same |
| The PIN guard | msq.avvis_pin() + trigger fremgang_uten_pin | backend/migrations/0003_fremgang.sql |
| Row-level security | the policies | backend/migrations/0006_rls.sql |
| Rate limits | msq.krev_kvote() | backend/migrations/0005_hastighet.sql |
| Retention, what exists today | tjener_vedlikehold() | backend/migrations/0009_tjener_api.sql |
The Article 30 record of processing activities is in docs/juridisk/06-ropa.md. The Article 35 data protection impact assessment is in docs/juridisk/03-dpia.md. Both are provided to the supervisory authority on request.