Cross-app planning · 5 App Store products

Shared Infrastructure for the App Store Launch

All five products (fish-finder, meal-finder, movie-recommender, tax-strategy-app, trip-planner-app) already grow the same set of account / billing / support features — but each one re-invents them in its own way. This is what can be unified, why it's worth doing, what it changes in each repo, and how to capture it as a reusable skill.

To be precise about what "shared" means here: there are no shared components between the apps today, and this plan does not create a shared runtime library either. Each app keeps its own independent codebase. What gets unified is the standard — the data model, routes, flows, and UX contract — which every app implements on a per-app basis. "Shared" = one agreed specification, five separate implementations. Never one package imported five times.

The short version

Every app independently re-built the same five things: authentication, an admin/role gate, an account page, Stripe billing, and a feedback/bug board. They share the concept but not a line of code — four different auth systems, billing that ranges from fully wired to a bare schema, and a feedback board that exists in four apps and is missing in one.

The honest constraint: these repos are not one stack. They fall into two families, so "shared" means a shared specification + reference implementation + a code-generating skill — not a single npm package dropped into all five.

  • Family A — Cloudflare + D1 (4 of 5): fish-finder, meal-finder, movie-recommender, trip-planner-app. SQLite/D1, deployed on Workers/Pages.
  • Family B — Vercel + Postgres (1 of 5): tax-strategy-app. This one is also the most complete reference: real Stripe tiers, account page, voting feedback board, Sentry, hardened security headers.

The App Store gap that matters most: selling through the iOS App Store means Apple requires In-App Purchase for digital subscriptions. None of the apps have live IAP — only movie-recommender even stubs it. Stripe-on-web alone will get the apps rejected.

Where each app stands today

Read this as "how much is already there to harvest into the shared layer."

Capabilityfish-findermeal-findermovie-rec tax-strategytrip-planner
StackVite+React / HonoNext / CFVanilla JS / CF PagesNext / VercelNext / CF
DatabaseD1D1+DrizzleD1PostgresD1+Drizzle
Authemail/pwBetter Authpbkdf2HMAC cookiemagic-link
Admin / rolesenv listadmin pageis_adminenv listisAdmin flag
Account pagefullminimalAPI onlyfullprefs only
Stripe (web)wiredschema onlystubs3 tierswired
Apple IAPnonenonestub 501nonenone
Feedback boardyes+triage+comments+votingnone
Transactional emailResendpartialResendpartialmagic-link
Legal pages4 pages2 pagespartial
Error monitoringSentry
Rate-limit / auditpartialbothrate-limitaudit log
● done / solid ● partial ● missing

What to unify — pick what's in scope

Tick the items you want in the shared layer and add notes (priority, tier choices, app-specific quirks). Tier 1 = App Store blockers, Tier 2 = core shared product surface, Tier 3 = hardening. Use the Copy my selections bar at the bottom to send a single block back.

Tier 1 — App Store launch blockers

Tier 1

What: a shared subscription/entitlement model that both Stripe (web) and Apple StoreKit (iOS) write into, plus a StoreKit purchase + restore + server-side receipt validation flow and an App Store Server Notifications webhook. App code asks one question — "is this user entitled?" — and never cares which channel paid.

Why: Apple requires IAP for digital subscriptions sold in an iOS app and takes 15–30%. Shipping Stripe-only is the single most likely rejection reason. movie-recommender already modelled the dual-channel shape (source: stripe|apple) — that becomes the template for all five.

Downstream: new entitlements table + Apple webhook in every repo; feature gates must read the shared entitlement, not a Stripe-specific field. tax-strategy's tier mapping is the closest existing logic to generalise.
Tier 1

What: a uniform "delete my account" (cascade) and "export my data" (JSON) flow reachable from the account page in-app.

Why: Apple has required in-app account deletion since 2022; GDPR/CCPA require export + delete. movie-recommender and tax-strategy already do cascade delete + export; the others are partial.

Downstream: each repo needs a documented cascade map of its own tables; trivial where delete exists, real work where it doesn't (meal, trip).
Tier 1

What: a shared, templated set — Privacy Policy, Terms, Cookies, Refunds, Support/Contact — branded per app, plus the data-collection facts each app needs for Apple's privacy "nutrition labels."

Why: App Store review requires a working privacy-policy URL and accurate privacy labels; refunds/terms reduce disputes. fish-finder already has all four pages — that becomes the boilerplate.

Downstream: meal-finder and trip-planner have none today; mostly content/templating work, low engineering risk.

Tier 2 — core shared product surface

Tier 2

What: one agreed auth contract — session shape, cookie name convention, getCurrentUser() helper, email-verification + password-reset flows — and Sign in with Apple, which Apple mandates if you offer any other social login.

Why: there are four different auth systems today. You don't need to rip them all out, but a common interface lets every other shared module (billing, account, feedback, admin) assume the same user object.

Downstream: highest-touch item. Recommendation: standardise the interface and new flows, keep each app's existing auth engine. meal-finder (Better Auth) and trip-planner (magic-link) are the outliers to wrap.
Tier 2

What: a consistent account screen — change email, change password, manage subscription, export, delete — wired to the shared auth + entitlement modules.

Why: users expect one place to manage their account; it's also where the Tier-1 deletion/export/billing controls live. tax-strategy and fish-finder have full versions to copy.

Downstream: meal, movie (UI), trip get a real account page; mostly assembly once auth + entitlement land.
Tier 2

What: the web-side billing trio — Checkout, Billing Portal, signature-verified webhook with idempotency — writing into the same shared entitlement as Apple IAP.

Why: web purchase avoids Apple's cut and serves non-iOS users. Three apps already do this well (tax, trip, fish); meal has only a schema; movie has stubs. Consolidate to one implementation.

Downstream: meal-finder and movie-recommender get real billing routes; others refactor to the shared entitlement write-path.
Tier 2

What: the shared board — submit (feature/bug/question), status workflow (open → planned → in progress → shipped/declined), comment threads, optional voting, and an admin triage view.

Why: four apps already built near-identical versions; tax-strategy's (voting + comments + admin transitions) is the richest. trip-planner has none. One schema + one UI saves the most duplicated effort of any item here.

Downstream: trip-planner gains it from scratch; the other four converge their slightly-different tables onto the shared schema (a light migration).
Tier 2

What: one admin model (recommend an is_admin flag seeded from an ADMIN_EMAILS env list) and a small console: user list, comp/grant entitlement, feedback triage, force password reset.

Why: all five gate admin differently (env list vs DB flag). Unifying lets the feedback board, billing comps, and support actions share one permission check.

Downstream: low risk — all apps already have a gate; this standardises it and adds the missing console actions.
Tier 2

What: a shared mail helper (Resend) with templates for verification, password reset, magic-link, billing receipts, and account-deletion notices, with a safe no-op fallback when keys are unset.

Why: fish and movie already use Resend; the others are partial. Auth, billing, and account flows all depend on reliable email, so it underpins several Tier-1/2 items.

Downstream: standard EMAIL_FROM / SUPPORT_EMAIL / RESEND_API_KEY env contract across repos.

Tier 3 — hardening & operations

Tier 3

What: shared Sentry setup with a scrub hook and a tunnel route to keep CSP tight. Why: only tax-strategy has it; you'll want crash visibility the moment real users arrive. Downstream: add config + DSN env per repo; near-zero product risk.

Tier 3

What: per-IP/per-user throttle buckets on auth + write endpoints and an audit trail of sensitive actions. Why: protects auth/billing from abuse; movie-recommender already has both as a template. Downstream: two small shared tables + middleware per repo.

Tier 3

What: a shared CSP + security-header set (frame-ancestors none, HSTS, nosniff, referrer policy, locked permissions). Why: tax-strategy has a strong set; the rest vary. Downstream: per-stack config (Next headers vs Worker responses); test for broken third-party embeds.

Tier 3

What: agreed table shapes + naming for the cross-cutting tables (users, sessions, entitlements, feedback, webhook_events, audit_log) and a documented migration approach per family (Drizzle for D1, SQL migrate script for Postgres). Why: keeps the shared modules portable and the skill's generated code predictable. Downstream: the connective tissue that makes everything above reusable.

Can this become a skill in global-agents? Yes.

This is in fact the ideal use of a skill. A skill is a folder with a SKILL.md (name + description + instructions) plus supporting files; you already have the precedent in tax-strategy-app's claude-agents/ directory, which distributes reusable review personas the same way.

Because the five repos are two different stacks — and because you explicitly want no shared components — the skill is the perfect fit: it distributes a standard, not code that runs across apps. It carries a stack-agnostic specification + reference snippets and generates fresh per-repo code that lives entirely inside that repo. Nothing is imported at runtime; each app stays fully independent. Proposed shape:

global-agents/
  skills/
    app-store-infra/
      SKILL.md                  # when-to-use + step-by-step playbook
      spec/
        entitlements.md         # dual-channel Stripe+Apple model + table shape
        auth-contract.md        # session/user interface every module assumes
        feedback-board.md       # schema + statuses + UI contract
        account-page.md         # required controls (delete/export/billing)
        legal-pages.md          # page set + privacy-label data points
        admin.md                # gate + console actions
      reference/
        cloudflare-d1/          # snippets for Family A (fish/meal/movie/trip)
        next-vercel-postgres/   # snippets for Family B (tax)
      checklists/
        app-store-submission.md # IAP, deletion, privacy URL, Sign in w/ Apple

How you'd use it later: from any repo you say "apply the app-store-infra skill — add the feedback board and entitlement model." The skill detects the stack family, pulls the matching reference snippets, generates the migration + routes + UI to that repo's conventions, and runs its submission checklist. One source of truth, five consistent implementations, and new apps inherit it on day one.

Recommended sequence: (1) confirm scope on this page → (2) build the full implementation once in the strongest reference (tax-strategy for product depth; a D1 app for Family A) → (3) distil the proven patterns into the skill above → (4) roll out to the remaining repos via the skill. Writing the skill before building it once tends to encode guesses; build, then harvest.

0 selected
Your selections

Copied to clipboard. Paste this single block back to me.