The_Vibe/README.md
metatroncubeswdev 89cf37f5b5 Initial commit — The Vibe fair-trade delivery platform
- NestJS backend: auth, restaurants, orders, drivers, payments, tracking, reviews, zones, admin, email
- Next.js 14 frontend: landing, restaurants, checkout, tracking, dashboards, onboarding
- Expo mobile app: driver orders and earnings screens
- PostgreSQL + PostGIS schema with seed data
- Docker Compose for local dev (Postgres, Redis, OSRM)
- MapLibre GL + OpenStreetMap integration
- Stripe subscription and payment processing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 13:26:55 -05:00

6.6 KiB
Raw Permalink Blame History

The Vibe — Fair-Trade Delivery Platform

Flat-fee food delivery for the Greater Toronto Area. No commissions. No exploitation. Restaurants keep 100% of profits.


Quick Start

# 1. Copy env and fill in your keys
cp .env.example .env

# 2. Start PostgreSQL/PostGIS + Redis
npm run docker:up

# 3. Install all dependencies
npm install

# 4. Start backend + frontend
npm run dev

Backend: http://localhost:3001 Frontend: http://localhost:3000 PgAdmin: http://localhost:5050 (after docker-compose --profile dev up)


Project Structure

The_Vibe/
├── packages/
│   ├── database/
│   │   ├── schema.sql         # Full PostgreSQL + PostGIS schema
│   │   └── seed.sql           # GTA zones + dev data
│   ├── backend/               # NestJS API (port 3001)
│   │   └── src/
│   │       ├── modules/
│   │       │   ├── auth/      # JWT auth, roles guard
│   │       │   ├── drivers/   # Sessions, break-even algorithm
│   │       │   ├── restaurants/ # Menu, savings dashboard
│   │       │   ├── orders/    # Full order lifecycle
│   │       │   ├── payments/  # Stripe subscriptions + daily fee
│   │       │   ├── tracking/  # Socket.IO real-time gateway
│   │       │   ├── zones/     # GTA PostGIS geofencing
│   │       │   ├── menu/      # Menu CRUD
│   │       │   └── admin/     # Platform analytics
│   │       └── database/      # pg Pool + transaction helper
│   └── web/                   # Next.js 14 frontend (port 3000)
│       └── src/
│           ├── app/
│           │   ├── page.tsx              # Landing page
│           │   ├── restaurants/page.tsx  # Browse + map
│           │   ├── orders/[id]/track/    # Real-time order tracking
│           │   ├── driver/dashboard/     # Break-even dashboard
│           │   ├── restaurant/dashboard/ # Savings dashboard
│           │   └── admin/page.tsx        # Platform admin
│           ├── components/
│           │   └── map/MapView.tsx       # MapLibre GL JS
│           ├── hooks/
│           │   └── useDriverTracking.ts  # GPS + Socket.IO
│           └── lib/
│               ├── api.ts               # Axios client
│               └── osrm.ts             # OSRM routing client
└── docker-compose.yml

Pricing Model

Stakeholder Model Amount
Restaurant Monthly subscription $500/month
Restaurant Per-order fee $0.10/order
Restaurant CC processing (Stripe) 2.9% + $0.30
Driver Daily access fee $20/day
Driver Delivery fee $5 per delivery (kept 100%)
Driver Tips 100% kept
Customer Delivery fee $5 flat
Customer Hidden fees $0

Driver Break-Even

  • 4 deliveries × $5 = $20 → break even
  • Every delivery after #4 = pure profit
  • Tips never counted against break-even

Restaurant Savings Example (100 orders/day)

  • UberEats at 30% on $35 avg: $31,500/month
  • The Vibe: $500 + $300 + CC ≈ $3,400/month
  • Savings: ~$28,000/month

API Endpoints

Auth

POST /api/v1/auth/register
POST /api/v1/auth/login
GET  /api/v1/auth/me

Restaurants

GET  /api/v1/restaurants?lng=&lat=&radius=&cuisine=
GET  /api/v1/restaurants/savings-calculator?orders=&avgValue=
GET  /api/v1/restaurants/:slug
POST /api/v1/restaurants              (restaurant_owner)
GET  /api/v1/restaurants/dashboard/savings  (restaurant_owner)

Orders

POST   /api/v1/orders              (customer)
GET    /api/v1/orders/mine         (customer)
GET    /api/v1/orders/:id
PATCH  /api/v1/orders/:id/confirm  (restaurant_owner)
PATCH  /api/v1/orders/:id/ready    (restaurant_owner)
PATCH  /api/v1/orders/:id/pickup   (driver)
PATCH  /api/v1/orders/:id/delivered (driver)

Drivers

GET   /api/v1/drivers/me/session
POST  /api/v1/drivers/me/session/start
POST  /api/v1/drivers/me/session/end
PATCH /api/v1/drivers/me/location
GET   /api/v1/drivers/nearby?lng=&lat=

Payments (Stripe)

POST /api/v1/payments/restaurant/subscribe
POST /api/v1/payments/driver/daily-fee
POST /api/v1/payments/driver/payment-method
POST /api/v1/payments/orders/:orderId/intent
POST /api/v1/payments/webhook

Zones (GTA Geofencing)

GET /api/v1/zones
GET /api/v1/zones/geojson      # GeoJSON FeatureCollection
GET /api/v1/zones/check?lng=&lat=

Admin

GET   /api/v1/admin/stats
GET   /api/v1/admin/revenue?days=30
GET   /api/v1/admin/restaurants
GET   /api/v1/admin/drivers
PATCH /api/v1/admin/drivers/:id/approve

Map Stack

  • MapLibre GL JS — open-source map renderer (browser)
  • OpenStreetMap tiles via MapTiler (free tier)
  • OSRM — self-hosted routing engine (ontario-latest.osm.pbf)
  • PostGIS — geofencing, spatial queries, driver proximity

GTA Zones (active at launch)

  1. Downtown Toronto (priority 10)
  2. Liberty Village (priority 9)
  3. North York (priority 8)
  4. Scarborough (priority 7)
  5. Mississauga (priority 6)

Real-Time Architecture

Driver App          Socket.IO Gateway          Customer App
    │                      │                        │
    ├─ emit driver:location ──►                     │
    │                      ├─ emit driver:moved ────►│
    │                      │                        │
    │                      ◄── emit join:order ──────┤
    │                      │                        │
    │           Orders Service                       │
    │                      ◄── order:new ────────────┤
    │                      ├─ emit to restaurant room │

Driver location updates every 5 seconds via WebSocket. DB breadcrumbs written to delivery_tracking table.


Environment Variables Required

See .env.example for full list. Key ones:

  • DATABASE_URL — PostgreSQL + PostGIS connection string
  • STRIPE_SECRET_KEY — Stripe API key
  • STRIPE_RESTAURANT_PRICE_ID — $500/month Price ID in Stripe
  • JWT_SECRET — random secret, min 32 chars
  • NEXT_PUBLIC_MAPTILER_KEY — free MapTiler account for OSM tiles

Performance Targets

Metric Target
Restaurants 1,000+
Active drivers 5,000
Orders/day 50,000
Location updates/sec ~50,000 (drivers × 0.2hz)
DB connections max 20 (pg pool)

Scale path: Redis adapter for Socket.IO → horizontal Node scaling → Postgres read replicas.