Skip to content

About

Scores speed readings against time-versioned rule sets and computes tiered fines. Java 21, Spring Boot 3.5, PostgreSQL, Flyway.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

Repository files navigation

Traffic Engine

Speeding rules change over time, so a reading taken on 30 September must be fined by September's rules even if it reaches the server in October. Traffic Engine picks the rule set that was in force on the reading's date, works out the fine, and stores a citation that names the rule version and explains the amount.

Run

Needs Java 21 (brew install --cask temurin@21) and Docker.

# Start PostgreSQL 17
docker compose up -d

# Run with Maven Wrapper (./mvnw on macOS/Linux, mvnw.cmd on Windows)
./mvnw spring-boot:run

Open http://localhost:8080. Flyway automatically applies database migrations and creates the citations table on first start. docker build -t trafficengine . builds the container image.

Environment Configuration

Defaults match docker-compose.yml. For custom configurations, set environment variables:

Variable Default Purpose
DB_HOST localhost PostgreSQL host
DB_PORT 5432 PostgreSQL port
DB_NAME traffic Database name
DB_USER traffic Database user
DB_PASSWORD traffic Database password
PORT 8080 Application HTTP server port

How it works

  1. The dashboard sends POST /api/readings with a vehicle id, zone, speed and an optional observed time.
  2. CitationService normalises the ids (school zone becomes SCHOOL-ZONE) and uses the current time if none was sent.
  3. RuleCatalog returns the rule set whose start date is the latest one on or before the observed time. Rule sets live in application.yml and start at midnight India time.
  4. SpeedRuleEngine reads the zone's limit (or the default limit) and returns WITHIN_LIMIT, EXEMPT for an emergency vehicle, or VIOLATION with the fine tier for how far over the limit it is.
  5. A violation is saved as a Citation with its rule version and a one-line reason, and is never updated.

Example: 55 km/h in the school zone under the 2026-10 rules is limit 25, +30 over, above the +20 tier, so the fine is ₹3000. The same reading dated 30 September uses 2026-09: limit 30, +25 over, fine ₹2000.

Speeds and fines are BigDecimal in Java and numeric in PostgreSQL, so there is no floating point in the money.

API

Method Path What it does
POST /api/readings Judge one reading: 201 with the citation for a violation, 200 otherwise, 400 for bad input
GET /api/citations?zone= The newest 50 citations, optionally for one zone
GET /api/citations/{id} One citation with its reason, or 404
GET /api/analytics/summary Citation count and fine total per zone
POST /api/readings
{ "vehicleId": "KA 01 AB 1234", "zone": "school zone", "speedKph": 55 }

Errors are Spring ProblemDetail JSON; a 400 lists each rejected field.

Tests & Verification

Unit & Slice Tests (Fast, Offline)

./mvnw test

Runs 22 pure domain unit tests (SpeedRuleEngineTest) and API slice tests (CitationApiTest) in ~3 seconds. No database or Docker required.

Full Test Suite & Migration Verification (Integration)

./mvnw verify

Runs the unit tests plus integration tests (CitationRepositoryIT) against an ephemeral PostgreSQL 17 container using Testcontainers. Automatically verifies Flyway database migrations (V1__create_citations.sql), Hibernate schema validation (ddl-auto: validate), and repository queries.

Build & Package

./mvnw package -DskipTests

Generates an executable Spring Boot fat JAR at target/trafficengine-1.0.0.jar.

About

Scores speed readings against time-versioned rule sets and computes tiered fines. Java 21, Spring Boot 3.5, PostgreSQL, Flyway.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages