Skip to content

Commit a1563e4

Browse files
Kikolatorclaude
andcommitted
docs: update README with admin, mobile, email, and access control details
Reflects current project state: three apps (web, admin, mobile), Resend email infrastructure, Nuki smart lock integration, 29 migrations, shared package, and per-app environment variable docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e533f42 commit a1563e4

File tree

1 file changed

+126
-45
lines changed

1 file changed

+126
-45
lines changed

README.md

Lines changed: 126 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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
```
2529
cowork-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
93131
cp 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/)
122169
supabase 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
125177
npm 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

Comments
 (0)