Storefront and platform


Case Study · Digital products · Wellness printables and planners · UK
A child-safe download platform with membership, gated libraries, and admin — not a simple shop, a full product surface for families and classrooms.


SoulCraves is a digital wellness platform selling printables, planners, and wellbeing resources for individuals, families, and classrooms. The products are intentionally gentle: mindful morning planners, self-growth journals, wellbeing trackers, and similar downloadable content designed for calm daily practice.
The brief was not to build a shop. It was to build a platform. SoulCraves needed a public storefront for browsing and purchasing, a membership layer for subscribers, a personal library where customers access their purchases, child-safe features for family and classroom use, a content management system for the team to update products and editorial content without developer involvement, and an admin layer for operations. All of this had to be built to a standard appropriate for a platform where children are users.
Selling digital downloads sounds simple until you consider everything that breaks when you do it at scale or with a membership model.
A customer buys a printable. They download it. So does their partner, using the same link. So do two of their friends they forwarded it to. The download link has no expiry, no usage limit, and no connection to the purchaser. The business has no visibility into how many times each file has been accessed or by whom. Revenue leaks through link sharing with no mechanism to prevent it.
Add a subscription tier and the problem compounds. A free user and a lifetime member need to see the same storefront but access entirely different libraries. The entitlement logic that sits between browsing and downloading has to be correct on every request. Getting it wrong in either direction loses money or alienates customers.
Add children to the equation and the stakes change again. A platform where children access content needs parental controls, PIN-protected profiles, and the kind of data handling that can withstand scrutiny under UK child privacy standards. None of this is available off the shelf. It has to be built.
The entitlement architecture was designed first and everything else was built around it. Four tiers with explicit priority: Lifetime access at the top, then Premium subscription, then individual item purchases, then the Free tier capped at three downloads per month. Every download request resolves the user's highest entitlement before issuing a token. A lifetime member never sees a paywall. A free user hitting their monthly limit sees a clear upgrade path.
Download tokens were built as single-use and time-limited from day one. When a customer requests a download, the system generates a token tied to that customer, that file, and that session. The token expires after use or after a set window. Sharing the link gives the recipient an expired token. This eliminates the most common form of revenue leakage in digital download businesses without creating friction for legitimate customers.
Child-safe features were treated as a design constraint rather than an add-on. Child profiles sit under a parent account with PIN protection. Classroom and family sharing flows use an explicit sharing model rather than open access. Age verification gates content categories where appropriate. The data model keeps child profile data explicitly separated from adult account data throughout.
The platform runs on Next.js with TypeScript and Tailwind CSS, hosted on Vercel. Clerk handles authentication and user management. Prisma connects to PostgreSQL across a schema covering users, purchases, subscriptions, entitlements, child profiles, download tokens, audit events, and admin operations. Stripe handles three distinct payment flows: one-time item purchases, monthly and annual Premium subscriptions, and Lifetime access. Stripe webhooks drive entitlement updates so access is granted immediately on payment confirmation without manual intervention.
Files are stored on Vercel Blob with signed download URLs. Resend handles transactional email for purchase confirmations, subscription updates, and account notifications. Upstash Redis enforces rate limiting on download and API endpoints. Sanity Studio gives the team full control over product listings, editorial content, homepage sections, and site settings without touching the codebase.
The admin layer covers the full operational picture: product management, customer records, purchase history, subscription status, download audit logs, DSAR handling for data subject access requests, and content scheduling. Role-based access gives different team members appropriate visibility without exposing the full admin surface to everyone.
134 commits. 41 pages. 37 API routes. The test suite and pre-launch checklist cover Stripe webhook handling, Clerk integration, Resend delivery, Vercel Blob access, Redis availability, and analytics configuration in sequence.
SoulCraves launched with the full platform in place: a branded storefront, a working membership system, a protected personal library, child-safe family features, and an operational back-end the team can run without developer support for day-to-day tasks.
Imogen's summary: "In love with my new website looks Amazing."
What the platform represents beyond the immediate build is an architecture that scales with the product. Adding new printable categories, launching new subscription tiers, introducing classroom licensing, or expanding into new content types are all configuration and content changes rather than engineering projects. The infrastructure exists. The business can grow inside it.
Next.js, TypeScript, Tailwind CSS, Clerk, Prisma, PostgreSQL, Stripe, Vercel Blob, Upstash Redis, Resend, Sanity CMS, Vercel — four entitlement tiers, one-time expiring download tokens, child profiles, 37 API routes, 134 commits
“In love with my new website looks Amazing.”
The Sanity schema and the Prisma schema evolved in parallel rather than being designed together upfront. In a platform where CMS content and database records need to align — a product in Sanity needs a corresponding purchasable item in Prisma — that parallel evolution created several moments of friction where the two models did not quite match. Designing both schemas together before writing any application code would have produced cleaner alignment and fewer adjustments mid-build.
If you are selling digital products and relying on basic file links, a simple Gumroad setup, or a Shopify store that was not built for memberships, book a conversation. We can assess what your current setup cannot do and what a proper platform would change.