Workgrid is a multi-tenant B2B SaaS operations platform for managing clients, projects, tasks, billing, team access, and workspace activity from a single admin console.
- Public app: https://workgrid-82sw.onrender.com
- Health check: https://workgrid-82sw.onrender.com/api/health/ready
Workgrid helps B2B teams run delivery operations with secure tenant isolation, role-aware access, soft-delete recovery, analytics dashboards, and production-style CI/CD foundations.
Core value
- Centralize client, project, task, billing, and activity operations in one workspace
- Enforce workspace-aware permissions and authenticated access across every major route
- Recover archived records safely with Mongo-backed soft delete and restore flows
- Demonstrate production-minded engineering with testing, Docker, and GitHub Actions CI
Tech stack
- Frontend: React, TypeScript, Vite, React Router
- Backend: Express, TypeScript, Zod, JWT auth, bcryptjs
- Database: MongoDB with Mongoose-backed persistence
- DevOps: Docker, Docker Compose, GitHub Actions, Vitest, Testing Library, Supertest
Highlights
- Multi-tenant onboarding with organization-scoped sessions
- Role and permission guards for workspace modules
- Clients, projects, tasks, billing, and activity management
- Refresh-token auth with HTTP-only cookie flow
- Optional demo workspace seeding for public showcase deployments
- Health, readiness, liveness, and metrics endpoints for observability
- Analytics widgets and polished dashboard UI
- CI pipeline for tests, builds, and Docker verification
React + Vite frontend
|
v
Express API layer
|
v
Auth + permissions + validation
|
v
MongoDB persistence layer
npm install
docker compose up mongo -d
npm run dev:api
npm run dev:webOpen:
- Deployment guide: docs/deployment-guide.md
- Demo video script: docs/demo-video-script.md
- Resume project summary: docs/resume-project-summary.md
- Interview prep: docs/interview-prep.md
- Live demo checklist: docs/live-demo-checklist.md
flowchart LR
A["Owner or Team Member"] --> B["Auth and Session Layer"]
B --> C["Workspace Dashboard"]
C --> D["Clients Module"]
C --> E["Projects Module"]
C --> F["Tasks Module"]
C --> G["Billing Module"]
D --> H["Create / Edit / Archive / Restore"]
E --> H
F --> H
H --> I["Activity Logs"]
H --> J["MongoDB Persistence"]
G --> J
flowchart TB
subgraph Frontend
UI["React and Vite SPA"]
Router["Route Modules"]
Session["Session Provider"]
end
subgraph Backend
API["Express API"]
Auth["JWT Access Tokens"]
Refresh["HTTP-only Refresh Cookies"]
Guards["Auth and Permission Guards"]
Services["Clients, Projects, Tasks, Billing, Activity Services"]
end
subgraph Data
Mongo[("MongoDB")]
end
subgraph DevOps
CI["GitHub Actions CI"]
Docker["Docker and Compose"]
end
UI --> Router
Router --> Session
Session --> API
API --> Auth
API --> Refresh
API --> Guards
Guards --> Services
Services --> Mongo
CI --> Docker
Docker --> API
Docker --> UI
erDiagram
ORGANIZATION ||--o{ MEMBERSHIP : has
USER ||--o{ MEMBERSHIP : joins
ORGANIZATION ||--o{ CLIENT : owns
ORGANIZATION ||--o{ PROJECT : owns
ORGANIZATION ||--o{ TASK : owns
ORGANIZATION ||--o{ INVOICE : owns
ORGANIZATION ||--o{ ACTIVITY_LOG : records
ORGANIZATION ||--|| SUBSCRIPTION : has
USER ||--o{ AUTH_SESSION : opens
MEMBERSHIP ||--o{ AUTH_SESSION : authorizes
CLIENT ||--o{ PROJECT : contains
PROJECT ||--o{ TASK : tracks
CLIENT ||--o{ INVOICE : billed_for
PROJECT o|--o{ INVOICE : may_bill
ORGANIZATION {
string id
string name
string slug
string plan
string industry
string timezone
string currency
}
USER {
string id
string name
string email
string title
string password_hash
}
MEMBERSHIP {
string id
string organizationId
string userId
string role
string permissions
string status
}
CLIENT {
string id
string organizationId
string name
string status
string accountManager
string deletedAt
}
PROJECT {
string id
string organizationId
string clientId
string name
string status
string health
string ownerId
string deletedAt
}
TASK {
string id
string organizationId
string projectId
string title
string status
string assigneeId
string dueDate
string deletedAt
}
INVOICE {
string id
string organizationId
string clientId
string projectId
number amount
string currency
string status
}
ACTIVITY_LOG {
string id
string organizationId
string actorName
string action
string entityType
string entityName
}
SUBSCRIPTION {
string organizationId
string plan
number seats
string status
string renewalDate
}
AUTH_SESSION {
string id
string userId
string organizationId
string membershipId
string refreshTokenHash
string expiresAt
}
- Workspace onboarding and login
- Role-aware tenant dashboard
- Clients, projects, tasks, billing, and activity feeds
- Secure password hashing with
bcryptjs - Signed auth tokens with
jsonwebtoken - MongoDB persistence with required database startup
- MongoDB-only backend mode
- Passwords are hashed before storage
- Authenticated routes require signed bearer tokens
- Tenant data is filtered by
organizationId - Sensitive API routes use centralized auth middleware
- Production mode can serve frontend and API from one origin
npm installCopy apps/api/.env.example to apps/api/.env and set:
PORT=4000
NODE_ENV=development
CLIENT_URL=http://localhost:5173
JWT_SECRET=replace-with-a-long-random-secret
JWT_EXPIRES_IN=7d
MONGODB_URI=mongodb://localhost:27017/workgrid
SERVE_STATIC_FRONTEND=false
DEMO_MODE=falseIf you have Docker installed:
docker compose up mongo -dnpm run dev:api
npm run dev:webFrontend:
API:
Workgrid includes a GitHub Actions workflow that runs on every push and pull request to:
- install dependencies with
npm ci - run API and web tests
- run the full production build
- validate the Docker image can be built successfully
Workflow file:
.github/workflows/workgrid-ci.yml
docker compose up --buildOpen:
This runs:
- MongoDB in one container
- The app in one container
- The frontend served by Express in production mode
- Create a Linux VM
- Install Docker and Docker Compose
- Clone this project
- Set production values in
docker-compose.ymlor an env file - Run:
docker compose up -d --build- Open port
4000in the firewall or place Nginx in front - Point your domain to the VM IP
- Push this repo to GitHub
- Create a new service from the repo
- Use the root
Dockerfile - Set environment variables:
PORT=4000NODE_ENV=productionJWT_SECRET=<long-random-secret>JWT_EXPIRES_IN=7dMONGODB_URI=<managed-mongodb-connection-string>SERVE_STATIC_FRONTEND=trueCLIENT_URL=<your-app-url>
- Deploy
- Create a MongoDB Atlas cluster
- Create a database user
- Add network access rules
- Copy the Atlas connection string into
MONGODB_URI - Deploy the Docker app to your cloud platform
- Replace the default
JWT_SECRET - Replace the default
REFRESH_TOKEN_SECRET - Use MongoDB Atlas or a secured private Mongo instance
- Put the app behind HTTPS in production
- Restrict MongoDB network access
- Enable
DEMO_MODEonly for showcase environments - Use
/api/health/readyfor hosting health checks - Use
/api/health/metricsfor lightweight operational visibility
npm run build
npm run test
npm run test:api
npm run test:web
npm run start
docker compose up --build
docker compose downUdit Singh