@@ -9,63 +9,101 @@ Each coworking business (tenant) gets its own branded subdomain, Stripe Connect
99| Layer | Technology |
1010| -------| -----------|
1111| Framework | Next.js 16.1, App Router, React 19 |
12+ | Mobile | Expo 55, React Native 0.83, Expo Router |
1213| Language | TypeScript 5.9 (strict, no ` any ` ) |
13- | Styling | Tailwind CSS v4, shadcn/ui |
14+ | Styling | Tailwind CSS v4, shadcn/ui (web), NativeWind (mobile) |
1415| Backend | Supabase (Postgres 15, Auth, Edge Functions, RLS) |
1516| Payments | Stripe Connect (Standard accounts) |
17+ | Email | Resend + React Email |
18+ | Access Control | Nuki smart lock integration |
1619| Validation | Zod at all API boundaries |
1720| Forms | React Hook Form + Zod resolvers |
21+ | Data Fetching | Supabase JS + ` @supabase/ssr ` (web), TanStack Query v5 (mobile) |
1822| Testing | Vitest (unit), Playwright (E2E) |
1923| Monorepo | Turborepo with npm workspaces |
20- | Deployment | Vercel (app ), Supabase (database) |
24+ | Deployment | Vercel (apps ), Supabase (database), EAS (mobile ) |
2125
2226## Project Structure
2327
2428```
2529cowork-platform/
2630├── apps/
27- │ └── web/ # Next.js application
28- │ ├── app/
29- │ │ ├── (app)/ # Authenticated space routes (dashboard, bookings, admin)
30- │ │ ├── (auth)/ # Login, auth callback, space claim routes
31- │ │ ├── (platform)/ # Platform-level routes (onboarding, space selection)
32- │ │ └── api/
33- │ │ ├── health/ # Health check endpoint
34- │ │ └── webhooks/
35- │ │ └── stripe/ # Stripe Connect webhook handler
36- │ ├── components/
37- │ │ ├── layout/ # Sidebar, header, navigation
38- │ │ └── ui/ # shadcn/ui primitives
39- │ ├── lib/
40- │ │ ├── booking/ # Availability, rules, formatting
41- │ │ ├── credits/ # Credit granting and expiry
42- │ │ ├── products/ # Product visibility rules
43- │ │ ├── space/ # Space resolution from hostname
44- │ │ ├── stripe/ # Stripe client, Connect, checkout, subscriptions, webhooks
45- │ │ └── supabase/ # Server, client, admin, middleware helpers
46- │ └── middleware.ts # Space resolution + auth gate
31+ │ ├── web/ # Next.js tenant-facing app (:3000)
32+ │ │ ├── app/
33+ │ │ │ ├── (app)/ # Authenticated space routes
34+ │ │ │ │ ├── dashboard/ # Member overview
35+ │ │ │ │ ├── book/ # Desk & room booking
36+ │ │ │ │ ├── bookings/ # Booking history
37+ │ │ │ │ ├── profile/ # Member profile + avatar
38+ │ │ │ │ ├── plan/ # Membership plans
39+ │ │ │ │ ├── invoices/ # Member invoices
40+ │ │ │ │ ├── access/ # Door access codes (Nuki)
41+ │ │ │ │ └── admin/ # Role-gated admin section
42+ │ │ │ │ ├── bookings/ # Daily view, walk-ins
43+ │ │ │ │ ├── members/ # Directory, import, bulk actions
44+ │ │ │ │ ├── leads/ # Sales pipeline
45+ │ │ │ │ ├── passes/ # Day/week passes
46+ │ │ │ │ ├── plans/ # Tier configuration
47+ │ │ │ │ ├── products/ # Store catalogue
48+ │ │ │ │ ├── resources/ # Desks, rooms, pricing
49+ │ │ │ │ ├── invoices/ # Admin billing view
50+ │ │ │ │ ├── import/ # Bulk imports
51+ │ │ │ │ └── settings/ # Branding, hours, Stripe Connect
52+ │ │ │ ├── (auth)/ # Login, auth callback, space claim
53+ │ │ │ ├── (platform)/ # Onboarding, space selection
54+ │ │ │ └── api/
55+ │ │ │ ├── health/ # Health check endpoint
56+ │ │ │ └── webhooks/
57+ │ │ │ └── stripe/ # Stripe Connect webhook handler
58+ │ │ ├── components/
59+ │ │ │ ├── layout/ # Sidebar, header, navigation
60+ │ │ │ └── ui/ # shadcn/ui primitives
61+ │ │ ├── emails/ # React Email templates
62+ │ │ │ ├── tenant/ # Space-branded transactional emails
63+ │ │ │ └── platform/ # Platform-level notifications
64+ │ │ ├── lib/
65+ │ │ │ ├── booking/ # Availability, rules, formatting
66+ │ │ │ ├── credits/ # Credit granting and expiry
67+ │ │ │ ├── nuki/ # Smart lock API integration
68+ │ │ │ ├── products/ # Product visibility rules
69+ │ │ │ ├── space/ # Space resolution from hostname
70+ │ │ │ ├── stripe/ # Stripe client, Connect, checkout, webhooks
71+ │ │ │ └── supabase/ # Server, client, admin, middleware helpers
72+ │ │ └── middleware.ts # Space resolution + auth gate
73+ │ ├── admin/ # Platform admin dashboard (:3001)
74+ │ │ └── app/
75+ │ │ ├── (dashboard)/ # Tenant & space management
76+ │ │ ├── auth/ # Platform admin auth
77+ │ │ └── denied/ # Access denied page
78+ │ └── mobile/ # Expo mobile app
79+ │ └── app/
80+ │ ├── (app)/ # Authenticated routes
81+ │ ├── (auth)/ # Login flows
82+ │ └── index.tsx # Entry point
4783├── packages/
48- │ └── db/ # Database package
49- │ ├── docs/
50- │ │ └── MT-SCHEMA-SPEC.md # Full schema specification
51- │ ├── supabase/
52- │ │ ├── config.toml # Local Supabase configuration
53- │ │ ├── migrations/ # 15 sequential migrations (00001--00015)
54- │ │ └── seed.sql # Seed data for local development
55- │ └── types/
56- │ └── database.ts # Auto-generated TypeScript types
84+ │ ├── db/ # Database package
85+ │ │ ├── docs/
86+ │ │ │ └── MT-SCHEMA-SPEC.md # Full schema specification
87+ │ │ ├── supabase/
88+ │ │ │ ├── config.toml # Local Supabase configuration
89+ │ │ │ ├── migrations/ # 29 migrations
90+ │ │ │ ├── functions/ # Edge functions (cron jobs)
91+ │ │ │ └── seed.sql # Seed data for local development
92+ │ │ └── types/
93+ │ │ └── database.ts # Auto-generated TypeScript types
94+ │ └── shared/ # Shared logic (Zod schemas, constants, types)
5795├── .github/
5896│ ├── workflows/
59- │ │ ├── ci.yml # PR validation pipeline
60- │ │ ├── deploy-dev.yml # Dev migration + type generation
61- │ │ └── deploy-prod.yml # Prod migration with approval gate
62- │ └── CICD_SETUP.md # CI/CD setup instructions
97+ │ │ ├── ci.yml # PR validation pipeline
98+ │ │ ├── deploy-dev.yml # Dev migration + type generation
99+ │ │ └── deploy-prod.yml # Prod migration with approval gate
100+ │ └── CICD_SETUP.md # CI/CD setup instructions
63101├── docs/
64- │ ├── architecture.md # System architecture documentation
65- │ └── development.md # Local development guide
66- ├── CLAUDE.md # AI assistant project context
67- ├── turbo.json # Turborepo task configuration
68- └── package.json # Root workspace configuration
102+ │ ├── architecture.md # System architecture documentation
103+ │ └── development.md # Local development guide
104+ ├── CLAUDE.md # AI assistant project context
105+ ├── turbo.json # Turborepo task configuration
106+ └── package.json # Root workspace configuration
69107```
70108
71109## Quick Start
@@ -91,10 +129,19 @@ cd ../..
91129
92130# Configure environment
93131cp apps/web/.env.example apps/web/.env.local
132+ cp apps/admin/.env.example apps/admin/.env.local
94133# Fill in the values (see Environment Variables below)
95134
96135# Start the dev server
97- turbo dev # Next.js on http://localhost:3000
136+ turbo dev # web on :3000, admin on :3001
137+ ```
138+
139+ ### Mobile Setup
140+
141+ ``` bash
142+ cd apps/mobile
143+ cp .env.example .env
144+ npx expo start # Scan QR with Expo Go, or press i/a for simulators
98145```
99146
100147## Commands
@@ -121,25 +168,49 @@ supabase db push # Push migrations to remote project
121168# Type generation (run from packages/db/)
122169supabase gen types typescript --local > types/database.ts
123170
171+ # Mobile (run from apps/mobile/)
172+ npx expo start # Dev server (QR code for Expo Go)
173+ eas build --platform ios # Cloud build for iOS
174+ eas build --platform android # Cloud build for Android
175+
124176# Formatting
125177npm run format # Prettier across the repo
126178```
127179
128180## Environment Variables
129181
130- The web app requires the following environment variables in ` apps/web/.env.local ` :
182+ ### Web App ( ` apps/web/.env.local ` )
131183
132184| Variable | Description |
133185| ----------| -------------|
134186| ` NEXT_PUBLIC_SUPABASE_URL ` | Supabase project URL |
135187| ` NEXT_PUBLIC_SUPABASE_PUB_KEY ` | Supabase publishable (anon) key |
136188| ` SUPABASE_SECRET_KEY ` | Supabase service role key (server-only) |
137- | ` NEXT_PUBLIC_PLATFORM_DOMAIN ` | Platform domain (e.g., ` localhost:3000 ` or ` app.cowork.com ` ) |
189+ | ` NEXT_PUBLIC_PLATFORM_DOMAIN ` | Platform domain (e.g., ` localhost:3000 ` ) |
190+ | ` NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ` | Stripe publishable key |
138191| ` STRIPE_SECRET_KEY ` | Stripe platform secret key |
139192| ` STRIPE_WEBHOOK_SECRET ` | Stripe platform webhook signing secret |
140193| ` STRIPE_CONNECT_WEBHOOK_SECRET ` | Stripe Connect webhook signing secret |
194+ | ` RESEND_API_KEY ` | Resend email API key |
141195
142- For local development with Supabase, the URL and keys are printed by ` supabase start ` .
196+ ### Admin App (` apps/admin/.env.local ` )
197+
198+ | Variable | Description |
199+ | ----------| -------------|
200+ | ` NEXT_PUBLIC_SUPABASE_URL ` | Supabase project URL |
201+ | ` NEXT_PUBLIC_SUPABASE_PUB_KEY ` | Supabase publishable (anon) key |
202+ | ` SUPABASE_SECRET_KEY ` | Supabase service role key (server-only) |
203+ | ` NEXT_PUBLIC_PLATFORM_DOMAIN ` | Platform domain |
204+ | ` STRIPE_SECRET_KEY ` | Stripe platform secret key |
205+
206+ ### Mobile App (` apps/mobile/.env ` )
207+
208+ | Variable | Description |
209+ | ----------| -------------|
210+ | ` EXPO_PUBLIC_SUPABASE_URL ` | Supabase project URL |
211+ | ` EXPO_PUBLIC_SUPABASE_PUB_KEY ` | Supabase publishable (anon) key |
212+
213+ For local development, Supabase URL and keys are printed by ` supabase start ` .
143214
144215## Key Concepts
145216
@@ -150,12 +221,22 @@ For local development with Supabase, the URL and keys are printed by `supabase s
150221- ** Credit** -- Time-based currency (in minutes) for booking resources. Granted monthly by subscription or purchased as hour bundles.
151222- ** Pass** -- Day or week pass for non-members. Includes auto-assigned desk.
152223
224+ ## Architecture Highlights
225+
226+ - ** Multi-tenancy** : Single database, shared schema. RLS policies enforce full data isolation per space via JWT claims.
227+ - ** Auth** : Magic link only (Supabase Auth). Tenant resolved from subdomain or custom domain in middleware.
228+ - ** Payments** : Stripe Connect Standard accounts per tenant. Platform collects configurable app fees (5/3/1% based on plan tier).
229+ - ** Booking** : Multi-slot desk selection with hourly time ranges. Overlap prevention via Postgres ` EXCLUDE ` constraints. Credits deducted FIFO by expiry date.
230+ - ** Access** : Nuki smart lock integration for door access codes per member.
231+ - ** Email** : Branded transactional emails via Resend + React Email (welcome, booking confirmations, invoices).
232+ - ** Mobile** : Expo with Expo Router. All data fetched client-side via Supabase SDK + TanStack Query. RLS is the security boundary.
233+
153234## Documentation
154235
155236- [ Architecture] ( docs/architecture.md ) -- System design, multi-tenancy model, auth flow, data flow
156237- [ Development Guide] ( docs/development.md ) -- Local setup, database workflow, testing, CI/CD
157238- [ Schema Specification] ( packages/db/docs/MT-SCHEMA-SPEC.md ) -- Complete database schema reference
158- - [ CI/CD Setup] ( / .github/CICD_SETUP.md) -- GitHub Actions configuration and secrets
239+ - [ CI/CD Setup] ( .github/CICD_SETUP.md ) -- GitHub Actions configuration and secrets
159240
160241## License
161242
0 commit comments