← Projects

Petteach

Video course platform where verified pet trainers publish and sell courses to pet owners.

Petteach is a platform for pet training courses. Verified trainers and pet professionals publish structured video courses on training, care, behaviour and nutrition. Pet owners subscribe, watch chapter by chapter and track their progress, with free preview chapters before the paywall.

One monorepo

A Turborepo monorepo holds the Expo app for pet owners, Next.js dashboards for educators and admins, and a Hono and tRPC API on Cloudflare Workers with Better Auth and Drizzle on Postgres. Slow work goes through Cloudflare Queues to separate workers: push and email notifications, translations and payment webhooks. Educators apply, get reviewed, and manage courses and chapters with drag-and-drop ordering. Owners can browse as guests before they sign up.

How Petteach is put together Three front ends talk to one Hono and tRPC API on Workers. Slow work, like push, email, translations and payment webhooks, goes through Cloudflare Queues to separate workers.

Parts: Mobile app (Expo · pet owners), Educators (Next.js dashboard), Admins (Next.js · reviews), API Worker (Hono · tRPC), Queues (jobs · webhooks), Postgres (Neon · Drizzle), Polar (web subscriptions), Queue workers (notify · translate).

  • Mobile app to API Worker
  • Educators to API Worker
  • Admins to API Worker
  • API Worker to Queues (jobs)
  • API Worker to Postgres
  • API Worker to Polar (checkout)
  • Queues to Queue workers

Subscriptions

Web subscriptions run on Polar and mobile purchases go through RevenueCat. Owners subscribe to tiers, and each tier bundles a set of courses. Polar’s webhooks are verified, queued, and recorded by event ID before they touch a subscription, so a redelivered event changes nothing.

Access to a chapter is checked on the server, not in the app: a free preview chapter plays for anyone, an educator always sees their own course, and everyone else needs a subscription that isn’t cancelled, whose paid period hasn’t ended, and whose tier includes that course.

From payment to a playing chapter The webhook is verified and queued, then applied once per event ID. Whether a chapter plays is decided on the server, at the moment it's requested, against the subscription's paid period.
  1. Pet owner to API Worker: subscribe to a tier
  2. API Worker to Polar: create a checkout
  3. Polar to API Worker: subscription webhook
  4. API Worker to Webhook worker: verify, then queue
  5. Webhook worker to Postgres: insert event ID (once)
  6. Webhook worker to Postgres: upsert tier + period end
  7. Pet owner to API Worker: open a chapter
  8. API Worker to Postgres: free? own course? tier covers it?
  9. Postgres to API Worker: period not yet over
  10. API Worker to Pet owner: chapter video