Skip to content

Vishal27alpha/fueleu-maritime-compliance

Repository files navigation

FuelEU Compliance Platform

Overview

This repository contains a minimal full-stack FuelEU Maritime compliance platform built as a technical assignment.

It includes:

  • backend/

    • Node.js + TypeScript
    • Express HTTP API
    • PostgreSQL integration
    • FuelEU route, comparison, compliance balance, banking, and pooling logic
  • frontend/

    • React + TypeScript + Vite
    • TailwindCSS UI
    • Dashboard with four tabs:
      • Routes
      • Compare
      • Banking
      • Pooling

The project focuses on clean domain modeling, strict TypeScript, and hexagonal architecture separation between core business logic and framework-specific adapters.

Architecture Summary

Both frontend and backend follow a hexagonal structure.

Backend

backend/src/
├── core/
│   ├── domain/         # Domain models and core rules
│   ├── application/    # Use cases
│   └── ports/          # Interfaces / abstractions
├── adapters/
│   ├── inbound/http/   # Express controllers
│   └── outbound/postgres/ # PostgreSQL repository implementations
├── infrastructure/
│   ├── config/         # Environment config
│   ├── db/             # Database connection
│   └── server/         # App bootstrap
└── shared/             # Shared backend utilities

Frontend

frontend/src/
├── core/
│   ├── domain/         # Shared frontend types/domain models
│   ├── application/    # Frontend service layer
│   └── ports/          # API port abstractions
├── adapters/
│   ├── ui/             # React UI components and tabs
│   └── infrastructure/ # HTTP API adapter
└── shared/             # Shared components, constants, and utilities

Architecture Intent

  • core does not depend on Express, React, or PostgreSQL
  • ports define the contract used by the application layer
  • adapters implement those contracts
  • infrastructure wires everything together

This keeps business logic isolated from frameworks and makes the code easier to test and evolve.

Features Implemented

Backend

  • GET /routes
  • POST /routes/:id/baseline
  • GET /routes/comparison
  • GET /compliance/cb?shipId&year
  • GET /compliance/adjusted-cb?shipId&year
  • GET /banking/records?shipId&year
  • POST /banking/bank
  • POST /banking/apply
  • POST /pools

Frontend

  • Routes tab with filters and baseline selection
  • Compare tab with comparison table and chart-like visualization
  • Banking tab with compliance balance, bank/apply actions, and KPI display
  • Pooling tab with adjusted CB selection, validation, and pool creation
  • Dark mode toggle
  • Hero background image

Setup & Run Instructions

Prerequisites

  • Node.js 20+
  • npm 10+
  • PostgreSQL 14+ recommended

1. Install dependencies

From the repository root:

npm install

2. Configure backend environment

Copy the backend example env file:

cp backend/.env.example backend/.env

Default values expected by the backend:

PORT=3001
DB_HOST=localhost
DB_PORT=5432
DB_NAME=fueleu
DB_USER=postgres
DB_PASSWORD=postgres

You can also use DATABASE_URL if preferred.

3. Start PostgreSQL

Create a local database matching your env values, for example:

createdb fueleu

On startup, the backend creates required tables if they do not exist and seeds the initial route dataset.

4. Run the backend

npm run dev:backend

Backend runs on:

http://localhost:3001

5. Run the frontend

In a separate terminal:

npm run dev:frontend

Frontend runs on:

http://localhost:5173

The Vite dev server proxies API requests to the backend on port 3001.

How To Execute Tests

Backend tests

Run unit and integration tests:

npm run test --workspace backend

Backend build verification

npm run build --workspace backend

Frontend build verification

npm run build --workspace frontend

Sample Requests / Responses

1. Get routes

Request:

curl "http://localhost:3001/routes"

Example response:

[
  {
    "id": "1",
    "routeId": "R001",
    "shipId": "SHIP-001",
    "vesselType": "Container",
    "fuelType": "HFO",
    "year": 2024,
    "ghgIntensity": 91,
    "fuelConsumption": 5000,
    "distance": 12000,
    "totalEmissions": 4500,
    "isBaseline": true
  }
]

2. Set baseline

Request:

curl -X POST "http://localhost:3001/routes/R002/baseline"

Example response:

{
  "id": "2",
  "routeId": "R002",
  "shipId": "SHIP-002",
  "vesselType": "BulkCarrier",
  "fuelType": "LNG",
  "year": 2024,
  "ghgIntensity": 88,
  "fuelConsumption": 4800,
  "distance": 11500,
  "totalEmissions": 4200,
  "isBaseline": true
}

3. Compute compliance balance

Request:

curl "http://localhost:3001/compliance/cb?shipId=SHIP-002&year=2024"

Example response:

{
  "shipId": "SHIP-002",
  "year": 2024,
  "actualIntensity": 88,
  "targetIntensity": 89.3368,
  "energyInScopeMj": 196800000,
  "cbGco2eq": 263106240
}

4. Bank surplus

Request:

curl -X POST "http://localhost:3001/banking/bank" \
  -H "Content-Type: application/json" \
  -d '{"shipId":"SHIP-002","year":2024,"amountGco2eq":1000}'

Example response:

{
  "shipId": "SHIP-002",
  "year": 2024,
  "cbBefore": 263106240,
  "applied": 0,
  "cbAfter": 263106240,
  "availableBanked": 1000
}

5. Create pool

Request:

curl -X POST "http://localhost:3001/pools" \
  -H "Content-Type: application/json" \
  -d '{"year":2024,"shipIds":["SHIP-002","SHIP-003"]}'

Example response:

{
  "poolId": "generated-pool-id",
  "year": 2024,
  "poolSum": 0,
  "valid": true,
  "members": [
    {
      "shipId": "SHIP-002",
      "year": 2024,
      "cbBefore": 263106240,
      "cbAfter": 0
    },
    {
      "shipId": "SHIP-003",
      "year": 2024,
      "cbBefore": -263106240,
      "cbAfter": 0
    }
  ]
}

Notes

  • Backend tables are initialized automatically at startup.
  • Seed route data is loaded automatically from the backend seed module.
  • Pooling behavior depends on adjusted compliance balance, so banking/application actions can affect pool validity.
  • The frontend currently uses sample operational defaults for banking/pooling flows to keep the dashboard easy to test locally.

About

FuelEU Compliance Platform

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages