Dawnlet · under the hood

Purchases & gating

Dawnlet Plus is one product bought once. The interesting part isn't the transaction — it's where the gate is enforced, and why it's enforced twice.

One non-consumable $6.99 once No server-side tier Gate enforced twice

§One product

A single non-consumable in-app purchase, handled entirely by StoreKit. Buy it once and it's yours; there's nothing to renew and nothing to cancel.

There is no server-side record of your purchase — no tier column on your account, nothing in the database that knows you paid. The entitlement lives with Apple, tied to your Apple ID, and the app asks StoreKit. Restoring on a new device re-checks with Apple.

What that buys

Dawnlet's database has no idea whether you're a paying customer, so a bug in it can't revoke access, and the purchase record isn't another piece of personal data to hold. It also means subscriptions would be a real architectural change rather than a pricing decision — which is a feature, not an oversight.

A single purchase service instance is created once and made available to the whole app, so any screen can check the entitlement without it being threaded through every initialiser.

1Three shapes of gate

ShapeUsed byBehaviour
Whole featureThe money tab; Apple Calendar, Reminders and Contacts sync A lock screen with the live price replaces the content entirely.
Free-tier capHabits, todos, movies, books, places (10 each); activities (5) Everything works until the cap; the add button then routes to the paywall instead.
Per itemNotification kinds A locked kind is a dimmed row with a lock glyph, in a list of ones you can use.

The money module is the only whole-feature gate among the modules, for a reason spelled out in its own page: there's no unit to cap that's both meaningful and not hostile.

Notifications were originally gated as a whole feature, and that was wrong. The settings screen wrapped everything in a lock, which meant a free user couldn't turn on a habit reminder — making the free tier feel broken rather than limited. It's now per kind.

2Enforced twice

The Plus gate is checked in two independent places, and this is deliberate duplication.

  1. In the interface, so locked things render as locked.
  2. In the notification planner, which filters Plus-only kinds itself rather than trusting that the settings screen prevented them from being enabled.
The case that makes it necessary

Someone buys Plus, turns on quiet hours and the finance alerts, and later the entitlement stops resolving — a refund, a family-sharing change, a restore that fails on a new device. Their stored preferences still say those kinds are on. If only the settings screen enforced the gate, the planner would happily keep scheduling paid notifications indefinitely.

Checking at the point of use means the app degrades to the free tier on its own, without needing a migration to go and turn settings off — and without ever destroying the preferences, so restoring Plus brings the setup back exactly as it was.

3Where the line sits

Free
  • Events, agenda and guided planning in full
  • 10 habits, todos, movies, books, places each
  • 5 tracked activities
  • Meals, gratitudes, people, categories, tags
  • Core reminders and digests, birthdays, and the entire notification feed

Two principles decided the split. Reminders are table stakes — an organizer that won't remind you of anything unless you pay isn't a limited version, it's a broken one. And the notification feed is never paywalled: charging someone to see a record of things the app already did to them is actively hostile.

What Plus covers is the heavier module and the fine-grained control on top — the things that make the app better for someone already using it daily, rather than the things that make it work at all.

4Not hardcoding the name

Every "Plus"-branded string in the app reads from a single constant rather than being typed inline. The tier's name isn't final, and a rename shouldn't be a search-and-replace across dozens of files where the ones inside sentences get missed.

The same applies to the settings tab's own label, which may end up being called something else — it's one constant, read by the tab bar and every reference to it.

One piece of paywall copy is currently aspirational: "unlimited categories" is advertised, and there's no cap on categories to lift. That's a copy bug rather than a missing feature, and worth naming here rather than quietly matching the code to the marketing.