GradFix
GradFix is a multilingual civic issue reporting platform built for Serbian municipalities. Citizens can report problems from a phone with a photo and map location, follow progress in real time, and see issues on a public map. Municipal staff get a tenant-aware admin workflow for triage, assignment, work orders, notifications, and resolution tracking.
The project is being developed as part of the Studio Present AI-Driven Development internship and is structured around a live demo loop:
citizen report -> public map -> admin queue -> accept/assign -> status update -> work-order PDF -> citizen notification
What It Does
- Mobile-first report submission with photo upload, geolocation, category selection, and step-by-step guidance
- Public cross-tenant issue feed with map view, filtering, and heatmap mode
- Installable PWA with offline support and install guidance
- Multi-tenant authentication with JWT access tokens and refresh cookies
- Role-based admin workflow for reviewers, conductors, tenant admins, and super admins
- Admin queue with filtering, search, pagination, and CSV export
- Work-order generation with PDF jobs and status-driven transitions
- Real-time updates through Socket.IO
- Push notifications and in-app notifications
- Public stats dashboards and resident leaderboard/gamification
- AI-assisted photo analysis for category/title/description suggestions
- Shared Zod schemas and enums across frontend and backend
Monorepo Structure
apps/
api/ Express API, Prisma, Redis/BullMQ worker, PDF/email/notification jobs
web/ Next.js 15 PWA for citizens, public map, and admin interface
packages/
shared/ Shared Zod schemas, enums, and types
config/ Shared TypeScript and ESLint config
Stack
pnpmworkspaces + Turborepoapps/web: Next.js 15 App Router, React 19, Tailwind CSS v4, shadcn/ui, TanStack Query, Leaflet, next-intl, Serwist PWA toolingapps/api: Express, Prisma, PostgreSQL, Redis, BullMQ, Socket.IO, Zod, Pino- Shared contract layer in
@gradfix/shared - Optional AI photo analysis through Gemini
Local Development
Prerequisites
- Node.js
20+ pnpm9+(packageManageris pinned topnpm@11.7.0)- Docker Desktop or local PostgreSQL + Redis
1. Install dependencies
pnpm install
2. Start infrastructure
If you use Docker for local services:
pnpm docker
This starts PostgreSQL and Redis from docker compose.
3. Configure environment
Create the API env file from the example:
cp apps/api/.env.example apps/api/.env
The default local setup expects:
- PostgreSQL on
localhost:5432 - Redis on
localhost:6379 - Uploaded files stored in
apps/api/uploads/when running locally
4. Prepare the database
pnpm db:generate
pnpm db:migrate
pnpm db:seed
Optional:
pnpm db:seed:superadmin
5. Run the app
For normal development:
pnpm dev
Useful focused commands:
pnpm dev:web
pnpm dev:api
For a production-style local run:
pnpm start:local
That script builds the web app, then starts the API, worker, Prisma Studio, and the built Next.js app together.
Default Local URLs
- Web app:
http://localhost:3000 - API:
http://localhost:4000 - OpenAPI JSON:
http://localhost:4000/api/docs.json - Swagger UI:
http://localhost:4000/api/docs
Key Product Flows
Citizen
- Register or log in
- Create a report with photos, map location, category, and description
- Get optional AI suggestions from the uploaded image
- Track report status, comments, badges, and notifications
- Browse the public map, heatmap, dashboard stats, and leaderboard
Municipal Staff
- Review incoming reports in the admin queue
- Filter by status, priority, category, assignment state, and search query
- Transition report statuses through the operational workflow
- Assign responsible entities
- Generate and manage work orders
- Export queue data to CSV
- Monitor public/admin statistics
Architecture Notes
apps/webandapps/apishare schemas through@gradfix/shared; contracts are defined once and reused- Tenant scoping is enforced through
X-Tenant-Slugand auth context - Public report endpoints are intentionally cross-tenant so the national/public map can aggregate data
- Background work is handled through BullMQ workers for image processing, geocoding, notifications, badges, deduplication, email, and work-order PDFs
- The API serves uploaded files from
/uploads - Storage supports local files and S3-compatible backends
Auth Contract
The API auth flow returns:
{
"accessToken": "...",
"refreshToken": "..."
}
- Send
Authorization: Bearer <token> - Send
X-Tenant-Slug: <slug>for tenant-scoped requests - Refresh tokens via
POST /api/v1/auth/refresh
Current Focus
GradFix is aimed at an advanced demo that proves a full civic operations loop rather than a static prototype. The implemented codebase already includes the citizen reporting flow, public map/stat surfaces, admin queueing, work orders, PWA setup, real-time updates, and shared contract infrastructure.