Watchtower is an incident monitoring and reporting platform built for civil society organizations. It enables structured reporting of security incidents, real-time alerting, geolocation-based mapping, and AI-assisted analysis; with support for multiple languages and role-based access control.
- Incident reporting with severity classification and geolocation
- Real-time alert subscriptions and notifications (email, SMS)
- Interactive incident maps with heatmap visualization
- Role-based dashboards (Watcher, Admin, Super Admin)
- Anonymous and organization-based reporting
- AI-powered insights and dataset analysis
- Multilingual support (10 languages: English, French, Swahili, Kinyarwanda, Amharic, Luganda, Urdu, and more)
| Layer | Technology |
|---|---|
| Backend | Go 1.25, Clean Architecture, REST |
| Frontend | Next.js 15, TypeScript, tRPC, Tailwind CSS |
| Database | PostgreSQL (Neon) |
| Cache | Redis (Railway) |
| Auth | Better Auth |
| Storage | Cloudflare R2 (S3-compatible) |
| Notifications | AWS SNS, Mailjet |
| AI | Google Generative AI |
| Monitoring | Sentry |
| Deploy | Railway (backend), Vercel (frontend) |
watchtower/
├── backend/ # Go REST API
│ ├── cmd/api/ # Application entrypoint
│ ├── internal/
│ │ ├── domain/ # Entities, repository interfaces, domain errors
│ │ ├── usecase/ # Business logic (alerts, incidents, reports, insights...)
│ │ ├── adapter/ # HTTP handlers, middleware, presenters, repositories
│ │ ├── database/ # Database connection and configuration
│ │ └── server/ # Server setup and route registration
│ ├── docs/ # Auto-generated Swagger API docs
│ └── docker-compose.yml # Local database container
│
└── frontend/ # Next.js application
├── src/
│ ├── app/ # App Router — auth, admin, watcher, and public routes
│ ├── features/ # Feature modules (maps, alerts, reports, insights...)
│ ├── components/ # Shared UI components
│ ├── _trpc/ # tRPC client, routers, and middleware
│ ├── db/ # Drizzle ORM schemas
│ └── lib/ # Auth, AI, AWS, and utility helpers
├── messages/ # i18n locale files (en, fr, sw, rw, am, lg, ur, ...)
└── docs/ # Frontend architecture docs
- Go 1.25+
- Node.js 20+ with pnpm
- Docker (for local database)
A root Makefile wraps the per-service commands below so you don't have to
juggle two directories:
make setup # first-run: checks prerequisites, installs deps, copies env files, starts Postgres
make dev # runs Postgres, the Go backend (hot-reload), and the frontend togetherRun make help-style discovery via make -n <target>, or see the
Makefile for the full list (test, build, lint,
deploy-prod, and per-service variants like test-backend/test-frontend).
cd backend
# Start the database container
make docker-run
# Run with live reload
make watch
# Run tests
make testThe API will be available at http://localhost:8080. Swagger UI is at http://localhost:8080/swagger/.
cd frontend
# Install dependencies
pnpm install
# Start the development server
pnpm devThe frontend will be available at http://localhost:3000.
This project uses Husky to enforce quality checks before every commit. The pre-commit hook runs automatically and covers both services:
- Frontend: ESLint, Jest test suite, Next.js build
- Backend:
go vet,go test ./...,go build
All checks must pass for the commit to proceed.
All work is merged into main via pull requests. staging auto-syncs to
main on every push (rebase + force-push-with-lease, via
sync-staging.yml) so it always
mirrors main with no manual step. production is promoted deliberately:
feature-branch → main (via PR)
main → staging (automatic, on every push to main)
main → production (manual: make deploy-prod)
make deploy-prod rebases production onto main and force-pushes (with
lease) to trigger the platform deploys below. It refuses to run with a dirty
working tree and prompts for confirmation before pushing (set CONFIRM=yes
to skip the prompt in CI/scripted use).
Both services have dedicated environments on their respective platforms:
| Service | Platform | Staging | Production |
|---|---|---|---|
| Backend | Railway | Deploys on push to staging |
Deploys on push to production |
| Frontend | Vercel | Deploys on push to staging |
Deploys on push to production |
The GitHub Actions pipeline runs go test ./... before every backend deploy.
This project is licensed under the MIT License. See LICENSE for details.