tpt-jury-portal-nz
GoDigital jury summons management portal for New Zealand courts. Citizens claim summonses and respond via RealMe verified identity (SAML 2.0). Built with Go, Next.js, and PostgreSQL. Includes eligibility assessment under the NZ Jury Act 1981, panel management, and excusal workflows.
Languages
Secure Jury Duty Portal (app-jury-portal)
A digital jury summons management system for New Zealand courts, integrating RealMe for identity verification and eligibility assessment.
Features
- Digital Summons Dispatch — Court staff issue summonses with secure tokens for juror claim via RealMe.
- RealMe Login + Verified Identity — Citizens claim their summons using RealMe authentication (Verified level required).
- Eligibility Questionnaire — Self-assessment based on NZ Jury Act 1981 criteria (citizenship, residency, convictions).
- Summons Response — Jurors can respond with "attend", "excuse", or "defer".
- Excusal Management — Jurors submit excusal requests; court staff review and approve/deny.
- Panel Management — Court staff create jury panels, assign jurors, and track panel status.
- Court Staff Dashboard — View all summons, manage panels, review excusals.
Tech Stack
- Backend: Go 1.23, chi router, pgx (PostgreSQL)
- Frontend: Next.js 14, React 18, TypeScript
- Auth: RealMe SAML 2.0 (Verified identity)
- Infrastructure: Docker, docker-compose
Architecture
tpt-jury-portal-nz/
├── cmd/server/main.go # HTTP entrypoint
├── internal/
│ ├── models/jury.go # Domain types (Summons, Questionnaire, Panel, Excusal)
│ ├── repository/jury_repo.go # PostgreSQL data access
│ ├── services/
│ │ ├── summons.go # Summons dispatch and response logic
│ │ ├── eligibility.go # Eligibility checks (NZ Jury Act stubs)
│ │ └── panel.go # Panel management and excusal review
│ └── handlers/
│ ├── juror.go # Juror-facing endpoints
│ ├── court.go # Court staff endpoints
│ └── auth.go # RealMe authentication
├── migrations/001_init.sql # Database schema
├── packages/
│ ├── realme-go/ # SAML 2.0 RealMe Go library
│ └── ui-shared/ # Shared React component library
├── web/ # Next.js frontend
├── Dockerfile # Backend container
├── docker-compose.yml # Full stack orchestration
└── README.md
Getting Started
Prerequisites
- Go 1.23+
- PostgreSQL 16+
- Node.js 20+ (for frontend)
- RealMe certificates (for production; mock IdP available for dev)
Configuration
Environment variables (or .env file):
| Variable | Default | Description |
|----------|---------|-------------|
| LISTEN_ADDR | :8080 | Server listen address |
| DATABASE_URL | postgres://tptnz:tptnz_dev@localhost:5432/tptnz?sslmode=disable | PostgreSQL connection string |
| REALME_ENVIRONMENT | mts | RealMe environment (mts, prod) |
| REALME_CERT_FILE | certs/sp.crt | SAML SP certificate path |
| REALME_KEY_FILE | certs/sp.key | SAML SP private key path |
| REALME_ENTITY_ID | http://localhost:8080/auth/metadata | SP Entity ID |
| REALME_ACS_URL | http://localhost:8080/auth/callback | Assertion Consumer Service URL |
Running Locally
1. Database
createdb tptnz
psql -d tptnz -f migrations/001_init.sql
2. Backend
go mod download
go run ./cmd/server
3. Frontend
cd web
pnpm install
pnpm dev
4. Docker
docker-compose up --build
The API will be available at http://localhost:8082 and the web UI at http://localhost:3008.
API Endpoints
Public
GET /summons/lookup/{token}— Look up a summons by secure token
Authentication (RealMe)
GET /auth/login— Initiate RealMe loginGET /auth/callback— RealMe SAML callbackGET /auth/logout— LogoutGET /auth/metadata— SAML metadata XMLGET /auth/status— Check auth status
Juror (requires RealMe Verified)
POST /summons/claim— Claim a summons using tokenGET /summons/my— List summons for authenticated userPOST /summons/{id}/respond— Respond to summons (attend/excuse/defer)POST /summons/{id}/questionnaire— Submit eligibility questionnaireGET /summons/{id}/questionnaire— Get questionnaire status
Court Staff (requires RealMe Verified)
GET /court/summons— List all summonsPOST /court/summons— Dispatch a new summonsGET /court/panels— List all panelsPOST /court/panels— Create a new panelGET /court/panels/{id}— Get panel with membersPOST /court/panels/members— Add juror to panelGET /court/excusals— List pending excusalsPOST /court/excusals/{id}/review— Review excusal request
Eligibility Criteria (NZ Jury Act 1981)
The portal implements stub checks for:
- Must be a New Zealand citizen or resident (s6)
- No disqualifying criminal conviction (imprisonment for 3+ years) (s7)
- Additional manual review for minor convictions
RealMe Registration
To use this app with real RealMe identities (ITE or Production environments), you must register a Service Provider with the Department of Internal Affairs.
MTS (Messaging Test Site) — Development
-
Generate a self-signed certificate and key:
mkdir -p certs openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout certs/sp.key -out certs/sp.crt \ -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost" -
In MTS, no formal registration is needed — use the mock IdP in
packages/realme-go/testenv/for local development. -
Start the mock IdP:
cd packages/realme-go go run ./testenv/ -addr :8081 -
Configure the app to use the mock IdP:
REALME_IDP_METADATA_URL=http://localhost:8081/metadata
ITE (Integration Test Environment) — Pre-Production
- Log in to the RealMe Developer Portal and register a new service.
- Submit your SP metadata XML (available at
GET /auth/metadata) to DIA. - DIA will provide the ITE IdP metadata URL.
- Generate a proper certificate (not self-signed) using the naming convention:
ite.{service-name}.{org-domain}.nz - Configure environment variables:
REALME_ENVIRONMENT=ite REALME_CERT_FILE=certs/ite.sp.crt REALME_KEY_FILE=certs/ite.sp.key REALME_IDP_METADATA_URL=<DIA-provided-ITE-url>
Production
Follow the ITE steps above, substituting:
REALME_ENVIRONMENT=production
REALME_CERT_FILE=certs/prod.sp.crt
REALME_KEY_FILE=certs/prod.sp.key
REALME_IDP_METADATA_URL=<DIA-provided-prod-url>
Production use requires Ministry of Justice approval in addition to DIA registration.
Testing
go test ./...