Billy case study | Custom platform, agentic operations | ComplxAI
Custom platform · Operations

Billy: a custom platform with agentic workflows in its core operations

Billy connects NDIS participants with support workers and a directory of NDIS providers. We built the platform end to end: a React web app, a serverless API on AWS, an admin console and a communications engine, with routine operations carried by the system and the decisions that matter left to people.

Two‑sided
Participants, support workers and providers on one platform
Serverless
Fastify on Lambda, DynamoDB, Cognito, S3 and SES
Event‑driven
Agentic workflows running through the core operations, not beside them (client-reported)
The problem

Finding a verified support worker should not need a back office

Participants need a trustworthy way to find verified support workers near them, agree an hourly rate within NDIS price caps, set up recurring support and reconcile the hours delivered. Workers need onboarding, verification and a pipeline of jobs. Behind both sits an operations team that would otherwise send welcome emails and reminders by hand and work verification queues by hand. Billy needed a platform where that routine work is carried by the system and people step in only for a judgement call.

Constraints

  • Every support worker must be verified by a person before a participant can find them
  • Rates and schedules have to respect NDIS price caps and time bands
  • Three roles (client, support worker, admin) on one codebase with strict separation of what each can see and do
  • Signups, reminders and booking creation cannot depend on manual steps

At a glance

Client
Billy
Industry
NDIS disability support marketplace, Australia
Scope
Web app, serverless API, admin console, communications engine
Platform
AWS Lambda, API Gateway, Cognito, DynamoDB, S3 and CloudFront, SES, EventBridge; Node.js, Fastify, React
Delivery
Bitbucket Pipelines, dev and prod stages, Serverless Framework
The solution

One platform, three roles, and a system that does the routine work

A React single-page app talks to a serverless API, DynamoDB is the system of record, and AWS events drive the routine work that does not need a person. Two decisions shaped the build: keep the human approvals explicit in code, and make routine operations triggers, not tasks.

Web app

React 18 with Vite, Tailwind and React Router, signed in through the Amplify Authenticator. A role-driven router builds separate client, support-worker and admin dashboards, and an onboarding wizard runs before any of them renders. PWA-capable, with a schedule builder, budget estimator, location autocomplete and image uploader.

Serverless API

One AWS Lambda per HTTP route behind an API Gateway HTTP API, on Node.js 22. Each handler is a Fastify app wrapped for Lambda through a shared factory, with JSON-schema validation on every route. Shared code ships as two Lambda layers.

Identity and accounts

An Amazon Cognito user pool handles email and phone login. Lambda triggers provision the DynamoDB user record on confirmation and block suspended or deleted accounts at sign-in. A JWT authoriser and an authorise plugin enforce account status, terms acceptance and route-level roles.

Discovery and matching

Location-aware search over workers and providers: paginated DynamoDB queries filtered by text, skills, rate band and verification, with addresses geocoded through AWS Location Service, a radius filter and a state-level fallback. Private fields are stripped before anything is returned.

Jobs, schedules and bookings

Clients post jobs with a recurring schedule (one-off, weekly, fortnightly or monthly, per-day time slots, timezone), a budget and public or invite-only visibility. A scheduler expands each job into timezone-correct occurrences and creates bookings idempotently, re-syncing future bookings when a schedule or rate changes.

Verification and admin console

Support workers upload insurance, police-check and qualification evidence. An admin approves or rejects each document and flips the verified flag; only verified, onboarded workers appear in client search. The console also covers user and job search and the NDIS provider directory.

Around these sit connection requests with in-app chat, a media pipeline that resizes profile photos and serves them from S3 through CloudFront, a public interest form that stores leads and emails ops, and a key-protected worker feed that returns only public profile fields.

Agentic operations

How the workflows run through the core operations

The platform watches for state changes and acts on them: a confirmed account, a stalled onboarding, a flipped verified flag, a new schedule. The decisions that matter stay with a person.

  1. Sign-upCognito confirms the account; a trigger provisions the user record and notifies ops.
  2. Welcome and nudgesA change record on the users table sends the welcome email. A daily job sends a capped series of onboarding reminders to anyone who stalls.
  3. VerificationThe worker uploads evidence; an admin approves or rejects it. Only then is the worker searchable, and the verified email goes out on the flag change.
  4. Job and matchA client posts a schedule; workers apply or are invited; the job owner accepts, and the negotiated rate is kept with the application.
  5. Bookings and hoursThe scheduler turns the job into bookings. The worker submits hours, the client confirms, the booking completes.

The approvals are explicit in the code, not a policy beside it: an admin verifies each worker and approves each document, job owners accept applications, and clients confirm hours before a booking is complete. Internal jobs run under a named script identity, so every write is attributed.

The helpers layer also registers Amazon Bedrock runtime and OpenSearch clients as groundwork rather than features in use, so model-backed steps and richer search can be added without re-plumbing the platform. That is how we approach agentic workflow automation: deterministic where the rules are known, with seams in place for models where they earn their keep.

Architecture

How the system is put together

Serverless end to end: one Lambda per route, DynamoDB as the system of record, AWS events wiring the operations together.

  • Clientweb app
    React 18 + Vite SPAAmplify Auth + AuthenticatorRole-based routeraxios with Cognito ID tokenPWA build
  • Edge and identitywho gets in
    Amazon Cognito user poolAPI Gateway HTTP APICognito JWT authoriserCloudFront for profile images
  • API computeone function per route
    AWS Lambda (Node.js 22)Fastify via shared lambdify()Lambda layers: core libs + helpersAuthorise plugin (status, terms, role)JSON-schema validationVPC-attached, per-stage IAM role
  • Datasystem of record
    DynamoDB on-demand: users, jobs, bookings, verifications, applications, connections, chats, leads, providersGSIs by email, role, status, suburb, client, workerS3 resources bucketAWS Secrets Manager
  • Events and automationthe operations layer
    Cognito triggers: PostConfirmation, PostAuthenticationDynamoDB change records → transactional email LambdaEventBridge daily schedule → onboarding remindersSNS post-confirmation processor
  • Integrationsservices around it
    AWS Location Service (AU-filtered place index)Amazon SES (raw MIME HTML email)Ops chat webhooks (errors, signups)Bedrock runtime and OpenSearch clients (groundwork)
  • Delivery and opshow it ships
    Bitbucket PipelinesServerless Framework v3 → CloudFormationPer-function packagingserverless-pruneserverless-offline + aws-jwt-verify
Implementation

Security, delivery and day-to-day operation

Two repositories, API and web, on Bitbucket. Every push is linted and tested; the dev and prod branches each deploy their own stage. Security is enforced at the gateway, in the API and in the data layer.

Security

  • API Gateway validates Cognito JWTs pinned per stage; the authorise plugin re-loads the user from DynamoDB and rejects unauthenticated calls on any route not marked public
  • Route config declares allowed roles; handlers add ownership checks (job owner, invited worker or admin); terms acceptance is required and periodically re-required
  • Every route carries a JSON schema that rejects unknown properties; the public worker feed requires a shared key compared in constant time and strips private fields
  • Third-party keys come from AWS Secrets Manager; Lambdas sit in VPC subnets under a per-stage IAM role; every DynamoDB write is attributed, and records are soft-deleted rather than hard-deleted

CI/CD and observability

  • Bitbucket Pipelines runs lint, a Serverless config print and tap unit tests on every push
  • Pushes to the dev and prod branches deploy with the Serverless Framework straight to CloudFormation, each function packaged on its own; stage configuration is injected through per-stage environment variables
  • Local development runs serverless-offline with aws-jwt-verify checking real Cognito tokens, so auth behaves the same on a laptop
  • Structured logs with a request ID per invocation; the central error handler posts server errors to an ops chat channel, and scheduled handlers are wrapped so a failure is reported, not dropped

Technologies

  • React 18
  • Vite
  • Tailwind CSS 4
  • AWS Amplify Auth
  • Node.js 22
  • Fastify 4
  • Serverless Framework 3
  • AWS Lambda + layers
  • API Gateway HTTP API
  • Amazon Cognito
  • Amazon DynamoDB
  • Amazon S3 + CloudFront
  • Amazon SES
  • Amazon EventBridge
  • AWS Location Service
  • AWS Secrets Manager
  • Bitbucket Pipelines

As with every paid stage in how we work, the IP is the client's: the two repositories, their pipelines and the documented table design are Billy's to run or take in-house.

Outcome

Routine operations carried by the system

Signups, welcome and verified emails, onboarding reminders, lead capture and booking generation run from triggers and schedules rather than from anyone's to-do list. Built so the operations team works a verification queue and receives signups and expressions of interest as alerts. The outcome is client-reported.

Client-reported
Routine operations carried by the system
A custom platform with agentic workflows running through its core operations rather than sitting beside them.
Human-approvedWorker verification, document approval, application acceptance and hours confirmation stay with people.
Start with a conversation

Running a two‑sided operation by hand?

Book an AI strategy call. The first two conversations are free and every stage is priced in writing before it begins.