Farm Cooperative Management SaaS for Emilia-Romagna
A comprehensive Next.js platform for Italian agricultural cooperatives — managing fields, compliance, traceability, IoT sensors, marketplace, governance, and 40+ additional modules from carbon tracking to AI advisory.
AgriRomagna is a multi-tenant SaaS platform designed for agricultural cooperatives in Italy's Emilia-Romagna region. It provides a unified dashboard covering the full lifecycle of cooperative farm management — from field planning and IoT sensor monitoring to EU compliance, supply-chain traceability, and carbon accounting.
| Domain | Features |
|---|---|
| Core Farm | Field management, crop planning, harvest declarations, yield prediction |
| Compliance | EU regulatory tracking, compliance chain, audit packages, document management |
| Supply Chain | Lot traceability, digital product passports, supply-chain tracking |
| IoT & Sensing | Sensor device management, real-time readings, NDVI satellite data |
| Financial | Cost/revenue tracking, financial KPIs, insurance policies |
| Sustainability | Carbon accounting, ESG indicators, water management |
| Intelligence | AI advisor, anomaly detection, pest warnings, knowledge graph |
| Cooperative | Governance (proposals & voting), communication hub, workforce scheduling |
| Marketplace | Direct sales, order management, benchmarking |
| Infrastructure | Federation, data interoperability (ISOBUS, INSPIRE), analytics telemetry |
- Framework: Next.js 16 (App Router)
- Language: TypeScript 5
- Database: SQLite via Prisma 7 + better-sqlite3
- Auth: JWT (access + refresh tokens) + bcrypt password hashing
- Validation: Zod 4
- UI: React 19, Tailwind CSS 4, Lucide icons
- Testing: Vitest 4 (67 unit tests across 8 test suites)
- Deployment: Docker multi-stage build + Docker Compose
- Node.js ≥ 20
- npm ≥ 10
# Clone and install
git clone <repo-url> && cd agri-romagna
npm install
# Generate Prisma client + run migrations + seed demo data
npm run db:generate
npm run db:migrate
npm run db:seed
# Start development server
npm run devOpen http://localhost:3000 to access the platform.
The seed script creates demo users for each role. Check prisma/seed.ts for exact credentials.
# Build and run with Docker Compose
docker compose up --build
# Or build the image directly
docker build -t agri-romagna .
docker run -p 3000:3000 agri-romagnaagri-romagna/
├── prisma/
│ ├── schema.prisma # 36 data models
│ ├── migrations/ # SQLite migrations
│ └── seed.ts # Demo data seeder
├── src/
│ ├── app/
│ │ ├── api/ # ~50 API route handlers (32 domains)
│ │ ├── dashboard/ # Protected dashboard pages
│ │ ├── login/ # Auth pages
│ │ ├── onboarding/ # Cooperative onboarding flow
│ │ └── traceability/ # Public traceability viewer
│ ├── components/ # React components (navbar, dashboard, etc.)
│ ├── lib/ # Core business logic (45+ modules)
│ │ ├── auth-service.ts # JWT auth + bcrypt
│ │ ├── rbac-middleware.ts # 7 roles, 70+ permissions
│ │ ├── data-layer.ts # Prisma query layer (36 model accessors)
│ │ ├── event-bus.ts # Cross-module event system
│ │ ├── api-errors.ts # RFC 7807 error responses
│ │ ├── telemetry.ts # Request/feature telemetry
│ │ └── validators/ # Zod schemas
│ ├── generated/ # Prisma generated client
│ └── middleware.ts # Next.js edge auth middleware
├── tests/
│ └── lib/ # 8 test suites, 67 test cases
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Single-service deployment
└── vitest.config.ts # Test configuration
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run test |
Run all tests (Vitest) |
npm run test:watch |
Run tests in watch mode |
npm run test:coverage |
Run tests with coverage |
npm run db:generate |
Generate Prisma client |
npm run db:migrate |
Run database migrations |
npm run db:seed |
Seed demo data |
npm run db:reset |
Reset database (drop + migrate + seed) |
See docs/ARCHITECTURE.md for detailed architecture diagrams and data flow documentation.
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Next.js │────▶│ API Routes │────▶│ Prisma │
│ Frontend │ │ (32 domains)│ │ (SQLite) │
└─────────────┘ └──────┬───────┘ └─────────────┘
│
┌──────┴───────┐
│ Middleware │
│ JWT + RBAC │
└──────────────┘
- Edge middleware checks token presence on every request
- Public paths (
/,/login,/api/auth,/api/health,/traceability) skip auth - API routes without token → 401 JSON response
- Dashboard routes without token → redirect to
/login - Route handlers validate JWT and check RBAC permissions
- 36 Prisma models covering users, cooperatives, farms, fields, compliance, IoT, financial, marketplace, governance, and more
- Dual data layer: Prisma-backed
data-layer.tsfor persistent data +InMemoryStore<T>for ephemeral/demo data - Cross-module event bus connecting 15 event flows between modules
See docs/API.md for the full API reference with all 50 endpoints.
# Run all 67 tests
npm run test
# Watch mode
npm run test:watch
# With coverage
npm run test:coverage| Suite | File | Coverage |
|---|---|---|
| Auth Service | tests/lib/auth-service.test.ts |
JWT, bcrypt, login, register, token refresh |
| RBAC Middleware | tests/lib/rbac-middleware.test.ts |
Permissions, role hierarchy, route gating |
| Event Bus | tests/lib/event-bus.test.ts |
Pub/sub, circuit breaker, event flows |
| Telemetry | tests/lib/telemetry.test.ts |
Metrics, percentiles, feature heatmap |
| In-Memory DB | tests/lib/db.test.ts |
CRUD operations, filtering |
| Validators | tests/lib/validators.test.ts |
Zod schema validation |
| Utils | tests/lib/utils.test.ts |
Class name merging |
| Moonshot OS | tests/lib/moonshot-operating-system.test.ts |
Intelligence fabric, GDD, NDVI |
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
file:./dev.db |
SQLite database path |
JWT_SECRET |
agri-romagna-dev-secret-... |
JWT signing secret (change in production) |
NODE_ENV |
development |
Environment (development, production, test) |
PORT |
3000 |
Server port |
Source code is publicly available. No open-source license has been selected yet.