No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
Multi-tenant ticketing and check-in platform for party fishing boat operators. Each operator gets their own isolated deployment (Vercel + Neon Postgres) from this shared codebase.
The mate check-in app (QR scanner, offline manifest, PIN auth) is built from the same apps/mobile codebase using the mate EAS build profile (EXPO_PUBLIC_APP_VARIANT=mate).Read the full README ↗Multi-tenant ticketing and check-in platform for party fishing boat operators. Each operator gets their own isolated deployment (Vercel + Neon Postgres) from this shared codebase.
| App | Description |
|---|---|
apps/web | Next.js 14 — marketing site, booking calendar, checkout, boarding passes, admin dashboard, API routes |
apps/mobile | Expo SDK 53 — consumer booking app (trips calendar, Stripe Payment Sheet, offline tickets wallet, Account tab with OTP sign-in) + mate check-in app (same codebase, separate EAS profile) |
packages/db | Drizzle ORM schema + migrations (shared source of truth) |
The mate check-in app (QR scanner, offline manifest, PIN auth) is built from the same apps/mobile codebase using the mate EAS build profile (EXPO_PUBLIC_APP_VARIANT=mate).
npm install -g pnpm)npm install -g expo-cli)npm install -g eas-cli) — for mobile device buildsbrew install stripe/stripe-cli/stripe) — for local webhook forwardinggit clone <repo>
cd open-boat-fishing
pnpm install
Create a Neon project. Copy the connection string.
# In packages/db — run migrations against the new database
DATABASE_URL="postgres://..." pnpm db:migrate
Then seed development data (creates one operator row, 4 vessels, products, prices, and ~150 trips):
DATABASE_URL="postgres://..." pnpm --filter @openboat/db seed
For production, replace the seed script with real operator data or use the admin dashboard.
acct_...).Create apps/web/.env.local:
# Database
DATABASE_URL=postgres://...
# Stripe (platform account)
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_... # from `stripe listen` in dev; from Stripe dashboard in prod
STRIPE_CONNECTED_ACCOUNT_ID=acct_... # operator's connected account
# App
NEXT_PUBLIC_APP_URL=https://yourclient.com # used in boarding pass links in emails
# Email (Resend)
RESEND_API_KEY=re_...
# Auth (signs mate + customer tokens)
SESSION_SECRET=<32+ char random hex> # generate with: openssl rand -hex 32
# Vercel cron auth (required for push notification reminders)
CRON_SECRET=<32+ char random hex> # must also be set in Vercel dashboard
Create apps/mobile/.env.local for local dev:
EXPO_PUBLIC_API_URL=http://localhost:3000
EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Apple Pay / Google Pay
EXPO_PUBLIC_APPLE_MERCHANT_ID=merchant.com.yourclient.app
EXPO_PUBLIC_URL_SCHEME=yourclientapp
EXPO_PUBLIC_MERCHANT_NAME=Your Client Name
# Set to "mate" to run the mate check-in app instead of the consumer app
# EXPO_PUBLIC_APP_VARIANT=mate
For EAS builds, set these in apps/mobile/eas.json under the appropriate build profile (see Mobile builds below).
app.json — per-operator mobile identityEdit apps/mobile/app.json to match the operator:
{
"expo": {
"name": "Your Operator Name",
"slug": "your-operator-slug",
"scheme": "youroperatorapp",
"ios": {
"bundleIdentifier": "com.youroperator.fishing"
},
"android": {
"package": "com.youroperator.fishing"
}
}
}
Each operator needs a unique bundle ID and scheme. For a second operator, either fork the repo or use EAS build profiles to override these values.
# Start everything (Turborepo — web + mobile Metro in parallel)
pnpm dev
# Or individually:
pnpm --filter @openboat/web dev # Next.js on :3001 (or :3000)
pnpm --filter @openboat/mobile dev -- --clear # Expo Metro on :8081
# Forward Stripe webhooks to local server (required for booking confirmation + wallet sync)
stripe listen --forward-to localhost:3001/api/webhooks/stripe
Webhook note: booking status only transitions to
confirmed(and tickets appear in the mobile wallet) afterpayment_intent.succeededfires. In local dev this requiresstripe listenrunning.
pnpm --filter @openboat/mobile ios
The app opens automatically. Use test card 4242 4242 4242 4242 with any future expiry and any CVC.
Requires an EAS development build — see Mobile builds. The simulator build won't install on a device.
# Run migrations
DATABASE_URL="..." pnpm db:migrate
# Generate migration from schema changes
pnpm --filter @openboat/db generate
# Open Drizzle Studio (visual DB browser)
DATABASE_URL="..." pnpm db:studio
This is the beginning of the README. Read the rest at the original. Read the full README ↗