The ProcureIQ supplier portfolio, listing suppliers with their category, location, status, risk, rating, on-time delivery and spend

The problem

Buying for a company passes through many hands. Someone needs something, a manager approves it, procurement asks suppliers for prices, picks one, issues an order and checks what arrives. When each of those steps lives in a different inbox or spreadsheet, nobody can say how much money is already committed, which supplier is late, or why one quotation won over another.

The approach

I built one platform for the whole chain. A purchase request is approved, turned into a request for quotation, quoted by suppliers through their own portal, evaluated and awarded, and then becomes a purchase order that the supplier acknowledges or rejects. Goods are received against the order, and the supplier's delivery performance is tracked from what actually arrived.

Around that chain sit the modules a procurement team uses to steer: budgets, contracts, supplier risk, compliance, analytics and strategy. They follow one rule: the system explains and recommends, people decide. Anomalies, policy breaches and data-quality problems are flagged with their reasons instead of being fixed silently, scores are advisory, and snapshots freeze the figures behind a decision so they cannot be rewritten later.

Who uses it

Requesters
Raise a purchase request, guided toward the right buying route, template and preferred supplier.
Buyers
Run RFQs, compare and evaluate quotations, issue purchase orders and follow deliveries and invoices.
Approvers
Decide on requests against approval policies and budgets, with the full decision history kept.
Suppliers
Quote, answer purchase orders and upload compliance documents in a portal that shows only their own work.
Leadership
Follow spend, savings, risk and strategy in cockpits and board-ready governance reviews.

What it does

  • Purchase requests, guided buying with request templates and preferred suppliers, and an approval center that enforces approval policies
  • RFQs sent to invited suppliers, a quotation comparison and a weighted evaluation that recommends a supplier before the award
  • Purchase orders the supplier acknowledges or rejects, deliveries with partial receipts, and invoices matched against the order and the receipt
  • A supplier portal for RFQs, quotations, purchase orders and compliance documents, opened with a one-time invitation
  • Supplier onboarding, scorecards, resilience, risk monitoring, a document vault and ESG sustainability tracking
  • Budgets, contracts and renewals, negotiations, savings tracking and category strategies
  • Policy checks, anomaly detection and data-quality rules that flag problems with their reasons, without rewriting the source records
  • A command center and a control tower that put approvals, deadlines, deliveries and exceptions in one prioritized queue
  • Spend analytics, process mining of cycle times, and date-range reports with CSV exports
  • Strategy, capacity and capital-planning modules where scores are advisory and every decision stays a recorded human approval

Where the engineering is

Choosing a supplier with the reasons on screen

Once the quotations are in, the evaluation page scores each supplier on price, delivery, supplier rating, supplier risk and quality, with the weights printed above the table: 40%, 20%, 15%, 15% and 10%. The highest weighted score is recommended, and the award is recorded as a separate decision, with the name of the person who made it.

Before scoring, a comparison page lines up every quotation against the highest one, so the buyer sees the potential saving, the fastest delivery and any incomplete quotation first.

The evaluation and award page for an RFQ, ranking two suppliers by weighted score, with the recorded award decision below, Open the full-size image (opens in a new tab)
Weighted ranking and the recorded award.

An order the supplier can answer only once

When a purchase order is issued, the supplier finds it in their portal and either acknowledges it or rejects it with a reason. They can answer once, and an order cannot be reopened after goods have been received against it.

Those rules are guarded in the SQL statement itself, not only in the code that calls it, so they stay correct when two people act at the same moment. A dedicated script checks the reopen statement against the real database.

A purchase order in the supplier portal, waiting for the supplier to acknowledge or reject it, with the order lines and the total, Open the full-size image (opens in a new tab)
The supplier's view of an order, waiting for an answer.

Suppliers see only their own work

Suppliers are not internal users. Procurement invites a supplier contact, who activates the account with a one-time token and a password of at least 12 characters, and procurement can revoke that access at any time.

Isolation is enforced in the API and covered by tests: one supplier cannot see another's quotations or orders, and a supplier who loses a bid is never told who won.

The supplier portal's purchase orders, split into orders waiting for an answer and past orders that were acknowledged, rejected or partly received, Open the full-size image (opens in a new tab)
A supplier's orders, and nobody else's.

Every query checked against the real database

The backend talks to PostgreSQL through repositories that send SQL with JdbcTemplate. A checker prepares every one of those SQL strings against the live database, so a misspelt column or a wrong type fails the check before anyone opens the screen.

A read sweep does the same for the API: it calls every GET endpoint declared in the backend controllers and reports any that fail.

Screens

How it's built

LayerTechnology
BackendJava 21 and Spring Boot 4.1, with 85 REST controllers and repositories that use JdbcTemplate
DatabasePostgreSQL 17, with 85 Flyway migrations and 278 tables, started locally with Docker Compose
FrontendNext.js 16, React 19 and TypeScript, with 215 screens built from 36 shared components
Supplier portalA separate sign-in for invited supplier contacts, isolated from internal users in the API
QualityUnit and PostgreSQL integration tests, API smoke tests, an SQL prepare check and a browser test in Chrome
Architecture

Testing

The backend has 526 test methods in 101 test classes, in layers. Unit tests cover the business rules, and PostgreSQL integration tests each run in a disposable schema, against a throwaway database container.

On top of those sit end-to-end API smoke tests for the supplier RFQ flow, policy compliance and the anomaly scan, the SQL prepare check and the endpoint read sweep, and a browser test that drives the purchase order screens in Chrome, once as the supplier and once as the buyer.

Results

  • 132 commits between 14 September and 10 October 2026.
  • 215 screens, 102 of them detail pages, built from 36 shared components.
  • 85 database migrations creating 278 tables, served by 85 REST controllers.
  • 526 backend test methods in 101 test classes.

Built with

  • Java
  • Spring Boot
  • PostgreSQL
  • Flyway
  • Next.js
  • React
  • TypeScript

56 results