Collaborate is a full-stack team collaboration platform for planning work, managing teams, tracking tasks, generating AI-assisted project roadmaps, chatting in real time, and running browser-based meetings.
This repository is a monorepo with three apps:
server/for the Node.js + Express + MongoDB backendclient/for the React + Redux + Vite web appmobile/for a Flutter starter app
This document is intended to be the main source of truth for how the codebase works. It explains:
- the overall architecture
- how the frontend is wired
- how the backend is wired
- authentication and request flow
- data models
- API routes
- realtime Socket.IO and WebRTC behavior
- local setup
- environment variables
- deployment notes
- common failure points and debugging tips
The app is split into a client and server:
- The React client renders pages, dispatches Redux actions, and calls the API through Axios.
- The Express server handles authentication, CRUD operations, AI roadmap generation, messaging, meetings, and organisation management.
- MongoDB stores users, teams, projects, tasks, conversations, messages, meetings, and organisations.
- Socket.IO is used for presence, meeting signaling, and chat notifications.
The most important flow is:
- The frontend sends a request to the backend using
client/src/utils/api.js. - The backend authenticates the request with
server/middleware/authMiddleware.js. - The controller performs database work through Mongoose models.
- The response is returned to Redux and then rendered in the UI.
- React
- Vite
- React Router
- Redux
- Redux Thunk
- Redux Persist
- Axios
- Socket.IO client
- React Icons
The Redux store is defined in client/src/store.js.
Important slices:
userLoginstores the logged-in user and JWTteamList,teamCreate,teamJoin,teamDelete,teamDetailsprojectList,projectCreate,projectUpdate,projectDelete,projectDetails,projectCreateWithAItaskList,taskCreate,taskUpdate,taskDelete,taskDetailsorgCreate,orgList,orgDetails,orgUpdate,orgDelete,orgInvite,orgCurrentmessageList,messageSend,messageMarkReadserverStatustracks whether the API appears online
Redux persistence currently keeps:
userLoginorgCurrent
All client API calls go through client/src/utils/api.js.
Behavior:
- Axios
baseURLcomes fromclient/src/config/runtime.js - JWT is injected automatically from the Redux store in a request interceptor
- server offline / online state is updated based on response success or network failure
This means most feature actions do not need to manually attach the token, although some actions still do for parity.
Main app routing is in client/src/App.jsx.
The app shell is:
- a fixed left sidebar on authenticated routes
- a main content area to the right
- a public landing page at
/
Important route groups:
- Public:
/,/login,/register,/invite/accept - Auth protected:
/dashboard,/projects,/teams,/tasks,/chat,/settings,/organisations/* - Project detail and task detail pages are also routed in the main app shell
Key screens in client/src/screens/:
LandingPage.jsxfor the marketing homepageLoginScreen.jsxandRegisterScreen.jsxfor authHomeScreen.jsxfor the dashboardOngoingProjectsScreen.jsxandProjectScreen.jsxfor project browsing and detailTaskScreen.jsxandTaskEditScreen.jsxfor task managementTeamScreen.jsxandTeamDetailsScreen.jsxfor teamsOrganisationsScreen.jsx,CreateOrganisationScreen.jsx,OrganisationDetailScreen.jsxChatScreen.jsxfor chatMeetingScreen.jsxfor video meetingsProfileScreen.jsxandSettingsScreen.jsx
Useful shared components live in client/src/components/:
Sidebar.jsxfor the app navigationOrgSwitcher.jsxfor selecting the active organisationChatDocked.jsx,ChatPanel.jsx,ChatSidebar.jsx,MessageList.jsx,MessageInput.jsxTaskSideDrawer.jsxandProjectCreateModal.jsxGoalModal.jsx,UserGuideModal.jsx,Loader.jsx,Message.jsx
- Node.js
- Express
- MongoDB
- Mongoose
- JWT
- bcryptjs
- Socket.IO
- Groq SDK
The backend entry file is server/index.js.
It is responsible for:
- creating the Express app
- creating the HTTP server
- mounting Socket.IO
- installing middleware
- mounting API routes
- attaching the global error handler
- connecting to MongoDB before listening
The server currently uses:
express.json()express.urlencoded({ extended: true })cors()- request logging middleware
notFoundanderrorHandler
Important middleware files:
- server/middleware/authMiddleware.js
- server/middleware/asyncHandler.js
- server/middleware/errorMiddleware.js
Auth middleware responsibilities:
- read the JWT from
Authorization: Bearer <token> - verify the token using
JWT_SECRET - fetch the user from MongoDB
- attach
req.user - return
401if the token or user is invalid
Async handler responsibilities:
- wrap async route handlers
- forward rejected promises to Express error middleware
The error middleware returns JSON errors instead of a blank HTML response. This is critical for debugging production failures.
Fields:
nameemailpasswordroleprofileImagetechStackteamsorganisationsreputationScore
Notes:
- password is hashed before save
matchPassword()compares user input against the stored hashprofileImageis persisted and returned in auth/profile responses
Fields:
namememberstasksprojectsownerorganisationpendingJoinRequests
Notes:
- teams can exist with or without an organisation for backward compatibility
Fields:
nameslugdescriptionlogoownermembersteamspendingInvitessettings
Notes:
slugis generated from the name and kept uniqueowneris requiredsettingshas a default object so new orgs can be created without extra payload
Fields:
namegoalownerteamorganisationtasksdueDate
Notes:
organisationis optional for compatibility- AI-generated projects create a project document first, then associated tasks
Task concepts:
- task metadata
- duration
- priority
- status
- assignee
- dependencies
- parent / subtask hierarchy
- project link
- team link
Additional models:
All API routes are mounted under /api.
POST /api/users/registerPOST /api/users/loginGET /api/usersGET /api/users/searchGET /api/users/profilePATCH /api/users/profilePATCH /api/users/profile/image
POST /api/teamsGET /api/teamsGET /api/teams/:idDELETE /api/teams/:idPUT /api/teams/:id/membersPOST /api/teams/:id/joinPUT /api/teams/:id/join
server/routes/projectRoutes.js
GET /api/projectsPOST /api/projectsPOST /api/projects/aiGET /api/projects/:idPUT /api/projects/:idDELETE /api/projects/:id
POST /api/tasksGET /api/tasksGET /api/tasks/:idPUT /api/tasks/:idDELETE /api/tasks/:id
server/routes/messageRoutes.js
POST /api/messagesGET /api/messages/team/:teamIdGET /api/messages/conversation/:conversationIdPUT /api/messages/read
server/routes/meetingRoutes.js
POST /api/teams/:teamId/meetingsGET /api/teams/:teamId/meetingsPUT /api/teams/:teamId/meetings/:meetingId
server/routes/organisationRoutes.js
POST /api/organisationsGET /api/organisationsGET /api/organisations/:idPUT /api/organisations/:idDELETE /api/organisations/:idGET /api/organisations/:id/membersPOST /api/organisations/:id/members/invitePUT /api/organisations/:id/members/:userId/roleDELETE /api/organisations/:id/members/:userIdGET /api/organisations/:id/teamsGET /api/organisations/invite/accept
- User submits email and password.
loginUservalidates credentials.- Server returns a JWT and user payload.
- Frontend stores
userInfoin Redux and persistence.
- User enters project name, goal, due date, and optional team.
- Frontend dispatches
createProjectorcreateProjectWithAI. - Backend creates the project and optionally links it to a team.
- AI project creation additionally generates a roadmap from Groq and persists tasks recursively.
- User submits the organisation form.
- Frontend dispatches
createOrganisation. - Backend generates a unique slug.
- Backend creates the organisation document.
- Backend adds the owner to the org members list.
- Backend adds the org to the user’s
organisationsarray.
- User submits team name and optional organisation.
- Backend creates the team.
- If organisation is supplied, the team is attached to that organisation.
- The team is added to the owner’s
teamsarray.
- A team member starts a meeting.
- The backend saves the meeting state.
- Socket.IO broadcasts meeting state and participant changes.
Socket.IO is initialized in server/index.js.
joinTeamRoomstartMeetingendMeetinguserJoineduserLeftparticipantsUpdateduser-connecteduser-disconnectedtoggle-cameratoggle-miccamera-toggledmic-toggledjoinConversationleaveConversationnewMessagechat messageofferanswerice-candidate
The app uses Socket.IO as the signaling transport and the browser WebRTC API for peer-to-peer media exchange.
Flow:
- Users join the team room.
- The app exchanges offers and answers over Socket.IO.
- ICE candidates are relayed.
- Media tracks are attached to the peer connections.
- Camera and mic toggles are broadcast to the room.
Chat uses a mixture of:
- backend message persistence
- Redux actions
- periodic polling in the UI
- socket events for newer room updates
PORTMONGO_URIJWT_SECRETGROQ_API_KEYNODE_ENV
VITE_API_URLVITE_SOCKET_URLVITE_MCP_GATEWAY_URLVITE_API_TIMEOUT_MS
If frontend env vars are not set, client/src/config/runtime.js falls back to the production URLs in client/src/config/productionUrls.js.
cd server
npm install
npm startExample server/.env:
PORT=3002
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_secret_key
GROQ_API_KEY=your_groq_api_key
NODE_ENV=developmentcd client
npm install
npm run devcd mobile
flutter pub get
flutter runThe backend is designed to run on Render with:
npm startas the start commandnode index.jsas the entrypoint in server/package.jsonMONGO_URIconfigured in Render environment variablesJWT_SECRETconfigured in Render environment variables
The frontend is configured to hit the Render API URL in production through client/src/config/productionUrls.js.
These are the areas that typically break first:
protectmiddleware failures when the JWT or secret is missing- MongoDB connection issues from an invalid
MONGO_URI - Missing or stale client auth state in Redux Persist
- Validation failures when required model fields are not supplied
- CORS / origin mismatches between the Vercel frontend and Render backend
- UI pages relying on older CSS class names or duplicate legacy styles
- Some legacy route files still exist alongside the newer
server/routes/versions. - Some screen files are duplicated between
client/src/components/andclient/src/screens/. - Chat still has polling behavior in parts of the UI.
- The meeting screen is large and could be split into smaller modules.
- Some page styles are still being migrated from older layout systems to the newer dark design language.
- Add automated tests for auth, project creation, organisation creation, and team creation.
- Add request logging around all protected create endpoints.
- Replace remaining legacy duplicate screen/component files with a single canonical version.
- Add API docs or an OpenAPI spec.
- Add a short troubleshooting section for Render deployment and auth failures.