Client operations hub with a reviewed update queue
An internal web app that gives an agency one page per client, with search, role-based visibility enforced in the database, a review queue for every change, live feeds from work tools, quality-check punch lists and a connector for AI assistants.
Problem
An agency kept what it knew about each client in several places at once: hand-maintained text files on one person's laptop, spreadsheets, a project management tool, meeting notes and separate reports. The lists disagreed with each other, there was no single page per client that the account team could open, and anything typed into the shared notes went in without anyone checking it.
Goal
One place where client facts live and are edited: a page per client that the account team can browse and search, where each person sees only what their role allows, where no update reaches a client's record until a second person approves it, and where the data can still be read as plain text so the agency is not locked in.
My role
Sole developer and architect. I worked from a leadership meeting and an existing hand-built mockup, mapped the existing sources, designed the data model and permission rules, built and tested the app, imported the existing records, deployed it, and ran the review rounds before it opened to leadership.
Solution
A server-rendered web app on a managed PostgreSQL database, running as serverless containers on a public cloud, with scheduled jobs for the live feeds. Each client has one page: an at-a-glance summary, their side and ours, services, likes and dislikes, open actions, conflicts and gaps, documents and a team and services panel.
Visibility is decided by the database itself, every change goes through a review queue, and AI assistants reach the same records through a separate connector service whose writes are always queued for a person to approve.
How it works
Sign-in. Staff sign in with their company account through the cloud provider's identity-aware proxy. The app verifies the signed token on every request and then requires the person to be on the hub's own staff list.
Visibility. There are three audiences: everyone, account managers, and leadership with admins. Row-level security in PostgreSQL enforces them, and the app connects as a role that does not own the tables, so the policies always apply. Money terms are visible to leadership only.
Review queue. Anyone signed in can suggest an update. It is stored as a proposal with the version it was based on and who sent it. A different approver accepts, rewords or rejects it with a reason; nobody approves their own. Approval writes the change and its audit entry together, and only if the record has not changed underneath. Updates that appear to contain a password or key are refused when sent and again at approval. Approvers get a short notice in the team chat tool with a link and no client details.
Search. PostgreSQL full-text search with a typo-tolerant extension, limited to what the searcher's role can see.
Live feeds. Scheduled jobs bring in task status from the project management tool every hour and turn meeting-recorder summaries into queue suggestions for approvers, never applied on their own. A weekly growth check pulls search-visibility figures for each client, gives a rule-based verdict and asks a hosted language model for ideas, sending only fields every staff member may see with money masked.
Quality checks. Each piece of client work can get a punch list built from a versioned checklist for its type of job. Every item needs proof before it passes, high-risk items need a second person to verify them, and checklist items cannot be deleted, only marked not applicable with a recorded decision. Only account managers and leadership can sign a list off, and a client-facing copy downloads as a PDF without internal notes. A scheduled job watches the project management tool and alerts leadership when a card moves on before its list is signed off. A hosted language model can suggest missing checks, which count for nothing until a person accepts them, and a card description that mentions money is never sent to it.
AI connector. A separate service offers REST and Model Context Protocol endpoints. Tokens are issued by an admin, stored only as hashes and expire. A connector session never carries leadership or admin rights, and every write it makes goes to the review queue.
Staff portal integration (built and tested, not yet deployed). Once deployed, staff will reach the hub through the company's staff portal. Before touching the database, the hub checks two things on each call: the identity of the portal's own service, and a short-lived, single-use proof of the signed-in person, signed by the cloud provider for that request. The person's rights still come from the hub's own staff list, never from the portal.
Portability. A nightly job writes a read-only Markdown copy of each client without the leadership-only or account-manager-only content. Other internal tools read a staff-safe view of the data through their own restricted database login.
Credentials. Shared logins sit in secure credential storage with restricted access, separate from the client pages.
Technical challenges
Making visibility part of the data itself, so search, exports and the AI connector cannot show more than the person is allowed to see.
A review queue that is safe under concurrent edits: version checks, no self-approval, and the change and its audit entry written in one transaction.
Importing years of hand-written notes into structured records while leaving out logins, personal material and anything that did not belong to a client.
Turning meeting summaries into useful suggestions without letting any of them change a record on their own.
Keeping money terms and other restricted data away from the language model.
Letting AI assistants work with the records without giving them more rights than a person, or any way to skip review.
A scheduled check of the project management tool that never duplicates a list, never remakes a cancelled one, and skips alerts for work that was already past its checks when its list was made.
Letting a second application act for a signed-in person while the hub itself decides who that person is and what they may do.
Capabilities
- One page per client with summary, services, actions, conflicts and documents
- Search across all clients with typo tolerance, within each role's visibility
- Three audiences enforced by database row-level security
- Review queue with version checks, no self-approval and an audit trail
- Approver notices in the team chat tool
- Hourly task status and meeting-note suggestions from work tools
- Weekly growth check with a rule-based verdict and AI-written ideas
- REST and Model Context Protocol connector with hashed, expiring tokens
- Nightly read-only Markdown export
- Staff-safe read views for other internal tools
- Secure credential storage with restricted access
- Quality-check punch lists with proof, second-person checks and sign-off
- Client-facing punch list PDF
- Leadership alerts when work moves on before sign-off
- Light and dark themes checked for text contrast
Technology
Impact
Built, deployed and live with the agency's leadership, who sign in and approve updates through it. The scheduled feeds, the weekly growth check and the nightly export run in production, and other internal tools read from it. The quality-check punch lists are live in a pilot, and the staff portal integration is built and tested and waits for its own deployment. Opening it to the wider account team is the next step. No business outcomes are claimed.
Skills demonstrated
- Full-stack web development
- Database design and row-level security
- Access control and audit design
- Data migration from unstructured notes
- API and integration design
- Safe use of language models with restricted data
- Cloud deployment and scheduled jobs
- Automated and browser testing
Demo
Live demoOne invented client page and three invented people. Switch between staff, an account manager and leadership to see sections appear and disappear, with money terms shown to leadership only. Suggest an update, then try to approve it: staff cannot approve, nobody approves their own update, and a change only reaches the page once another approver accepts it, with every step written to the audit trail.
A demo here uses only invented names and data.