Skip to content
mbmsabithb
All work

Personal project

Live

Topnotch

One platform for a UAE steel contractor: the website, the books and an AI that reads the paperwork.

Role
Co-owner · built the platform
Period
Oct 2024 – present
Built with
PostgreSQL (Supabase, RLS)Cloudflare WorkersOpenNextGeminiNext.js 15React 19TypeScriptnext-intlTailwind

Visit topnotchsteel.com

Topnotch Steel & Contracting FZE is a UAE contractor for steel, aluminium and fit-out work. The platform combines a public website that wins customers with a private portal that runs quoting, invoicing, job costing, banking and VAT, plus an AI assistant that reads supplier bills and bank statements. I co-own the company and built the platform.

22
database tables, with row-level security
14
read-only tools for the AI assistant
~90
service pages, each in English and Arabic
525
commits over two years

A job moves through numbered documents

Each document links to the one before it, so nothing is retyped and every figure can be traced.

  1. 1

    Quotation

    Starts from a job-type preset. Saved line items fill in with one click.

  2. 2

    Proforma

    Requests the advance payment before work starts.

  3. 3

    Tax invoice

    Raised against the quote. Revisions still count toward the same job.

  4. 4

    Receipt

    Records the payment and the account it landed in.

  5. 5

    Credit note

    Corrects or reduces an invoice.

  6. 6

    VAT return

    Quarterly figures come straight from the documents above.

What the portal does

Documents that edit like they print
Click any field on the A4 sheet and type. Presets by kind of job, a description library, revisions saved without overwriting, and amounts in words with 5% VAT calculated for you.
Receivables
Who owes the company, aged into 0–30, 31–60, 61–90 and 90+ days. Statements of account, and duplicate clients merged in one safe step.
Costs and job costing
Every bill and expense can be charged to a project, so profit and margin per job are visible. Subcontracts handle staged bills, advances and retention.
Bank, cash and VAT
Ledgers for bank, card and petty cash, balance checks with an audit trail, and a quarterly VAT return. Every sidebar item shows the Tally screen it replaces.
A website the team runs themselves
Around 90 bilingual service pages managed from the portal as draft or published. An AI draft button writes SEO-focused English and Arabic content from a service title.
Found by people and by AI
Per-page metadata, sitemap and RSS, and llms.txt files so AI assistants can describe the company accurately.

The assistant reads the paperwork. A person approves the books.

Staff upload a supplier bill or a bank statement. The assistant proposes entries as cards that a person edits and confirms, one by one.

  • Modelcan be wrong
  • Codedeterministic
  • Persondecides
  1. 1

    Upload

    A bill or statement as PDF, JPG, PNG, WebP or HEIC, up to 10 MB.

    Person
  2. 2

    Read it

    Finds the account by IBAN, account number or bank name, and asks if unsure.

    Model
  3. 3

    Check for duplicates

    Compares with entries already recorded within three days of each line.

    Code
  4. 4

    Propose entries

    Exactly one editable card per statement line. Nothing skipped or merged.

    Model
  5. 5

    Confirm each card

    Staff edit, answer the few questions it asks, and confirm.

    Person
  6. 6

    Record

    Written in a single all-or-nothing database step.

    Code

Decisions I'd defend

It never posts by itself
Every entry is a proposal. Nothing is recorded until a person confirms it.
Numbers come from code
Totals are calculated by the system, not estimated by the model.
A hidden menu item is also a locked door
Roles are sets of permission keys, enforced the same way in the menu, the pages and the database through row-level security. The assistant runs as the signed-in person, so it sees only what they may.
Owner-only area
The partners' profit-share record is visible to the owner login alone, not even to other admins.
All-or-nothing steps
Recording a statement line, merging clients and paying a partner share each run as one transactional step.
Duplicates are refused
Document numbers are unique, and a supplier's bill number can only be entered once.

Under the hood

One Next.js 15 codebase serves both the website and the portal. It runs on Cloudflare Workers through OpenNext, stores data in Supabase (Postgres, Auth and row-level security), and calls Gemini for the assistant. English and Arabic come from next-intl, including right-to-left layouts. Every push to main deploys automatically through Bitbucket Pipelines.

Its print sheets later became the model for the Araco admin: editable A4 sheets, quote-to-invoice links and row actions.