╔══════════════════════════════════════════════════════════════╗ ║ ║ ║ ████ ██████ ██ ██ ██████ ██████ ██ ██ ██████ ██ ║ ║ ██ ██ ███ ██ ██ ██ ███ ██ ██ ██ ║ ║ ████ ████ ██ █ ██ ██ ██ ██ █ ██ ████ ██ ║ ║ ██ ██ ██ ███ ██ ██ ██ ███ ██ ██ ║ ║ █████ ██████ ██ ██ ██ ██████ ██ ██ ██████ ██████ ║ ║ ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝
A modern security and emergency response ecosystem connecting clients, control rooms, security personnel, and response teams through web and mobile applications for faster, smarter protection.
- Overview
- Features
- Architecture
- Project Structure
- Prerequisites
- Environment
- Getting Started
- Useful Scripts
- Database
- Testing and Quality
- Docker and Deployment
- Contributing
- License
Sentinel is a TypeScript monorepo for a security operations platform. It currently includes a NestJS API, a Next.js web console, an Expo mobile client, shared validation schemas, shared auth/device types, and infrastructure for local services and production deployment.
The product surface focuses on authentication, organization onboarding, role-aware dashboards, user invitation workflows, profile management, and mobile client authentication with password reset support.
- Organization onboarding for security companies with an initial organization admin.
- Better Auth email/password authentication with required email verification.
- Session-backed web auth and token-backed mobile auth.
- Password reset flows for web links and mobile OTP-style reset.
- Email delivery pipeline with Bull, Redis, Nodemailer, Mailpit for local development, and Resend support for production.
- Multi-tenant organization and user model with roles for
SUPER_ADMIN,ORG_ADMIN,CONTROL_ROOM,MANAGER,RESPONDER,GUARD, andCLIENT. - Organization user management, including invites, invite acceptance, resend invite, role updates, status updates, editing, deletion, search, filtering, and pagination.
- Role-aware web dashboard surfaces for operations staff and responders.
- Profile read/update endpoints and web profile management.
- Expo mobile auth screens for sign in, sign up, OTP, email check, phone verification, forgot password, reset password, and a basic home screen.
- Shared Zod schemas in
@sentinel/schemasand shared domain types in@sentinel/types. - Docker Compose support for local Postgres, Redis, and Mailpit.
- Production Dockerfiles for API and web, with PM2 runtime configs and nginx config templates.
| Area | Workspace | Stack | Default Port |
|---|---|---|---|
| API | apps/api |
NestJS, Better Auth, Prisma, Postgres, Redis, Bull | 4000 |
| Web | apps/web |
Next.js, React, Tailwind CSS, React Query | 3000 |
| Mobile | apps/mobile |
Expo, Expo Router, React Native | Expo assigned |
| Docs | apps/docs |
Next.js | 3001 |
| Schemas | packages/schemas |
Zod validation schemas | n/a |
| Types | packages/types |
Shared TypeScript domain types | n/a |
| UI | packages/ui |
Shared React UI primitives | n/a |
apps/
api/ NestJS API, Prisma schema, auth, users, profile, queues
web/ Next.js web application and dashboard
mobile/ Expo mobile application
docs/ Next.js documentation app
packages/
schemas/ Shared Zod schemas for auth, users, and profile
types/ Shared auth and device types
ui/ Shared React UI components
eslint-config/
typescript-config/
infra/
docker/ Development and production compose files
nginx/ API and web nginx configs
pm2/ API and web PM2 runtime configs
scripts/ Deployment and database backup scripts
- Node.js
>=18for local development. The Docker images use Node22-alpine. - Yarn
4.12.0via Corepack. - Docker and Docker Compose for local Postgres, Redis, and Mailpit.
Enable Yarn through Corepack if needed:
corepack enableThe repo currently has local .env files, but no committed .env.example. Create the files below for a new checkout and keep secrets out of source control.
Root .env is used by Docker Compose defaults. The API expects apps/api/.env; production uses apps/api/.env.production.
Required API values:
DATABASE_URL="postgresql://postgres:postgres@localhost:5434/sentinel"
REDIS_URL="redis://localhost:6381"
BETTER_AUTH_SECRET="replace-with-a-long-random-secret"
BETTER_AUTH_URL="http://localhost:4000"
FRONTEND_URL="http://localhost:3000"Common optional API values:
APP_NAME="Sentinel"
PORT="4000"
CORS_ORIGINS="http://localhost:3000"
MAILPIT_HOST="localhost"
MAILPIT_SMTP_PORT="1027"
MAILPIT_WEB_URL="http://localhost:8027"
RESEND_API_KEY=""
RESEND_FROM_EMAIL=""
LOGTAIL_SOURCE_TOKEN=""
LOGTAIL_ENDPOINT=""
AUTH_COOKIE_DOMAIN=""Web environment in apps/web/.env:
NEXT_PUBLIC_API_URL="http://localhost:4000"Mobile environment in apps/mobile/.env:
EXPO_PUBLIC_API_URL="http://localhost:4000"Install dependencies:
yarn installStart local infrastructure:
yarn docker:devGenerate the Prisma client and apply migrations:
yarn workspace api db:generate
yarn workspace api db:migrate:deploySeed development data if needed:
yarn workspace api db:seedRun the full monorepo in development mode:
yarn devOr run apps individually:
yarn workspace api dev
yarn workspace web dev
yarn workspace mobile start
yarn workspace docs devLocal service URLs:
- Web:
http://localhost:3000 - API:
http://localhost:4000 - Docs:
http://localhost:3001 - Mailpit:
http://localhost:8027 - Postgres:
localhost:5434 - Redis:
localhost:6381
Root scripts:
yarn dev # Run all workspace dev tasks through Turborepo
yarn build # Build all workspaces
yarn lint # Lint all workspaces
yarn check-types # Type-check all workspaces
yarn format # Format TypeScript, TSX, and Markdown files
yarn docker:dev # Start local Postgres, Redis, and MailpitAPI scripts:
yarn workspace api dev
yarn workspace api build
yarn workspace api start:prod
yarn workspace api test
yarn workspace api test:e2e
yarn workspace api test:cov
yarn workspace api db:generate
yarn workspace api db:migrate:deploy
yarn workspace api db:seedWeb, mobile, and docs scripts:
yarn workspace web dev
yarn workspace web build
yarn workspace web check-types
yarn workspace mobile start
yarn workspace mobile android
yarn workspace mobile ios
yarn workspace docs devPrisma models cover organizations, users, invitations, role-specific profiles, sessions, accounts, and verification tokens.
The local Docker Compose file creates:
- Postgres database
sentinelon host port5434. - Redis on host port
6381. - Mailpit SMTP on host port
1027and web inbox on host port8027.
Production admin seed scripts are available for controlled production setup:
yarn workspace api db:seed:prod-admin
yarn workspace api db:seed:prod-admin-orgThese expect the matching PROD_SECURITY_ORG_* and PROD_SUPER_ADMIN_* environment variables from apps/api/src/config/env.schema.ts.
Run all workspace checks:
yarn lint
yarn check-types
yarn buildRun API tests:
yarn workspace api test
yarn workspace api test:e2e
yarn workspace api test:covThe API has focused tests for app bootstrapping, password reset, registration, users, profile, Redis queue options, and logger behavior.
Development infrastructure:
yarn docker:devProduction compose builds the API and web images:
docker compose -f infra/docker/docker-compose.prod.yml up -d --buildProduction compose expects:
apps/api/.env.productionapps/web/.env.production
The API image exposes port 4000 and uses infra/pm2/api.ecosystem.config.cjs. The web image exposes port 3000 and uses infra/pm2/web.ecosystem.config.cjs.
nginx config templates live in:
infra/nginx/api.confinfra/nginx/web.conf
Deployment helper scripts live in infra/scripts/.
- Fork the repository.
- Create a feature branch.
- Install dependencies with
yarn install. - Start local services with
yarn docker:dev. - Make changes with focused tests.
- Run
yarn lint,yarn check-types, and relevant tests before opening a pull request.
No project license file is currently committed. Add a LICENSE file before publishing or distributing this project.