Westbridge Materials Pty Ltd
Tax invoice
INV-4628
12 September 2026
Supply of paving and sand
Total AUD 4,280.00
GST included 389.09
PO reference not on page 1
PrimeHQ · Application engineering
Weeks, not quarters.
Custom web applications delivered through AI-assisted development and a Cloudflare-native architecture. Built to launch quickly, scale naturally and keep evolving as the business changes.
Custom web applications, built faster with AI, engineered for continuous change.
Example request path
Workers run the application itself: routes, checks, auth decisions, and calls to the data services below. This replaces a traditional application server for the request path.
One possible shape. An application uses the services it actually needs.
Short-cycle development
The point is the next release, not a single handover. Each pass is smaller than a traditional project, and a person still decides what is allowed into production.
The users, the real steps, the constraints, and what a finished job looks like.
A small working slice that a person can click, before the rest of the system exists.
The smallest production application that completes the job, including the unglamorous edges.
Behaviour, permissions, and failure. Generated tests are read, not trusted on arrival.
A staged release. A person decides when it is allowed to face real users.
What people actually do, where the process stalls, and which assumption was wrong.
The next change, smaller than the first, shipped the same way.
Applications
The work is a business process with users, records and a result. Named case studies are not required to see the kind of application. The longer accounts are custom web applications, AI inside the product, and the Cloudflare architecture.
A single place for a process that currently lives in a spreadsheet and an inbox.
The work in flight, not a wall of charts detached from the queue that produced them.
A customer can see status, documents and requests without emailing to ask.
Accounts, bookings, invoices and records for a membership or a program.
A known sequence of steps, with a person where the decision is not safe to automate.
A product used by more than one organisation, with tenant data kept apart.
Availability, bookings and the exceptions that a calendar link does not handle.
Records of money, stock or entitlements where the state of each item has to be clear.
Intake, extraction, review and filing, with the original file kept beside the fields.
Figures the business already defines, drawn from the application that created them.
A clear boundary to Xero, a CRM, a line-of-business system, or another PrimeHQ product.
Search, extraction or drafting inside a workflow that still has an owner.
A working internal tool keeps the queue, the exceptions and the last run in one place. This is a conceptual member-operations console.
Example interface. Not a client project.
Operations · 1–28 Sep 2026
Production
All automation runs this month.
Most of the extra time is on documents with no purchase order on the first page.
| Run | State | Duration | When |
|---|---|---|---|
| Supplier invoice intake | Completed | 2 min | 28 Sep, 14:06 |
| Member document pack | Awaiting review | — | 28 Sep, 13:41 |
| Booking reminder | Completed | 18 sec | 28 Sep, 13:12 |
| Nightly reconciliation | Retry 1 | 4 min | 28 Sep, 02:10 |
18 active. Invoice intake, member packs, booking reminders and the nightly reconciliation are the ones with traffic this week.
The Monday operations summary is generated from D1. It is not typed into a slide.
A member should be able to find a booking, a document and an invoice without writing in.
Example interface. Not a client project.
Member since March 2024
Active
Nothing in this example matches that search.
Thu 2 Oct 2026, 9:00 · Court 2 · confirmed.
Sat 11 Oct 2026, 8:00 · Court 1 · waitlist.
1842 · $186.00 · due 6 Oct 2026 · unpaid.
1790 · $186.00 · paid 4 Sep 2026.
SR-1044 · Change of contact email · received 26 Sep · in review.
27 Sep · “Your Thursday court is confirmed.” No reply needed.
AI-assisted engineering
Research, drafts, tests and notes move faster. Architecture, security, data access and the production release stay with an engineer.
Write down the process, the users and the outcome before generating code.
Read the existing systems, the constraints, and the platform documentation that applies.
Choose the smallest set of Cloudflare services that can hold the application.
AI drafts code and changes. A person reviews the diff before it is kept.
Tests are generated and then edited. Passing tests do not replace a look at the behaviour.
Data access, auth, failure and abuse get a human review on every release.
Decisions and operator notes are written so the next change has a starting point.
The last known behaviour is compared with the change, especially around permissions and money.
The next release is scoped from what the running application showed, not from a new slide deck.
The assistant can explain, draft a test, or propose a check. A person accepts the change. The example never ships it.
Example interface. Not a client project.
member-portal
// Active invoices for one organisation. Archived rows stay out.
export async function listInvoices(db: D1Database, orgId: string) {
return db
.prepare(`SELECT id, supplier, amount_cents, status
FROM invoices
WHERE org_id = ? AND archived_at IS NULL
ORDER BY issued_on DESC
LIMIT 40`)
.bind(orgId)
.all()
} export default {
async fetch(request: Request, env: Env) {
const orgId = await requireOrg(request, env)
const rows = await listInvoices(env.DB, orgId)
return Response.json({ invoices: rows.results })
}
} // Wait for a person. Do not mark the invoice paid here.
await step.waitForEvent('manager-review', {
type: 'approval',
timeout: '5 days',
})
await step.do('record decision', async () => {
return env.DB.prepare('UPDATE invoices SET status = ? WHERE id = ?')
.bind('approved', invoiceId).run()
}) {
"name": "member-portal",
"d1_databases": [{ "binding": "DB" }],
"r2_buckets": [{ "binding": "FILES" }],
"queues": { "producers": [{ "binding": "JOBS" }] }
} Build passed · 12 tests passed · not deployed
Engineering assistant
The query returns the latest 40 live invoices for one organisation. Archived rows are excluded in SQL, not in the page.
A useful test covers an empty organisation, an archived row that must not appear, and a second organisation that must not leak.
+ if (status && !['open', 'review', 'paid'].includes(status)) {
+ return Response.json({ error: 'Unknown status' }, { status: 400 })
+ } Inside the application
The model sees a bounded set of records and returns something the workflow can use: a field, a source, a draft, or a flag. It does not become the owner of the process.
Find a passage by meaning, then show the document it came from.
Ask a question in English and get a table, not only a paragraph.
Pull fields from an invoice or a form into the workflow that already expects them.
Route a file to the right queue, and leave odd files for a person.
Shorten a thread or a document for someone who still needs the source.
Suggest the next team from the content, without skipping an approval the business requires.
Surface a likely next action from similar past work.
Flag a figure that moved, with the rows that explain it.
Assemble a report from data the application already stores.
Answer from a named set of documents, and say when that set does not contain the answer.
A bounded helper for one job, with the tools it is allowed to call written down.
A short sequence of steps inside a limit, stopped when a step needs authority the agent does not have.
The model proposes. A person approves before a record changes or a message is sent.
The useful version shows which records it read, the table it produced, and what it will not do next.
Example interface. Not a client project.
Read invoices and product categories · September 2026
| Category | Amount | Invoices |
|---|---|---|
| Materials | $48,200 | 16 |
| Services | $31,440 | 9 |
| Membership | $18,600 | 100 |
| Hire | $6,240 | 11 |
Hire is down $2,110 on August. The other categories are within 6% of last month. Source: paid invoices in D1, not a forecast.
Task drafted for operations: review Hire invoices. Nothing is assigned until a person confirms it.
The file stays visible beside the fields. A low-confidence value is a review, not a silent write.
Example interface. Not a client project.
Westbridge Materials Pty Ltd
Tax invoice
INV-4628
12 September 2026
Supply of paving and sand
Total AUD 4,280.00
GST included 389.09
PO reference not on page 1
INV-4628.pdf · page 1 of 2
Waiting on a person before the record changes.
Each stage names the Cloudflare primitive that would carry it. The person at the review gate is still a person.
Example interface. Not a client project.
INV-4628 · elapsed 6 h 12 m · retries 0 · example captured 28 Sep 2026
Worker
The supplier invoice arrives on a Worker route and is stored as a row plus the original file.
Worker
Required fields are checked in code. A missing total fails here, before any model is called.
Workers AI · R2
The PDF stays in R2. Extraction reads it and writes proposed fields. Low confidence is flagged, not overwritten later.
Workflow wait
The workflow waits. No server is held open. Yuki Tanaka in Operations is the named reviewer.
Responsible: Yuki Tanaka, Operations. The run is waiting, not failed.
Workflow
Approval is an event on the workflow. The model does not approve.
Queue
The accounting update is queued so a slow partner API does not sit inside the approval request.
Queue
The supplier contact is emailed after the record write succeeds.
D1
The invoice row in D1 is the record. The PDF remains in R2 for the audit trail.
Cloudflare application stack
The diagram is a set of primitives, not a logo wall. PrimeLabs picks the ones the application needs. Deeper notes on each primitive are planned as their own pages and are not published yet.
The interface people use: pages, dashboards, portals and installable web apps.
When the work needs a screen, a form, or a dense operational view.
It is not the system of record. Business rules that must hold on every request live in the Worker.
The application runtime. Requests, validation, permissions and integrations run here.
For the request path and for jobs that are still short-lived code.
Not a place for multi-day waits or for files. Those belong to Workflows and R2.
SQL tables for the records the application owns and queries together.
Accounts, invoices, bookings, memberships, workflow records.
Not for large files, and not for a hot key that many users must update at the same instant.
A single place for state that must be consistent for one room, one tenant, or one live document.
Presence, a live editing session, a counter that cannot be loosely updated.
Not the default database. Ordinary lists and reports stay in D1.
Small values read from many places, where a slightly stale read is acceptable.
Configuration flags, a cached lookup, a short-lived token check.
Not a relational store, and not where two writes must succeed or fail together.
Object storage for uploads, originals, exports and generated files.
Invoices, member documents, CSV exports, images the application produced.
Not a database. Fields extracted from a file are stored in D1 and point back at the object.
A buffer between a request and work that can finish later.
Sending mail, calling a slow partner API, smoothing a burst of uploads.
Not the engine for a process that waits on a person for days. That is a Workflow.
A process that can pause, retry, and wait for a person without a server staying online.
Approvals, document pipelines, and anything that must resume after a failure.
Not for a single read on a page load.
Model inference beside the application, for a feature that has a defined input and output.
Classification, extraction, a short summary, an embedding.
Not on the path of every request. If the step can be done with rules, it stays rules.
A vector index for semantic search, retrieval and recommendations.
“Find documents like this” over a corpus the business owns.
Not the source of truth. Membership, money and permissions stay in D1.
A control point for model calls: logs, routing, caching and a place to change provider behaviour.
When the application calls models often enough that failures and cost need to be seen.
Not required for an application that does not call a model.
The network in front of the Worker: TLS, caching, rate controls and DDoS protection.
Every public application. The path is the same one Cloudflare already provides.
It does not replace application auth, validation, or a decision about who may see a record.
This is an operations view of one example application. It is not the Cloudflare dashboard, and PrimeLabs did not build Cloudflare.
Example interface. Not a client project.
Application · Member Portal
86,400 queries in 30 days. Rows for members, bookings and invoices. No file bodies.
Member documents and invoice PDFs. 1.8 GB. Downloads go through the Worker, not a public bucket URL.
One object per live booking board. Used so two staff cannot confirm the same court.
Depth 3. Reminder mail and the accounting handoff. Not the approval wait.
1,104 runs in 30 days. 7 waiting on a person. 1 retrying a partner timeout.
640 requests in 30 days, all from document extraction. Ordinary page views do not call a model.
Member handbook and policy pages. Used by the portal search. Invoices are still found by number in D1.
2,140 requests this week. p95 41 ms. Error rate 0.4% on a fixture import, already fixed in review.
Copy of the schema, not a copy of production members. 3,200 queries this week.
Fixture PDFs only.
Booking-board fixture. Two conflicting confirms are the test.
Depth 0. Consumers point at a log, not at members.
46 runs. Used to rehearse the approval wait.
28 extraction runs against fixture invoices.
A small index of the same handbook, rebuilt when the draft changes.
AI search improvements. Handbook queries return the section title with the passage. No schema change.
Document processing workflow. Extraction writes proposed fields and stops on a missing purchase order.
UI refinements on the member booking card. Not promoted.
Business outcomes
No application-server fleet to patch, size and watch overnight.
A release is a Worker deploy and a migration, not a machine build.
A change can ship when it is reviewed, instead of waiting for a quarterly window.
The next improvement starts from the running application and its logs.
Traffic is absorbed by the platform. Capacity planning is not a rack diagram.
TLS, rate limits and edge policy sit in front of the code. Application rules still live in the code.
Bindings, routes and environments are declared and reviewed with the application.
Fewer moving boxes. The remaining work is the application, the data and the releases.
Business areas
Work queues, handoffs and the status of a job.
What a customer asked, what was promised, and what is still open.
Pipeline context that should not be retyped into a spreadsheet.
Invoices, approvals and the trail back to a source document.
Who did what, and the record that shows it.
People, entitlements, renewals and the documents they are owed.
A defined set of records, with a question interface only where it helps.
Numbers that match the application, produced on a schedule.
Jobs, evidence and status for people who are not at a desk.
Matters, time and deliverables in one record.
A product surface that can change without a replatform.
A process with a named owner at each gate.
Process modernisation
PrimeLabs can turn that process into an application one workflow at a time. The first release is the painful path, not a replacement for every adjacent task.
Engineering principles
Engagement
Understand the users, the workflow, the constraints and the outcome.
Create the smallest coherent production application.
Deploy it safely and watch real usage.
Keep changing the application as the work changes.
Contact
Write to PrimeLabs . Say who uses the process, what the finished job is, and what must not change. There is no form and no account on this site.