Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GPP Monorepo

A unified monorepo for local development of the Generic Publication Platform (GPP) services.

Overview

This monorepo consolidates all GPP microservices for easier local development and testing:

Service Description Tech Stack Port
gpp-app (ODPC) Publication Composer - UI for creating publications .NET 8 + Vue 3 62230
publicatiebank (ODRC) Publication Registry - stores publications Django + Celery 8002
woo-hoo LLM Metadata Extraction - AI-powered document analysis FastAPI + Python 8003
openzaak Document Management System Django 8001
nginx Unified reverse proxy nginx 8080

Quick Start

Prerequisites

  • Docker & Docker Compose
  • just command runner (brew install just)
  • Node.js 20+ (for frontend development)
  • .NET 8 SDK (for backend development, optional)
  • uv (for Python/woo-hoo development)

First Time Setup

# 1. Create environment file
cp .env.example .env

# 2. Add your OpenRouter API key to .env (required for woo-hoo)
#    Get one at: https://openrouter.ai

# 3. Build and start everything
just quickstart

# Or step by step:
just build
just up

Daily Development

# Start all services
just up

# Start only dependencies (DB, Redis, OpenZaak, Publicatiebank)
just up-deps

# Check health of all services
just health

# View logs
just logs

# Stop everything
just down

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           METADATA GENERATION FLOW                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Browser   │───▢│   gpp-app   │───▢│ publicatiebank│───▢│   OpenZaak   β”‚
β”‚  (Vue.js)   β”‚    β”‚  (.NET 8)   β”‚    β”‚   (Django)    β”‚    β”‚  (DRC API)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                   β”‚                   β”‚                    β”‚
      β”‚                   β”‚                   β”‚                    β”‚
      β”‚                   β–Ό                   β”‚                    β”‚
      β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚                    β”‚
      β”‚            β”‚   woo-hoo   β”‚            β”‚                    β”‚
      β”‚            β”‚  (FastAPI)  β”‚            β”‚                    β”‚
      β”‚            β”‚  LLM/OCR    β”‚            β”‚                    β”‚
      β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚                    β”‚
      β”‚                                       β”‚                    β”‚
      β”‚                                       β–Ό                    β”‚
      β”‚                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
      β”‚                              β”‚ celery worker β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                              β”‚  (strip_pdf)  β”‚
      β”‚                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

STEP BY STEP:
═══════════════════════════════════════════════════════════════════════════════

1. DOCUMENT UPLOAD (User β†’ gpp-app β†’ publicatiebank β†’ OpenZaak)
   Browser POST /api/v2/documenten ──▢ gpp-app ──▢ publicatiebank ──▢ OpenZaak
   
2. STRIP_PDF TASK (celery β†’ OpenZaak)  
   celery downloads from OpenZaak ──▢ strips metadata ──▢ uploads NEW to OpenZaak
   
3. METADATA GENERATION (gpp-app β†’ publicatiebank β†’ OpenZaak β†’ woo-hoo)
   gpp-app GET /api/v2/documenten/{uuid}/download ──▢ publicatiebank 
   publicatiebank proxies to OpenZaak ──▢ returns PDF
   gpp-app POST /api/v1/metadata/generate-from-file ──▢ woo-hoo
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚   Browser/User   β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                             β”‚
                                             β–Ό
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚  nginx (8080)    β”‚
                                    β”‚  Reverse Proxy   β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                             β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚                              β”‚                              β”‚
              β–Ό                              β–Ό                              β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  gpp-app (ODPC)  β”‚          β”‚  publicatiebank  β”‚          β”‚    woo-hoo       β”‚
    β”‚  .NET + Vue      │◄────────►│  (ODRC) Django   β”‚          β”‚    FastAPI       β”‚
    β”‚  Port 62230      β”‚          β”‚  Port 8002       β”‚          β”‚    Port 8003     β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                             β”‚                              β”‚
             β”‚                             β”‚                              β”‚
             β”‚                             β–Ό                              β”‚
             β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
             β”‚                    β”‚    OpenZaak      β”‚                    β”‚
             β”‚                    β”‚    Port 8001     β”‚                    β”‚
             β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
             β”‚                             β”‚                              β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β–Ό                         β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   PostgreSQL     β”‚      β”‚      Redis       β”‚
                    β”‚   Port 5432      β”‚      β”‚    Port 6379     β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Access URLs

Service URL Credentials
Main Application http://localhost:8080 Auto-login (dev mode)
GPP-App Direct http://localhost:62230 Auto-login (dev mode)
Publicatiebank Admin http://localhost:8002/admin admin / admin
OpenZaak Admin http://localhost:8001/admin admin / admin
woo-hoo API Docs http://localhost:8003/docs -
woo-hoo Health http://localhost:8003/health -

Development Modes

Full Docker Stack (Recommended for Testing)

just up

All services run in Docker containers. Best for integration testing and simulating production.

Hybrid Development (Frontend Focus)

# Start dependencies in Docker
just up-deps

# Run Vue dev server with hot reload (in a new terminal)
just dev-frontend

Access the Vue app at http://localhost:5173 - it proxies API calls to the Docker backend.

Hybrid Development (woo-hoo Focus)

# Start dependencies
just up-deps

# Run woo-hoo locally with hot reload
just dev-woo-hoo

Full Local Development

# Start only infrastructure
just up-infra

# Run each service locally (in separate terminals):
just dev-backend    # .NET backend
just dev-frontend   # Vue frontend
just dev-woo-hoo    # woo-hoo

OIDC / Authentication

In production, GPP uses OIDC (OpenID Connect) for authentication, which provides:

  • User identity and roles from the identity provider
  • User groups (OrganisationUnits) for authorization

For local development, OIDC is bypassed:

  • The OIDC_AUTHORITY environment variable is intentionally NOT set
  • GPP-app automatically logs in as a local developer with admin rights
  • Test user groups are seeded via fixtures

If you need to test OIDC integration, you can configure it in .env:

OIDC_AUTHORITY=https://your-idp.example.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret

woo-hoo (LLM Metadata Extraction)

woo-hoo uses LLMs to extract metadata from Dutch government documents. It requires an OpenRouter API key.

Setup

  1. Get an API key from OpenRouter
  2. Add it to your .env:
    OPENROUTER_API_KEY=sk-or-v1-...

Supported Models

By default, woo-hoo uses EU-based Mistral models for data sovereignty:

  • mistralai/mistral-large-2512 (default)
  • mistralai/mistral-medium-3.1
  • mistralai/mistral-small-3.2-24b-instruct-2506

Change the model in .env:

WOO_HOO_MODEL=mistralai/mistral-large-2512

Testing woo-hoo

# Check health
curl http://localhost:8003/health

# View API docs
open http://localhost:8003/docs

# List available models
curl http://localhost:8003/api/v1/metadata/models

# Generate metadata from a file
curl -X POST http://localhost:8003/api/v1/metadata/generate-from-file \
  -F "file=@document.pdf"

Justfile Commands

Run just or just --list to see all available commands:

# Main commands
just up              # Start all services
just down            # Stop all services
just restart         # Restart all services
just logs            # View logs

# Selective startup
just up-infra        # Start only postgres & redis
just up-deps         # Start dependencies (+ openzaak, publicatiebank)
just up-woo-hoo      # Start woo-hoo only

# Development
just dev-frontend    # Vue dev server (hot reload)
just dev-backend     # .NET backend (local)
just dev-woo-hoo     # woo-hoo (hot reload)

# Testing
just test            # Run all tests
just test-gpp-app    # Run gpp-app tests
just test-woo-hoo    # Run woo-hoo tests

# Code quality
just lint            # Lint all code
just format          # Format all code

# Database
just db-shell        # Open psql
just db-odpc         # Connect to ODPC database
just db-publicatiebank # Connect to publicatiebank database

# Utilities
just health          # Check service health
just ps              # Show running containers
just clean           # Clean up Docker resources

Project Structure

gppmono/
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ gpp-app/           # Publication Composer (.NET + Vue)
β”‚   β”‚   β”œβ”€β”€ ODPC.Server/   # .NET backend
β”‚   β”‚   β”œβ”€β”€ ODPC.Test/     # Backend tests
β”‚   β”‚   └── odpc.client/   # Vue frontend
β”‚   β”œβ”€β”€ publicatiebank/    # Publication Registry (Django)
β”‚   β”‚   └── src/woo_publications/
β”‚   └── woo-hoo/           # LLM Metadata Service (FastAPI)
β”‚       └── src/woo_hoo/
β”œβ”€β”€ docker/
β”‚   β”œβ”€β”€ nginx/             # Reverse proxy config
β”‚   β”œβ”€β”€ postgres/init/     # Database initialization
β”‚   └── fixtures/          # Seed data for local dev
β”œβ”€β”€ docker-compose.yml     # Main compose file
β”œβ”€β”€ docker-compose.override.yml  # Local dev overrides
β”œβ”€β”€ justfile               # Command runner recipes
β”œβ”€β”€ .env.example           # Environment template
β”œβ”€β”€ CLAUDE.md              # AI assistant instructions
└── README.md              # This file

Troubleshooting

Services won't start

# Check what's running
just ps

# View logs for specific service
just logs gpp-app
just logs publicatiebank

# Rebuild images
just build

# Nuclear option: clean slate
just down-v
just up

Database issues

# Reset databases (destroys all data!)
just down-v
just up

# Check database health
just db-shell
\l  # List databases
\c ODPC  # Connect to ODPC
\dt  # List tables

woo-hoo not generating metadata

  1. Check if OPENROUTER_API_KEY is set in .env
  2. Check woo-hoo logs: just logs woo-hoo
  3. Test health: curl http://localhost:8003/health

Port conflicts

If ports are already in use, check for running containers:

docker ps -a
# Kill conflicting containers or change ports in docker-compose.override.yml

Contributing

  1. Create a feature branch
  2. Make your changes
  3. Run tests: just test
  4. Run linting: just lint
  5. Submit a pull request

License

See individual service directories for license information.

About

A monorepo for all things gpp

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages