02Professional WorkLive internal system · no records, routes or screens published

Internal Management System

An internal operations system for a wireline company — incident reporting, crews, equipment, attendance and medical readiness — held together by one permission model and the test suite that guards it.

Relational tables
26
Permissions
32 · 7 baseline profiles
Feature modules
13, sliced by domain
Committed test files
33
Context
Well Logging Energy · Professional work
Replaces
Printed incident forms, planning sheets and monthly paper registers
Period
July 2026 — Present
Role
Requirements, architecture, constraints, direction and review
Shape
Nine workspaces over one schema and one permission model
Status
Deployed internally · under active development
Visibility
Private repository · no records, routes or screens shown

Covers

Systems Programming
Data
Databases
Security
Product
People

Stack

  • Next.js
  • React
  • TypeScript
  • PostgreSQL
  • Drizzle ORM
  • Zod
  • Cloudflare Turnstile
01

The problem

The company ran its operations on paper. Incident and hazard reports on printed forms, field work on a standard operations planning sheet, attendance and equipment utilisation on monthly grids, medical fitness on certificates in a folder.

Each of those has a different audience and a different rule about who may see it. A safety report is not an attendance register is not a medical certificate, and the people allowed near one are frequently not allowed near another. On paper that separation is enforced by which filing cabinet a document sits in.

So the replacement could not be one dashboard over one table. It had to be several workspaces sharing an organization, a permission model and an audit trail, without leaking across the boundaries between them — which is the part that actually determines whether a system like this can be trusted with medical records at all.

  1. ORGANIZATION
  2. PEOPLE
  3. CLIENTS
  4. ACCESS
  5. MEDICAL
  6. JOBS
  7. ATTENDANCE
  8. INCIDENTS
  9. ASSETS
02

The system

The code is sliced by feature rather than by technical layer. Each workspace owns its domain rules, its validation, its permission checks and its components in one place, so a change to how attendance works stays inside attendance instead of rippling through a shared controllers folder.

Underneath, everything leans on one organization module — people, departments, teams — because every other workspace is ultimately about someone or something that belongs to the company. Getting that spine right early is what let the later workspaces be small.

Writes go through a single wrapper that resolves the caller, checks authority, runs the mutation and records the audit event inside one transaction. A state change and the record of that change either both land or neither does. An audit trail that can silently disagree with the data it describes is worse than no audit trail, because it is trusted.

    • Intake form

      Unauthenticated

    • Staff portal

      Signed in

    • Self-service

      Own records only

  1. Route gating

    First boundary

  2. Authorization module

    Permissions resolved

  3. Feature modules

    Sliced by domain

  4. Transactional actions

    Write and audit together

  5. PostgreSQL

    26 relational tables

  • Organization module

    People, departments, teams

  • Audit log

    Per-record timelines

  • Private media

    Access-checked routes

03

Who may do what

Authorization is its own module rather than a check scattered through routes. It resolves what a caller may do from 32 named permissions, seven baseline profiles, and any direct grants layered on top of a profile for the person who is a genuine exception.

The check runs on the server on every request. Route gating is the first boundary, not the only one — a workspace the navigation never offers is still refused when it is requested directly, and hiding a control is treated as presentation, never as protection.

It is also the one part of the system carrying a regression suite of its own. Permission logic is exactly the code where a quiet change is expensive and invisible: nothing breaks, nothing errors, and someone can suddenly read a colleague's medical record. The tests exist so that a widened boundary fails loudly instead.

  • Named permissions
  • Baseline profiles
  • Direct grants
  • Server-side checks
  • Route gating
  • Audited writes
04

What it actually does

Nine workspaces are in internal use, each replacing something that used to be printed, photocopied or kept in a spreadsheet on one person's machine.

Two details shaped more of the build than their size suggests. Intake is bilingual, Urdu and English, because the people closest to a hazard are not always the people most comfortable reporting it in English — and a safety system that quietly filters by language is not collecting the reports that matter most.

The second is that spreadsheets had to keep working. Registers import from and export to workbooks, and reports print to a clean A4 page, because the system has to interoperate with the paper process it is replacing rather than demand everyone abandon it on the same day.

Safety & compliance

  • Incident and hazard reporting
  • Bilingual intake, Urdu and English
  • Triage, routing, investigation, closure
  • Medical readiness and expiry tracking

Operations

  • Field job planning
  • Crew assignment
  • Stage progression
  • Customer directory

Assets

  • Equipment register
  • Monthly utilisation grid
  • Fleet register and status logs
  • Odometer readings

Workforce

  • Employee records
  • Self-service profiles
  • Departments and teams
  • Monthly attendance register

Administration

  • Access control
  • Permission profiles
  • Branding held in the database
  • Activity log

In and out

  • Workbook import
  • Workbook export
  • Print-ready reports
  • Field photographs normalized on upload

Every workspace listed here is in internal use. Nothing is named at record, route, client or role level, and no screen is shown.

05

A month at a glance

The attendance and utilisation workspaces are the same shape: one entry per subject per day, folded into a month-wide grid an operations lead can read across in a single pass.

The grid deliberately stops at recording. It says which state an asset or a person was in on each day; it does not compute a utilisation percentage, an efficiency score or a ranking. Those numbers would be easy to add and easy to misread, and nobody has asked for a measure whose definition has not been agreed.

One status entry per subject, per day

Subject × calendar month

  • One code per cell
  • Up to 31 day columns
  • One row per person or asset

A month-wide grid, exportable as a workbook

A register, not a score

The grid records which state something was in on a given day. Turning that into a percentage would mean agreeing what counts as available, what counts as productive and what a good number looks like — decisions that belong to the operations team, not to the schema.

subject × day → state
06

What the tests hold

There are 33 committed test files, and they sit beside the code they cover rather than in a separate tree — a workspace's domain rules, validation, permissions and workflow tests live in the workspace.

They run on Node's own test runner, so the suite adds no test framework to the dependency list. That was a deliberate constraint on a system one person maintains: every dependency is something that will eventually need upgrading, and a test suite is not worth a second toolchain.

The shapes worth naming are the permission tests on every workspace that has a boundary, the round-trip tests on workbook import and export, and one end-to-end test that walks a record through its whole lifecycle. Coverage is not measured, so no coverage figure appears here.

  1. 0133 test files committed alongside the code they cover
  2. 02Authorization carries both a core suite and a regression suite
  3. 03Every workspace with a permission boundary has a permissions test
  4. 04Workbook import and export are tested as a round trip
  5. 05One end-to-end test walks a record through its whole lifecycle
  6. 06Node's built-in test runner — no test framework dependency

Known-data KPI test

  1. Sign-in
  2. Permissions resolved
  3. Workspace entered
  4. Record created
  5. State advanced
  6. Audit event written

The chain names the stages one end-to-end test walks, not its assertions, fixtures or data. No coverage percentage is reported here, because none has been measured.

07

How it is served

The application sits behind a reverse proxy that terminates TLS, and talks to PostgreSQL through a bounded connection pool. Sessions are database-backed, sign-in is rate-limited and bot-checked, and passwords are stored with a salted key-derivation function rather than a plain hash.

Private media never has a public URL. Field photographs, portraits and medical certificates are held in a private bucket and reached only through in-app routes that re-check the caller's permissions on the way past — a link that leaks is a link that stops working for whoever it leaked to.

Photographs arrive from phones, which means they arrive large and occasionally in formats a browser will not display. They are converted and resized on upload, so the storage cost and the load time are settled once at intake rather than paid on every read.

  1. Client

  2. Reverse proxy

    TLS termination

  3. Next.js application

    Server Components

  4. Connection pool

    Bounded

  5. PostgreSQL

  6. Private object storage

    Reached only through the app

    08

    How it grew

    The order was driven by which piece of paper was costing the most, not by which module was most interesting to build.

    Reporting came first because an incident form that goes missing is the one failure with a genuine safety cost. The organization spine came second, because every workspace after it needed somewhere for a person to belong. The permission model was hardened once there was enough in the system to be worth protecting properly.

    1. 01

      Reporting core

      Structured incident and hazard reporting, replacing the printed form.

    2. 02

      Organization spine

      People, departments and teams — something for every later workspace to hang off.

    3. 03

      Job planning

      The operations planning sheet digitized, with crews and lifecycle stages.

    4. 04

      Assets and workforce

      Equipment, fleet, monthly utilisation and attendance, with workbooks in and out.

    5. 05

      Permission model

      Named permissions, baseline profiles and direct grants, resolved server-side.

    6. 06

      Test suite

      Domain, validation, permission and workflow tests committed beside the code.

    09

    The tradeoff

    My strongest engineering evidence on this project sits in exactly the places I cannot show: domain rules, permission resolution, transactional behaviour and the relationships between records.

    On this page I would rather describe those honestly and abstractly than manufacture a realistic-looking screen full of invented employees. A fake dashboard would show more and prove less, and anyone who has built one of these can tell the difference.

    Where the engineering is

    • Domain rules
    • Permission resolution
    • Transactional writes
    • Audit behaviour
    • Data relationships

    What may be published

    • Sanitized diagrams
    • Architecture only
    • No records, routes or clients
    • Approved screenshots when available
    • Private system
    • Public case study
    • Safe abstraction
    • Engineering evidence
    10

    What holds, and what does not

    The previous version of this case study said the repository had no committed tests. That is no longer true — there are 33 files — so the claim has been replaced rather than quietly dropped.

    What is genuinely outstanding is narrower and less flattering. Schema reaches the database by push rather than through committed, versioned migrations, which means there is no migration history to review or roll back. The tests run when someone runs them; no continuous integration runs them on a change. Both are known, both are mine, and neither is hard — they are simply not done.

    Verified

    • Domain rules and validation, by committed tests
    • Permission resolution, by a dedicated regression suite
    • Workbook import and export, as a round trip
    • Type-checking and a production build, on every change

    Not verified

    • Schema history — the database is pushed, not migrated
    • Continuous integration — tests run on demand, not automatically
    • Behaviour under load or real concurrency
    • Any security review by someone other than me

    Next proof

    1. Versioned migrations
    2. CI on every push
    3. A restore rehearsal
    4. An external review
    11

    Current status

    The system is deployed internally and in daily use across its nine workspaces, and remains under active development.

    The rows below separate what is in place from what is not, on the same terms as the section above: nothing planned is listed as though it were delivered.

    Nine workspaces
    In internal use
    Permission model
    32 permissions · 7 profiles
    Automated tests
    33 files committed
    Backup & restore procedure
    Documented
    Versioned migrations
    Not yet — schema is pushed
    Continuous integration
    Not configured

    Access & audit model

    • Authority derived from named permissions, not from job titles
    • Baseline profiles, with direct grants for genuine exceptions
    • Server-side checks on every request, not only at the route
    • Database-backed sessions, rate-limited and bot-checked sign-in
    • Transactional mutations that write the record and its audit event together
    • Per-record audit timelines, plus a separate administrative activity log
    • Private media reachable only through access-checked in-app routes

    Described at concept level only. Permission matrices, role identifiers, route structures and implementation detail are deliberately withheld.

    Evidence boundary

    Supported

    I can show explicit feature boundaries, a permission model of 32 named permissions with baseline profiles and direct grants, server-side authorization carrying its own regression suite, transactional writes paired with per-record audit timelines, private media delivery behind access checks, and 33 committed test files covering domain rules, validation, permissions, workflows and workbook import and export.

    Not overstated

    This is a live internal system, so no records, routes, screens, client names or role identifiers appear here. I do not claim production scale, quantified business impact, or a security review by anyone other than me. Schema is applied by push rather than by committed migrations, and the tests are not yet run by continuous integration.

    Technical notes

    The system runs as one Next.js application over PostgreSQL, with private S3-compatible object storage reachable only through in-app routes that re-check permissions per request. Data moves in and out as spreadsheet workbooks, field photographs are normalized on upload, and every write that changes a record's state is transactional and audited.

    Core stack

    • Next.js (App Router)
    • React Server Components
    • TypeScript
    • PostgreSQL
    • Drizzle ORM

    Domain & safety

    • Schema validation at every boundary
    • Transactional server actions
    • Typed domain errors

    Data in & out

    • Workbook import
    • Workbook export
    • Print-ready reports

    Media

    • Private S3-compatible object storage
    • Access-checked media routes
    • Conversion and resizing on upload

    Security

    • Salted key-derivation password hashing
    • Database-backed sessions
    • Rate-limited sign-in
    • Cloudflare Turnstile

    Testing

    • Node's built-in test runner
    • 33 committed test files
    • Authorization regression suite
    Repository
    Private
    Public artifacts
    Approved public artifacts will be added after redaction and review.