A.T. Automations
connecting
Healthcare automation · working demonstration

Bots that know
when to stop.

Three unattended processes against a real SQL database, built the way an enterprise automation has to be built: queue-driven, retried only when retrying can help, auditable to the field, and handing work to a person the moment the decision stops being the robot's to make. Run them below and watch the queue move.

loading .NET 8 · minimal API SQL · 13 tables, 3 views 98 tests
Every record here is synthetic. Patients, claims, remittances and identifiers were generated by tools/generate_seed.py. Nothing in this database came from a real person, and no complete identifier exists in it — SSN values are a fabricated four-digit fragment that the API never returns to anyone.
01 · Run it

Automation console

Each process follows the same skeleton — initialise from configuration, claim a transaction, process it, classify the outcome, close the run — because a shared skeleton is what makes a portfolio of bots supportable by someone who did not write them.

02 · When it goes wrong

Exception triage

The distinction that keeps a queue moving: a business exception is terminal for that item — the denial needs a coder, the payer has no such member — and retrying it only burns SLA. A system exception is the environment failing, and gets the retry budget with exponential backoff. Conflating the two is the most common reason a production bot looks healthy while quietly doing nothing.

Queue depth

Denial recovery by reason code

● Worked by the robot ▲ Still open

Failed transactions

ReferenceClassificationCode RetriesWhat happened
03 · Human in the loop

Steward review

The matcher scores candidate duplicates on weighted features and auto-merges only above the configured threshold. Everything in the ambiguous band becomes a task here, with the feature breakdown attached — a steward handed a bare confidence number cannot audit the decision, and a wrong merge in a master person index puts one patient's history in another patient's chart.

04 · The database

SQL workbench

A read-only console over the live database. Exposing SQL to a browser is either carefully bounded or a breach, so it is bounded in five places: shape (one statement, SELECT or WITH only), content (every identifier is checked against the minimum-necessary map before execution, so aliasing a column does not get you past it), output (masked again on the way out), volume (a hard row cap) and attribution (every query, accepted or refused, lands in the audit chain).

Query

05 · The surface

API

Every endpoint resolves to a principal with a role and a stated purpose of use before a handler runs — nothing touches data anonymously, because an audit trail that cannot name the actor is decoration. The same request returns different fields to different roles; that is the policy engine, not per-endpoint branching.

Endpoints

MethodPathRolesWhat it does
06 · Minimum necessary

PHI governance

The policy is data, not code. Every column the API can emit has a row in phi_field_map giving its classification, which of the 18 HIPAA identifiers it is, how it is degraded, which roles may receive it and which roles receive it unmasked. A column with no row is never emitted — so adding a column to a table cannot silently leak it.

That means compliance can read and change the policy without reading C#, and the same record renders differently for every role with no per-endpoint branching. Here is one patient, as each role receives them:

One record, five roles

GET /api/patients

Field map

Audit chain

Append-only. Each event stores the SHA-256 of the previous hash plus its own canonical body, so editing or deleting any row breaks every hash after it. The table also carries BEFORE UPDATE and BEFORE DELETE triggers that abort — tampering has to go around the database engine rather than through it. Events record the purpose of use and exactly which PHI fields were released.

07 · Translation

How this maps to UiPath

This is a .NET implementation of the patterns I deliver in UiPath Studio and Orchestrator. The shapes are deliberately one-to-one, so the code is readable as a REFramework process by anyone who works in that stack.

UiPath conceptHereWhy it matters
REFramework states
Init / Get / Process / End
JobRunner.Run() Same four phases, same guarantee: a crash mid-transaction leaves the queue item claimed and recoverable rather than lost.
Orchestrator queues queue_item Status, priority, retry count, deadline, postpone window, and a unique reference. Dispatch is INSERT OR IGNORE on that reference, so re-running a dispatcher after a crash cannot create duplicate work.
Dispatcher / performer IAutomationProcess Split, as they should be: the dispatcher finds work in one indexed query, the performer does one transaction and knows nothing about batching.
Business rule exception BusinessRuleException Never retried, and carries the disposition so the item lands in the right human queue instead of silently staying open.
System exception AutomationSystemException Retried with exponential backoff up to the per-queue budget, then abandoned to triage with the error code intact.
Config.xlsx asset Thresholds, batch sizes and backoff live as assets, snapshotted into the run record — so "why did it behave that way last Tuesday" is answerable.
Credential assets asset.credential_ref The database stores the name of a secret, never a value. The robot resolves it from the host secret store at run time and holds it in memory only.
Robot identity process_definition.robot_identity Each process runs as its own least-privilege service account, and that identity is what the audit trail records — not a shared "RPA" login.
Orchestrator logs run_log Stage, level, item reference, duration. Redaction happens on the way in, so a developer cannot forget it — logs are where PHI most often escapes a bot.
Triggers & schedules process_definition.schedule_cron Cron and queue triggers are declared with the process, alongside its SLA and owning team.
Action Center match_candidate The human-in-the-loop task carries the full feature breakdown, not just a score, so the reviewer can audit the robot's reasoning.

What I would do differently in a real deployment

  • SQL Server rather than SQLite, with the same schema — the DDL is deliberately portable and the views carry the reporting logic.
  • Entra ID app registrations and managed identities instead of API keys. The roles and the field map do not change; only the authentication in front of them does.
  • Orchestrator holds the queues, assets and schedules; this database keeps the domain tables and the audit chain.
  • Alerts on queue age and first-pass yield, not just on run failure — a bot that fails loudly is easier to support than one that succeeds at doing nothing.

Where AI assistance fits, and where it does not

I use AI assistants daily for scaffolding, refactoring, test generation and documentation, and this project was built that way. The discipline around it is the part that matters: synthetic data only, never real PHI or production credentials in a prompt; generated code reviewed line by line before it is committed; tests written to pin the behaviour rather than to describe what was generated; and a human named on every production change.

The concrete win here was the denial playbook. The rules are data, so most of the work was getting the classification right rather than typing branches — and the test suite for the exception taxonomy was written first, which is what caught a retry path that would have re-submitted corrected claims twice.

08 · Who built it

Addison Toscani

Automation and software engineer. Six years building and supporting enterprise automation as an Automation Integration Tech Lead — UiPath Studio and Orchestrator, attended and unattended, REFramework delivery from process assessment through production support — on top of a computer science degree and a long C++ background.

What I actually enjoy is the unglamorous half: reading the logs of a bot someone else wrote, finding why it fails at 3am, and fixing the cause rather than the symptom.

Everything on this page is running code. The API, the database, the automation framework and the 98-test suite are in the repository that ships with it, and it starts with dotnet run.

This build

Stack
.NET 8 minimal API, ADO.NET over SQLite, no ORM — the SQL stays visible and reviewable
Database
13 tables, 3 reporting views, append-only audit with database-level immutability triggers
Processes
Denial rework, patient record matching, eligibility verification
Tests
98 assertions, no third-party runner — clone and run
Data
100% synthetic, deterministically generated