Alarm dispatch and field investigation management platform for Pipeline Intrusion Detection Systems (PIDS).
This system enables operators to log intrusion alarms, route incidents based on pipeline chainage, assign field responders, capture geo-validated investigation reports, and track alarm closure lifecycle.
- Framework: Next.js 16.1 (App Router, server components, server actions)
- Language: TypeScript
- Database: PostgreSQL (via Prisma)
- ORM: Prisma with
@prisma/adapter-pg - Auth: Auth.js / NextAuth v5 (credentials provider, JWT sessions)
- UI: Tailwind v4, custom design tokens, Lucide Icons
- Storage: Azure Blob Storage for alarm evidence (fallback: local
public/uploadswhen not configured) - Hosting (target): Azure App Service + Azure Database for PostgreSQL
- Alarm creation from PIDS readings
- Chainage-based alarm routing
- Territory visibility for supervisors & RMP
- Self & supervisor assignment
- Field investigation reporting
- Geo-location capture during remarks
- Photo evidence uploads
- Alarm lifecycle tracking
- Role-based access control (RBAC)
- Audit logging
- Operator (Admin) — Creates & closes alarms, manages users
- Supervisor — Assigns & monitors alarms
- Night Supervisor — Extended chainage coverage
- RMP — Field investigation & reporting
- ER — Emergency response (RMP equivalent)
- QRV Supervisor — Oversight monitoring
- Alarm created by Operator
- Routed via chainage mapping
- Assigned to RMP
- Field investigation performed
- Geo + photo evidence submitted
- Operator reviews & closes
app/
(auth)/ → Legacy auth group (replaced by /auth routes)
(dashboard)/ → Role dashboards (operator, supervisor, rmp, qrv)
api/ → Route handlers (NextAuth)
auth/ → Sign in, register, error, redirect pages
loading.tsx → Global app loading UI
(dashboard)/loading.tsx → Dashboard skeleton while data loads
components/
ui/ → Design system primitives (Button, Card, Table, Badge, Modal…)
layout/ → App shell (navbar, sidebar, dashboard shell)
alarms/ → Alarm-specific UI (scoped tables, assign modal)
formComponents/ → Forms + their server actions (create alarm, chainage, mapping, profile, verify)
dashboard/alarms/ → Role-aware alarms UX (operator/supervisor/RMP/QRV)
lib/
auth/ → NextAuth config, session helpers, role guard, dashboard paths
alarm/ → Alarm repository + scoped alarm loader
assignment/ → Assignment repository (create/accept/reassign)
verification/ → Verification repository + review queries
evidence/ → Evidence upload & validation
scope/ → Alarm scoping by role/chainage
sla/ → SLA configuration + breach engine
geo/ → Geo helpers (distance, browser location)
validation/ → Zod schemas
db.ts → Prisma client
types/ → Shared domain & UI types (alarm, assignment, verification, geo, SLA, actions, UI, chainage mapping)
constants/ → Shared constants (auth, roles, alarm options, evidence, UI breakpoints, badge variants, dashboard config)
prisma/ → `schema.prisma`, migrations, seed script
docs/ → Phase specs, implementation notes
proxy.ts → Next.js 16.1 proxy for auth-aware redirects
- Auth routes:
/auth/signin– credentials sign-in (NextAuth)/auth/register– operator self‑registration/auth/error– friendly error surface for NextAuth error codes
- Dashboards by role (guarded on the server and via proxy):
OPERATOR→/operatorSUPERVISOR/NIGHT_SUPERVISOR→/supervisorRMP/ER→/rmpQRV_SUPERVISOR→/qrv
- Proxy protection (
proxy.ts):- If logged in, visiting
/auth/*redirects to the correct dashboard. - If not logged in, visiting any non‑public page redirects to
/auth/signinwith acallbackUrlback to the original path. /api/*and static assets are excluded from proxy checks.
- If logged in, visiting
Create .env (see also docs/azure-postgres-connection.md for Azure Web App):
DATABASE_URL= # PostgreSQL connection string
AUTH_SECRET= # or NEXTAUTH_SECRET — session signing
NEXTAUTH_URL= # app URL (e.g. https://your-app.azurewebsites.net)
# Evidence storage (optional — if unset, files are stored under public/uploads)
AZURE_STORAGE_CONNECTION_STRING= # Azure Storage connection string (from Portal → Storage account → Access keys)
AZURE_STORAGE_EVIDENCE_CONTAINER= # container name (default: evidence)
# AZURE_STORAGE_EVIDENCE_BASE_URL= # optional: CDN or custom domain base URL for serving blobs
# Web Push (optional — RMP notifications when alarms are created in their chainage)
# Generate keys: node -e "const w=require('web-push');const k=w.generateVAPIDKeys();console.log('VAPID_PUBLIC_KEY='+k.publicKey);console.log('VAPID_PRIVATE_KEY='+k.privateKey);console.log('NEXT_PUBLIC_VAPID_PUBLIC_KEY='+k.publicKey);"
VAPID_PUBLIC_KEY= # public key (base64url)
VAPID_PRIVATE_KEY= # private key (base64url)
NEXT_PUBLIC_VAPID_PUBLIC_KEY= # same as VAPID_PUBLIC_KEY (used by client to subscribe)For Azure Blob evidence: create a Storage account, then set the container’s Public access level to Blob (anonymous read access for blobs only) so evidence images load in the app, or use a CDN and set AZURE_STORAGE_EVIDENCE_BASE_URL.
pnpm install
pnpm prisma generate
pnpm prisma migrate dev # if you change schema
pnpm prisma db seed # optional: seed roles, users, chainages, example alarms
pnpm devHosted on Azure App Service with:
- CI/CD via GitHub Actions
- Azure PostgreSQL
- Azure Blob Storage
Core alarm & investigation workflow
Realtime updates, escalations, notifications
PIDS API ingestion, GIS analytics, patrol tracking
Proprietary — Internal Use Only. See LICENSE for full terms.
Internal operations & engineering teams.