Alex HerreraSoftware Developer · Cybersecurity focus
ES
← Back to projects

Professional

StarHub | Warehouse management

Container receiving line by line, with the position of each pallet and a photo of damaged goods. It reads the ERP over SQL and writes only through its API.

  • Full Stack
  • Mobile
Organisation
Star Cargo Serviceopens in a new tab
Role
API and security layer
Period
2026-08 — Present

Stack

  • TypeScript
  • Node.js
  • MySQL
  • Google Cloud Run
  • Docker
  • Kotlin

Context

The warehouse worker records an incoming container from a phone. They scan the receipt code, log every line as it comes off, mark the slot each pallet went to, and photograph damaged goods.

This service is the backend for that Android app. The Android client was led by another member of the team, with contributions from me.

Problem

Receiving was recorded on paper and transcribed into the ERP afterwards. Until that transcription happened, the system’s inventory did not match what was in the warehouse.

The service exists so a receipt reaches the ERP at the moment the warehouse worker records it.

Technical decisions

The ERP generates receipt numbers with its own formulas, and those formulas take no lock. Two warehouse workers operating at once would have been given the same sequence number. It also has notifications and automated actions over those tables, which a direct INSERT would not have fired.

Reads go over direct SQL against the ERP database. Writes go through its API, which is slower but respects those formulas and those triggers.

No route in the service writes over SQL. Every write leaves through a single API client, which is the only place in the code that issues one.

Architecture

A phone cannot authenticate with the platform’s identity, because enrolment happens before the device holds any credential. That is the service’s gate: a single public endpoint with four rules applied at once.

PhoneEnrolmentTokenServiceERP

Enrolment uses a code that expires and is bound to the device identifier. The registry stores its hash, never the value, and the code does not work again after first use.

The enrolment endpoint is public, so it is bounded per origin and per device. Repeated attempts to guess the code stop well before the space of possibilities is covered.

The token grants reads over SQL and writes only through the ERP's API. The service's surface exposes no direct write against the database.

Every query is limited to the warehouse of the enrolled device. A phone enrolled at one warehouse cannot reach another warehouse's inventory.

Four rules protect the one endpoint that does not require a prior credential.

The enrolment registry lives in the process itself, so the service is deployed on a single instance.

Result

A receipt reaches the ERP at the moment the warehouse worker records it, with its lines, the slot for each pallet and the photographs of damaged goods.

A smoke test starts the server and makes real requests against it. It covers TLS, credentials, warehouse scoping, the query and the response mapping. It uses no test doubles and writes no data.

Alongside it there are 30 node:test cases covering pagination and the device lifecycle.

What I learned

Enrolment state ended up inside the process, so the service cannot take a second instance until that state moves to shared storage. That move is recorded as the next change.