Skip to content

DEFRA/pafs-backend-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

415 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PAFS Backend API

License Node.js PostgreSQL Liquibase CDP Quality Gate Status Security Rating Maintainability Rating Coverage

Backend API for the Project Application and Funding Service (PAFS) - RESTful APIs for managing flood and coastal erosion risk management projects.

Overview

Purpose: RESTful API for user authentication, authorization, and data management

Tech Stack:

  • Node.js 22 + Hapi.js 21
  • PostgreSQL 16 (Aurora Serverless V2) + Prisma ORM
  • Liquibase 4.25 for schema migrations
  • JWT authentication + bcrypt
  • Vitest + Docker + CDP deployment

Key Features:

  • User authentication and authorization
  • Account provisioning workflow
  • Role-based access control
  • Database schema versioning
  • Health check endpoints

Table of Contents

Requirements

Node.js: >= 22
npm: >= 11
PostgreSQL: >= 16
Liquibase: 4.25 (via Docker or standalone)

Install Node.js:

# Using nvm (recommended)
nvm install 22
nvm use 22

Install PostgreSQL:

# Mac
brew install postgresql@16

# Linux
sudo apt-get install postgresql-16

# Windows: Download from postgresql.org

Quick Start

# Clone repository
git clone https://github.com/DEFRA/pafs-backend-api.git
cd pafs-backend-api

# Install dependencies
nvm use  # Use Node version from .nvmrc
npm install

# Setup database
psql -U postgres
CREATE DATABASE pafs_backend_local;
CREATE USER pafs_user WITH PASSWORD 'pafs_password';
GRANT ALL PRIVILEGES ON DATABASE pafs_backend_local TO pafs_user;
\q

# Configure Liquibase
cp liquibase.properties.template liquibase.properties
# Edit liquibase.properties with your credentials

# Run migrations
npm run db:migrate

# Start development server
npm run dev

Application runs at http://localhost:3001

VS Code Setup

Recommended for debugging and development.

Create .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Dev Server",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["run", "dev"],
      "skipFiles": ["<node_internals>/**"],
      "console": "integratedTerminal",
      "env": {
        "NODE_ENV": "development",
        "PORT": "3001"
      }
    }
  ]
}

Run: Press F5 or use Run and Debug panel

Prisma Schema

Location: prisma/schema.prisma
Purpose: Type-safe database access with auto-generated client

Workflow

  1. Pull schema from database (via VS Code) → Generates schema.prisma from existing database
  2. Generate Prisma Client (via npm) → Creates type-safe client for database access

Pull Schema from Database (VS Code)

Use VS Code launch configuration to pull schema:

Add to .vscode/launch.json:

{
  "type": "node",
  "request": "launch",
  "name": "PAFS Backend API - Prisma Pull",
  "skipFiles": ["<node_internals>/**"],
  "runtimeExecutable": "npm",
  "runtimeArgs": ["run", "prisma:db:pull"],
  "console": "integratedTerminal",
  "env": {
    "DB_HOST": "127.0.0.1",
    "DB_PORT": "5432",
    "DB_DATABASE": "pafs_backend_api",
    "DB_USERNAME": "postgres",
    "DB_PASSWORD": "pgadmin",
    "DB_USE_IAM_AUTHENTICATION": "false"
  }
}

Run: Press F5 and select "PAFS Backend API - Prisma Pull"

This pulls the database schema and generates/updates prisma/schema.prisma file.

Generate Prisma Client (npm)

After pulling schema, generate the Prisma Client:

npm run prisma:generate

This generates the type-safe Prisma Client based on your schema.

Note: This runs automatically on npm install (postinstall hook)

Important:

  • Run prisma:db:pull via VS Code to generate schema from database
  • Run prisma:generate via npm to create Prisma Client
  • Prisma works alongside Liquibase (Liquibase manages migrations, Prisma provides type-safe access)

Database Migrations

Tool: Liquibase 4.25
Location: changelog/ directory
Format: XML changesets

Setup:

# Copy template
cp liquibase.properties.template liquibase.properties

# Edit liquibase.properties with your database credentials

Run Migrations:

Option 1: Using Docker

# Interactive shell (recommended for multiple commands)
docker run -it --rm --network host \
  -v "$(pwd):/liquibase/workspace" \
  -w /liquibase/workspace \
  liquibase/liquibase:4.25 sh

# Then inside container:
liquibase --defaults-file=liquibase.properties validate
liquibase --defaults-file=liquibase.properties status
liquibase --defaults-file=liquibase.properties update
exit

# Or single command:
docker run --rm --network host \
  -v "$(pwd):/liquibase/workspace" \
  -w /liquibase/workspace \
  liquibase/liquibase:4.25 \
  --defaults-file=liquibase.properties update

Option 2: Using Podman

# Interactive shell
podman run -it --rm --network host \
  -v "$(pwd):/liquibase/workspace:Z" \
  -w /liquibase/workspace \
  liquibase/liquibase:4.25 sh

# Then inside container:
liquibase --defaults-file=liquibase.properties validate
liquibase --defaults-file=liquibase.properties status
liquibase --defaults-file=liquibase.properties update
exit

# Or single command:
podman run --rm --network host \
  -v "$(pwd):/liquibase/workspace:Z" \
  -w /liquibase/workspace \
  liquibase/liquibase:4.25 \
  --defaults-file=liquibase.properties update

Option 3: Using standalone Liquibase

liquibase --defaults-file=liquibase.properties update

Important Notes:

  • For Docker/Podman on Windows/Mac: Use host.docker.internal in liquibase.properties instead of localhost
  • For Podman: The :Z flag is required for SELinux contexts
  • For standalone Liquibase: Download from liquibase.org

Development

Run Development Server:

npm run dev  # Nodemon with hot reload

Run Tests:

npm test              # Run tests with coverage
npm run test:watch    # Watch mode

Available Scripts:

npm run dev           # Development server
npm start             # Production server
npm test              # Run tests
npm run lint          # Lint code
npm run format        # Format code

Schema Changes

Create New Changeset:

  1. Add XML file to changelog/
  2. Follow naming: {version}-{sequence}-{description}.xml
  3. Test locally with npm run db:migrate
  4. Create PR (automatic validation runs)
  5. After merge, publish via GitHub Actions

Automatic Validation:

  • PR checks validate changelog syntax
  • Runs migration on test database
  • Ensures no broken migrations

Docker

Build:

# Development
docker build --target development -t pafs-backend-api:dev .

# Production
docker build -t pafs-backend-api .

Run:

docker run -p 3001:3001 pafs-backend-api

Environment Variables

Variable Description Default
NODE_ENV Environment development
PORT Server port 3001
LOG_LEVEL Log level info
DATABASE_URL PostgreSQL connection -
JWT_SECRET JWT signing secret -

CDP Environments: Manage secrets via CDP Portal

Deployment

Automated (GitHub Actions):

  1. Push to main → Build & test
  2. Tests pass → Docker image built
  3. Image published to CDP
  4. Deploy via CDP Portal

Manual:

  • CDP Portal → Select service → Choose environment → Deploy

Related Links

Licence

THIS INFORMATION IS LICENSED UNDER THE CONDITIONS OF THE OPEN GOVERNMENT LICENCE found at:

http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3

The following attribution statement MUST be cited in your products and applications when using this information.

Contains public sector information licensed under the Open Government license v3

About

Git repository for service pafs-backend-api

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors