This file defines the conventions any automated agent (Cursor, Claude, Copilot, etc.) or human contributor should follow when working inside this monorepo. Read it before making changes.
server/— Express + MongoDB + Socket.IO backend. Entry:index.js.client/— React 19 web app (Create React App). Entry:src/App.js.mobile/— Expo React Native rider app. Entry:app/_layout.tsx.ai-core/— Experimental; not required for the platform to run.
Cross-package refactors must update all three apps if they touch a shared contract (API shape, socket event, fare rule).
These rules exist so data never drifts between apps. Violate them only with an explicit callout in the PR description.
- Fare math lives in
server/utils/fareCalculator.js. Both the mobile Fare Info screen and the web Fares page must read from/api/rides/fare-info. Never hardcode rates in the clients. - Socket event names are defined in
server/services/SocketService.js. Clients must import or mirror the constants, never invent new ones. - Role gates are enforced on the server.
Client-side route guards (e.g.
RoleProtectedRoute) are UX hints, not security. Every privileged endpoint must callprotect+ arequire*middleware. - IDs are Mongo ObjectId strings. Do not expose numeric surrogates.
- Language targets: Node 18+, React 19, React Native 0.81. Use
modern syntax (optional chaining,
??, top-levelawaitwhere valid). - Formatting: two-space indentation, semicolons, trailing commas in multi-line arrays and objects.
- Imports: absolute within a package when CRA/Expo supports it; otherwise relative.
- File names:
PascalCasefor React components,camelCasefor modules,kebab-casefor CSS files. - Don't add one-line narration comments. Only comment to explain why something non-obvious exists.
- Scroll-triggered animations use
viewport={{ amount: 0.2, margin: "-80px" }}so they fire in both directions. Avoidonce: trueunless the animation is specifically a one-shot reveal. - Keep the 3D hero (
client/src/components/Hero3D.js) inside a bounded stage. Never render it as a page-wide background overlay. - Toast / notification primitives expect
{ message, type, onClose }— when raising a toast in a parent component, always destructure and forward these explicitly.
- Use design tokens (slate / blue) already established on the landing page. Don't introduce new accent palettes without updating the whole brand sweep.
- Keep
index.jssmall. Heavy logic lives inservices/(Socket, AutoCancel, Scheduling) androutes/*.js. - Every new route must be documented in the route table in
server/README.md. - Every new socket event must be listed in the real-time table in the
root
README.md.
- Dispatcher-targeted events go to the
dispatchroom. - Driver-targeted events go to
driver:<id>. - Ride-scoped events go to
ride:<id>(rider + driver + dispatch). - Do not broadcast raw GPS packets to the public; only the
fleet:snapshotaggregate is open.
- Never commit real secrets.
server/.envis gitignored by convention. - When adding a new env var, document it in both the root
README.mdand the package's own README. - For mobile, all runtime env vars must be prefixed
EXPO_PUBLIC_or declared underexpo.extrainapp.json.
- Before opening a PR, at minimum:
- Run
npm run lintin any package you touched (where configured). - Boot the affected app locally and smoke-test the modified flow.
- Run
- When modifying fare logic, run
node server/utils/__fareTest.js. - When modifying real-time code, verify at least one dispatch → driver and driver → rider round trip through the socket.
When you're an AI agent making non-trivial edits:
- Read the relevant README(s) first (root + the package you're in).
- Confirm the change doesn't violate any source-of-truth rule above.
- If you modify the 3D hero, preserve the
mode="auto"day/night behavior unless the user explicitly asks otherwise. - If you add a dependency, update the matching
package.jsonand call it out in the PR description. - After substantive edits, run the lint / type-check tools that exist for the package.
- Never commit without explicit user approval.
- Imperative mood, present tense: "Add driver walkie channel".
- Reference the package when relevant: "server: fix auto-cancel race".
- Do not include decorative emojis unless the user requested them.