CruciDrive is organized as a monorepo with two first-class environments at the root:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DavidCevallos15/Crucidrive---APP/llms.txt
Use this file to discover all available pages before exploring further.
/backend (Node.js + Express + Socket.io) and /frontend (React Native via Expo). Both applications share a single Supabase project as the persistent data layer, but are developed, configured, and deployed independently. The backend exposes a dual-transport server — REST over HTTP for stateless operations and WebSockets for real-time GPS and chat events — while the mobile frontend consumes both channels simultaneously during an active ride.
Monorepo Structure
The full directory layout of the project, as defined inESTRUCTURA.md, is:
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React Native (Expo 57) | Cross-platform iOS and Android mobile app |
| Backend | Node.js + Express 5 | REST API and Socket.io server |
| Database | PostgreSQL + PostGIS | Relational data and geospatial proximity queries |
| Auth | Supabase Auth | Phone OTP authentication and JWT issuance |
| Real-time | Socket.io 4 | Live GPS tracking and in-ride chat |
| State | Zustand 5 | Frontend global state management |
| UI | NativeWind + expo-blur | Glassmorphic design system |
package.json files:
express^5.2.1,socket.io^4.8.3,@supabase/supabase-js^2.110.0 (backend)expo~57.0.1,react-native0.86.0,zustand^5.0.0,socket.io-client^4.8.0,expo-blur~57.0.0,react-native-reanimated4.5.0,expo-location~57.0.1 (frontend)
Architecture Patterns
Modular Monolith (Backend) The backend is a single Node.js process (src/index.js) that boots an Express HTTP server and a Socket.io server, both sharing the same underlying http.Server instance. Functionality is divided into discrete modules — routes/, controllers/, middlewares/, sockets/ — following separation of concerns without the operational overhead of microservices.
MVC in Express
HTTP requests flow through a strict three-layer chain:
POST /api/auth/registro— complete user profile creation after Supabase phone OTP sign-upPOST /api/viajes/solicitar— passenger creates a ride request;POST /api/viajes/aceptar— driver accepts a pending ride;PATCH /api/viajes/:id/estado— updates ride state (en_curso,finalizado,cancelado)GET /api/chats/:threadId/mensajes— fetch the full message history for a specific chat thread
src/store/. Zustand’s minimal API avoids boilerplate while keeping state updates reactive and co-located with the logic that triggers them.
Glassmorphic UI System
All UI containers (modals, ride cards, navigation bars, map overlays) use semi-transparent backgrounds (rgba(255, 255, 255, 0.1)), backdrop-blur via expo-blur’s <BlurView>, subtle borders, and soft drop shadows. Screen transitions and loading states are animated at 60 fps via react-native-reanimated 4.
Data Flow
CruciDrive uses two transport layers in parallel:- REST (HTTP) — used for stateless, transactional operations: authentication, ride creation, ride acceptance, status changes, and fetching chat history.
- WebSockets (Socket.io) — used for continuous, bidirectional real-time communication: live GPS position broadcasts from drivers to passengers, and in-ride chat message delivery.
Socket.io Event Reference
ThesocketHandler.js module registers three event groups on the Socket.io server:
| Event (Client → Server) | Direction | Description |
|---|---|---|
join_sector | Client → Server | Driver or passenger joins a geographic sector room |
update_location | Client → Server | Driver broadcasts new GPS coordinates; persisted to tricimotos.ubicacion_actual |
location_updated | Server → Client | Broadcast to all clients in the sector room with driver position and status |
join_chat | Client → Server | Authenticated user joins a per-trip chat room (membership verified against thread_members) |
send_message | Client → Server | User sends a message; persisted to messages table and broadcast to the room |
message_received | Server → Client | Broadcast to all members of the chat room with the full message record |
connection event fires. The middleware reads the bearer token from socket.handshake.auth.token, validates it against Supabase Auth, and attaches the resolved user profile (including rol) to socket.user.
Database Schema Overview
The Supabase PostgreSQL database (database.sql) defines 6 tables with PostGIS and full Row Level Security enabled:
CREATE EXTENSION IF NOT EXISTS postgis, and both tricimotos.ubicacion_actual and viajes.origen/viajes.destino use GEOGRAPHY(POINT, 4326) — the WGS 84 coordinate system used by GPS receivers.
Security Model
CruciDrive implements a layered security model across the REST and WebSocket layers: JWT Validation on Every Request TheauthMiddleware.js extracts the Authorization: Bearer <token> header on every protected REST route and calls supabase.auth.getUser(token) to validate it. Invalid or expired tokens receive a 401 response immediately. The same token validation runs as a Socket.io io.use() middleware — unauthenticated WebSocket connections are rejected before the connection event fires.
Role-Based Middleware
roleMiddleware.js gates specific routes by the rol field from the user’s perfiles record. For example, only users with rol: 'conductor' can emit update_location events, and only users with rol: 'admin' can access administrative endpoints.
Supabase Row Level Security (RLS)
Every table has RLS enabled. Key policies include:
perfiles: any authenticated user can read all profiles; users can only insert or update their own profile rowtricimotos: drivers can only update their own vehicle recordviajes: passengers and drivers can only read/update trips they are a party tomessages: users can only read or insert messages in chat threads they are a member of
Explore Further
Roles & Permissions
Deep dive into the
pasajero, conductor, and admin role model and how permissions are enforced at the middleware and RLS layers.Ride Lifecycle
Follow a trip from
solicitado through aceptado, en_curso, and finalizado — including the REST endpoints and state transitions at each stage.Geolocation & Sectors
Learn how PostGIS
GEOGRAPHY(POINT, 4326) columns, the toWKT utility, and Socket.io sector rooms power proximity matching and live driver tracking.Real-time Chat
Understand the
threads → thread_members → messages schema, WebSocket room management, and how chat membership is enforced per trip.