Home  /  Projects  /  Applicant Reminder Automation ← All six case studies

In plain English: Reminders for applicants who had not sent a requested document had to be assembled by hand from three separate systems. I joined that data on the case barcode and turned the reminder run into one reviewed batch — while a person still decides who should receive one.

PORTFOLIO CASE STUDY

APPLICANT REMINDER AUTOMATION

Building a Controlled Batch-Reminder Workflow for Missing-Document Cases

A Google Sheets and Google Apps Script workflow that joins three client data feeds, prepares personalised applicant reminders, and sends them in one reviewed batch — with the decision to send left deliberately in human hands.

Prepared byKhaled Medhat — Team Leader, Case Validation
EnvironmentGoogle Workspace — Google Sheets and Google Apps Script
StatusBuilt August 2025 — in continuous use since
UsersBuilt and operated by me, and used by two performers who work with me
Date of this documentOctober 2026

A. Executive Snapshot

Business problemA new client in education-document verification went live without the follow-up feature the standard workflow relies on: when an applicant has not sent a requested document, no automatic reminder reaches them after the first insufficiency email. Reminders were prepared and sent by hand, one applicant at a time, from data held in three separate client exports.
My role and contributionI designed the workflow end to end: the three-source join, the barcode key, the two-tab sheet structure, the personalised email template, the validation rules, the send-state controls and the three-day operating routine. I used AI as the implementation partner to write and revise the Apps Script, evaluated the generated code against my specification, tested it against live data, and have maintained the workflow ever since. The client system and the internal API were existing services; my contribution was the reminder workflow built around them.
Solution developedA Google Sheets workflow with a main working sheet and an email sender tab, driven by a Google Apps Script. One barcode typed into the working sheet populates the applicant's name, address and requirement by formula. A "Send Emails" button on the sender tab sends the queued reminders as one batch, marks each row done, and writes the reminder date back to the working sheet.
Methods and toolsGoogle Sheets (tabs, formulas, button), Google Apps Script (retrieval, joins, template population, batch send, state write-back), Gmail sending with deliberate per-message pacing, three existing internal API feeds, AI-assisted development under my specification and validation.
Project statusBuilt August 2025 and still in regular use in October 2026 — roughly fourteen months of continuous operation on a three-day reminder cycle.
Verified outcomesEffort per reminder cycle reduced from an estimated full employee-day of manual preparation and sending to one reviewed button press and about five minutes of machine time. A typical run sends 250–300 reminders; the pending queue ranges from roughly 150 to 500 cases. Manual-effort and volume figures are owner-reported estimates, not audited measurements.
Important limitationsNo delivery or bounce rate was recorded, and no applicant-response rate was measured, so the business effect on case turnaround is expected rather than demonstrated. "Done" records send processing, not arrival. The client, applicants, cases and barcodes are not identified anywhere in this document, and the sheet views shown are labelled reconstructions.

Contents

  • B — Executive summary
  • C — Business context and problem definition
  • D — Data discovery and root cause analysis
  • E — Solution design and AI-directed development
  • F — Project management and implementation
  • G — Preventive improvement and controls
  • H — Testing and validation
  • I — Business impact and performance measurement
  • J — Lessons learned and future roadmap
  • K — Skills demonstrated

B. Executive Summary

A client in education-document verification went live without the feature our other clients have. In the standard workflow an applicant receives an insufficiency email when we need a document they have not sent, and if nothing arrives about three days later they receive a reminder. For this client that follow-up did not exist, so every reminder was written and sent by hand.

The hard part was never the wording. It was the assembly. To send one correct reminder I needed three things that lived in three separate exports: who the applicant is and where to reach them, which of their cases is still waiting for a document, and the exact requirement that was communicated to them. The case barcode was the only thing those records had in common. Every reminder therefore started as a manual search across three files, and every one of them was an opportunity to reach the right person with the wrong requirement.

I built a workflow around that join. A Google Apps Script retrieves the three feeds into a Google Sheet, and a barcode typed into the main working sheet pulls the applicant's name, email address and requirement into place by formula — no copying, no re-typing. A second tab, the email sender tab, lists the cases to contact and carries a "Send Emails" button. Pressing it sends the whole list as one batch, writes "Done" against every row it sent, and records the reminder date back on the working sheet. A typical run covers 250–300 applicants and takes about five minutes; the work it replaces took close to a full working day of preparation and individual sending.

One part of the design I deliberately did not automate. Deciding whether a reminder is still required stayed a human decision, because a reminder that is no longer needed is a needless contact with an applicant. The script decides nothing about eligibility: I read the queue, check the last-reminder date on each case, queue the barcodes that are still due, review the list, and then press the button. Three days is the rhythm I work to, not a rule the script enforces.

The workflow was built in August 2025 and has run continuously since. It is used by me and by two performers who work with me. What it changed is the effort and the consistency of the contact, not the size of the queue — and I can demonstrate the first, while the second I can only state as an expectation until delivery and response data are captured.

C. Business Context and Problem Definition

The process that had to be worked around

Our operation verifies education documents for institutional clients. When a document is missing, the applicant is told what is needed through an insufficiency email. On the clients whose systems carry the follow-up feature, the system then watches for the upload and, if nothing arrives, sends the reminder automatically about three days later. The applicant receives two contacts and the case moves forward without anyone chasing it.

This client went live without that feature. The insufficiency email still went out, because that is part of our own operation, but nothing followed it. The reminders that the client system would have sent became our job, and the only way to send them was one at a time, by hand.

The manual baseline

Preparing and sending one cycle of applicant reminders took close to a full employee-day. The work consisted of pulling the three exports, matching them case by case on the barcode, reading the requirement that had been communicated to the applicant, composing the message around that requirement, and sending it individually — then repeating the whole sequence for the next case. I am reporting that as an estimate based on my own recollection; it was not measured with a time study, and I would not present it as an audited figure.

Two things made it worse than a simple time cost. First, the three sources were joined by eye, so a requirement could be attached to the wrong applicant. Second, because each contact was sent individually, the effort scaled directly with the number of pending cases — and the pending queue for this client routinely sits between roughly 150 and 500 cases.

Who was affected

Constraints and the decision to build in parallel

The client system and the internal API belonged to the company and were out of scope: I could not add a follow-up feature to the client system, and changing the API was not on the table. The solution had to work inside the Google Workspace environment the operation already used, and it had to read the data those systems already exposed rather than replace them. Building the workflow alongside the platform, rather than waiting for the platform to change, was the practical decision — with the trade-off that the automation lives in a spreadsheet rather than inside the system of record, and therefore depends on the data it reads being current. Figure 1 sets the two cycles side by side.

RECONSTRUCTED PROCESS DIAGRAMFigure 1
Current state — reminders prepared by hand Read three client exports for the pending cases Match the three records to each other, case by case Read the requirement and compose the message Send to one applicant, then repeat for the next Record by hand which cases were contacted Failure points: hand-joined records, one-at-a-time sending, no automatic contact log Future state — the reminder workflow Script retrieves the three feeds into the sheetno manual export handling One barcode typed in; name, address and requirement fill in by formulathe barcode is the only manual entry I review the list of cases still due and press Send Emailsthe eligibility decision stays with me One batch sends 250–300 messages, paced at ~1 second each~5 minutes for a full run, paced to protect the sending channel Each row marked Done and the reminder date written backa repeat run cannot contact the same case twice Controls: blank record skipped · done-flag guard · reminder history · human trigger

Figure 1 — The manual reminder cycle and the workflow that replaced it, reconstructed from the operating process. Failure points on the left, controls on the right.

D. Data Discovery and Root Cause Analysis

Before designing anything I compared what the three exports held and how a single case appears across them. That comparison produced the causal chain the whole project rests on.

SymptomContributing factorHow the workflow addresses it
Reminders took close to a working day per cycleThe content of one reminder was assembled by hand, case by caseOne barcode entry replaces the per-case join; every other field is formula-driven
Effort scaled with the queue, and the queue ran from ~150 to ~500 casesEach applicant was contacted individually, in sequenceOne batch covers 250–300 applicants in about five minutes
A requirement could be attached to the wrong applicantThree exports joined by eye, with the barcode as the only shared keyThe barcode drives a single lookup, so name, address and requirement come from the same case record
Nothing recorded who had actually been contactedNothing in the working view recorded who had been contactedA Done flag per row and a reminder date per case in the working sheet
An incomplete message could reach an applicantNothing stood between a partially populated record and the send buttonRows with a missing name, address or requirement are skipped and never sent
The follow-up stopped when the client feature was missingThe client system carried the reminder step for other clients, but not for this oneThe workflow reproduces that step on our side, on our data, without changing the client system

The root cause

The root cause was structural, not behavioural: the reminder content lived in three disconnected exports, and the case barcode was the only key they shared. That is what made the manual work heavy and what made it risky — not the speed of the team, and not the behaviour of applicants. The client system could not carry the follow-up step for this client, so the join had to be made and the send had to be performed on our side.

Two explanations that might be expected here are worth ruling out explicitly, because they are not the cause. The team was not slow: the effort per case was seconds of work repeated hundreds of times, which is a scaling problem rather than a performance problem. And applicants are not unresponsive by nature: the workflow changes the frequency and consistency of contact, but whether a given applicant responds is outside what this project can claim.

One explanation was considered and deliberately not adopted: a fully scheduled sender, which would remove the human step entirely. I rejected it for a stated reason rather than by default — an automated scheduler cannot tell whether a reminder is still required, and an unnecessary reminder is an unnecessary contact with an applicant. That trade-off shaped the design more than any other decision in the project.

How far the analysis goes. The causal chain above is supported by the structure of the data, by the observed join, and by the fact that the intervention is a data join. The effort figures that attach to it are my own estimates of past work, not measurements, and no time study separates reading, composing and sending.

E. Solution Design and AI-Directed Development

I wrote the specification before any code existed, because the specification was the part I owned and the code was the part I could produce quickly with AI. The specification had six elements:

  1. Inputs — three client feeds: applicant details (barcode, name, email address), cases still awaiting a document upload, and the insufficiency comment that states the requirement.
  2. Join key — the case barcode, entered once, with every other field resolved by formula from the same case record.
  3. Working structures — a main working sheet that holds the case record, and an email sender tab that holds what is to be sent and what has been sent.
  4. Template variables — applicant name, requirement text, and the barcode in the subject line, so every message carries the case it belongs to.
  5. Validation rules — a row with a missing name, address or requirement is skipped rather than sent.
  6. State write-backs — a Done flag on the sender tab and the reminder date on the working sheet, so a second run cannot contact the same case again.

How the workflow is put together

The script retrieves the three feeds into the sheet. A barcode typed into the working sheet triggers a formula lookup that returns the applicant's name, email address and requirement from the same case record. The email sender tab pulls the name and address onto each row and carries a "Send Emails" button. Pressing it walks the list, substitutes the variables into the template, sends each message, marks the row Done and writes today's date into the reminder column on the working sheet. Because every field is resolved by barcode, the same case cannot pick up another case's requirement. Figure 2 traces that path from the three feeds to the sent message and back to the state written on the sheet.

RECONSTRUCTED ARCHITECTURE DIAGRAMFigure 2
Existing client data sources Feed 1 — applicant detailsbarcode · applicant nameapplicant email address Feed 2 — pending uploadscases where the requesteddocument is still not uploaded Feed 3 — insufficiency commentthe requirement communicatedto the applicant Existing company services — not built or modified by me Google Apps Script • retrieves the three feeds • populates the sheet fields • fills the template variables • sends the batch, paced ~1 s/email built with AI against my specification Built and maintained by me Main working sheet barcode · start date · requirement number of reminders · date of last reminder applicant name · applicant email the barcode is the only manual entry Email sender tab applicant name · barcode applicant email email status — done / not done Send Emails the send trigger Batch send 250–300 messages ≈5 minutes per run name and address resolved by barcode Human decision • I read the pending queue • I check the last-reminder date • I queue the barcodes that are due • I review the list and press Send Emails The script decides nothing about eligibility. Validation guard Rows with missing data are skipped and never emailed. Skips are not logged today — a named next step. Write-back after every send: a Done flag on the sender tab, and today's date in the reminder column of the working sheet.

Figure 2 — Data flow and state write-back for the reminder workflow, reconstructed from the built system.

The sheet and the template

The working sheet is deliberately plain. The main tab carries the case record — barcode, start date, requirement, number of reminders, date of last reminder, applicant name and applicant email — and the email sender tab carries what is queued and what has been sent. Only the barcode is entered by hand; the applicant name, address and requirement resolve by formula from the same case, and the sender tab pulls the name and address across by barcode. The Send Emails button sits on the right of the sheet.

Figure 3 shows the two tabs as they work, and Figure 4 shows the message it produces. The message is a fixed template with three variables. The name opens the greeting, the requirement states what is still needed, and the barcode in the subject line ties the message to the case without anyone having to retype it. The body stays constant so no message can accidentally omit the request.

ILLUSTRATIVE MOCKUP — SYNTHETIC DATAFigure 3

Main working sheet

barcodestart daterequirementnumber of remindersdate of last reminderapplicant nameapplicant email
CASE-2025-104822025-08-12Certified transcript issued by the university12025-08-15Sample Applicant 01applicant01@example.com
CASE-2025-107332025-08-13Official equivalency certificate22025-08-19Sample Applicant 02applicant02@example.com
CASE-2025-110902025-08-14Signed copy of the secondary certificate0—Sample Applicant 03applicant03@example.com

Seven columns. The barcode is the only manual entry; every other cell is a formula. Names, addresses and barcodes shown here are synthetic.

Email sender tab

applicant namebarcodeapplicant emailemail status
Sample Applicant 01CASE-2025-10482applicant01@example.comdone
Sample Applicant 02CASE-2025-10733applicant02@example.comnot done
Sample Applicant 03CASE-2025-11090applicant03@example.comnot done

Four columns. The name and address are pulled from the working sheet by barcode; the status is written by the script after each send.

Figure 3 — The two working tabs, reconstructed from the live structure. The live sheet cannot be captured for this document, so every value shown is synthetic.

ILLUSTRATIVE MOCKUP — SYNTHETIC DATAFigure 4
To: applicant01@example.com
Subject: Required document for case {{barcode}}

Dear {{applicant name}},

We are following up on a document we asked you to submit for the above case. Our records show that we have not yet received it.

What we still need from you:
{{requirement}}

If you have already sent it, or if you believe you do not need to send it, please reply to this message so we can check the case and close it.

Kind regards,
Verification Operations Team

Figure 4 — The reminder template. The structure and the three variables are faithful to the built message; the surrounding wording is representative and the data is synthetic.

How I used AI to build it

I used AI as the implementation partner for the Apps Script, and I kept the judgement that the script could not make. The sequence was consistent throughout the project: I wrote the requirements, the join logic, the tab structure, the template variables and the validation rules; I asked for the script that implemented them; I read the generated code against my specification rather than accepting it; I tested the behaviour against live data; and I directed the revisions until the script did what I had specified. The specification was the part I owned, and the specification was where the real decisions sat — the join key, the three-day rhythm, the point where a person stays in the loop, and the rule that an incomplete record is skipped rather than sent.

That division is what made the workflow maintainable. Because the rules live in a written specification and a sheet, a change in behaviour is a change in the specification first, and the script follows it.

RECONSTRUCTED PROCESS DIAGRAMFigure 5
1 · Specify I write the requirement,the join key, the tabstructure and the rules 2 · Generate AI writes the Apps Scriptthat implements thespecification 3 · Evaluate I read the code againstthe specification and theoperating rules 4 · Revise I direct the changesuntil the behaviourmatches the intent 5 · Validate I test against live data,run it in the cycle, andkeep it working the specification changes when the operating rules change — the script follows it

Figure 5 — The directed-development loop used to build and maintain the workflow.

Two engineering decisions worth naming

Pacing the send. The script sends one message per second, so a 250–300 message run takes about five minutes. That is deliberate: sending faster risks being throttled or blocked by the sending channel, and a run that fails halfway is worse than a run that takes five minutes. The pacing is the reason a full batch is safe rather than merely fast.

Skipping rather than sending. A row with a missing name, address or requirement is skipped and no message goes out. The alternative — sending a partially populated message — would put an incomplete request in front of an applicant and waste the contact. The skip is silent today, which is a weakness of the design and is listed as a next step in section J.

F. Project Management and Implementation

PhaseWhat happenedWhat it produced
Gap identificationThe client went live without the client-side follow-up feature, and the reminder step fell back to the team.A decision to solve it on our side rather than wait for the platform
SpecificationThe join key, the two tabs, the template variables, the validation rules and the state write-backs were written down first.A written specification that the script was built against
BuildGoogle Apps Script and Google Sheets implemented the specification, with AI as the implementation partner.A working sheet, a sender tab and a Send Emails button
First cyclesThe workflow was run on the real pending queue and the behaviour was checked against the specification.Confirmed join, skip rule, Done flag and date write-back
Steady stateAugust 2025 onwards: a three-day cycle, run by me, with two performers working from the same sheet.Continuous operation for roughly fourteen months

Scope decisions

Risks and how they were handled

RiskHow it was handledResidual exposure
Contacting an applicant who no longer needs the reminderThe send trigger is manual; eligibility is never decided by the scriptThe guarantee depends on a person running the cycle on time
Sending a requirement that belongs to another caseEvery field resolves from one barcode lookup, so a case cannot borrow another case's fieldsA stale source feed could still pair a correct requirement with an outdated case state
Sending a message with missing detailsRows with a blank name, address or requirement are skippedSkipped rows are not logged, so a silent skip can go unnoticed
Sending the same case twiceThe Done flag is written after each send and is checked before a row is processedA row deliberately re-queued for a second reminder must be cleared by hand
The run being throttled or blocked part-wayPaced at about one message per secondA run interrupted by a failure has no automatic resume, and no skip log
The sheet being read in a state where a queued row is out of dateNothing — this control is not builtListed as the first next step in section J

Adoption and continuity

The sheet and the reminder bot are used by me and by two performers who work with me. The people preparing the reminders are the same people who can see the queue, and working from one sheet kept the operating routine common. The workflow has run without interruption since August 2025, and the maintenance load is low because the rules are visible in the sheet and the script follows a written specification.

RECONSTRUCTED TIMELINEFigure 6
August 2025built and first cycles run Late 2025three-day cycle established 2026continuous use, performers on the same sheet October 2026still in regular use Approximately fourteen months of continuous operation, one reminder cycle every three days

Figure 6 — The build and the period of continuous use. Only two dates are known: the build in August 2025 and the present; the intermediate points are reconstructed from the operating history.

G. Preventive Improvement

Most of the value in this project is preventive. It is not in how fast a message goes out; it is in the errors that can no longer happen, and in the one error that was designed out on purpose. Figure 7 sets out every control in the workflow, and separates the six that are built from the four that are not.

RECONSTRUCTED CONTROL MATRIXFigure 7
ControlWhat it preventsStatusHow it works
Human send triggerContacting an applicant who no longer needs a reminderImplementedEligibility is never decided by the script. I review the queued cases and press the button.
Barcode-keyed joinA requirement being sent with another case's detailsImplementedName, address and requirement resolve from one lookup on the same case.
Required-field checkAn incomplete message reaching an applicantImplementedA row missing the name, address or requirement is skipped and not sent.
Done flagThe same case being contacted twice in a cycleImplementedWritten after each successful send and checked before a row is processed.
Reminder date write-backLosing track of when a case was last contactedImplementedThe date is written to the working sheet and is the reference used to decide what is due.
Send pacingThe run being throttled or blocked part-wayImplementedAbout one message per second, so a 250–300 run completes in roughly five minutes.
Skip logA silently skipped case going unnoticedProposedNot built. A reason column on the sender tab would make every skip visible.
Stale-row checkSending from a row whose source data has since changedProposedNot built. A timestamp on the retrieved data would flag a row queued before the last refresh.
Delivery checkAn undeliverable address going unnoticedProposedNot built. It needs a bounce or delivery log that the current send does not produce.
Suggested-due listA due case being missed because the operator overlooked itProposedNot built. A read-only list of cases past three days, proposed but never sent, would help without removing the human decision.

Figure 7 — Controls in the built workflow and the controls identified but not built. The last four are named in section J as the next improvements.

The control that mattered most

Automating eligibility was the obvious next move, and I did not take it. The reason is worth stating in the company's own terms: a reminder that is not required is not a neutral message — it is an unnecessary contact with an applicant who is already waiting on a decision about their own documents. The cost of that error falls on the applicant, and it cannot be detected by a script that has no view of whether the request is still live. So the design keeps the assembly and the sending automatic, and keeps the judgement with the person who can see the case.

The controls below that judgement rather than replace it. The Done flag and the reminder date make a run safe to repeat; the required-field check makes an incomplete record impossible to send; the barcode join makes a mismatched message improbable; and the pacing makes a full run dependable.

Where the design does not yet protect, it should be said plainly. The workflow prevents unnecessary contact, mismatched content and duplicate sends. It does not currently detect a stale row, a silent skip, or a failed delivery — three of the four remaining risks in the matrix above — and it does not measure whether the contact actually changes the outcome for the applicant.

H. Testing and Validation

Validation here was practical rather than formal: the workflow was exercised on the live pending queue and its behaviour was checked against the written specification, cycle after cycle, over roughly fourteen months. There was no test suite, no regression set, and no formal sign-off record, and I am not going to present continuous use as a substitute for one.

BehaviourHow it was checkedResult
A barcode resolves the correct caseComparing the populated fields against the source records for a set of live casesConfirmed in use; the name, address and requirement come from the same case record
Incomplete records are not sentObserving the sender tab where a record was missing a required fieldConfirmed in use; the row is skipped and no message is produced
A repeated run does not resendRe-running against a list that had already been sentConfirmed in use; rows marked Done are not processed again
The reminder date is recordedChecking the working sheet after a runConfirmed in use; the date is written back and is the reference for the next cycle
The batch survives full volumeRunning at the typical 250–300 sizeConfirmed in use; the run completes in about five minutes at one message per second
Message content is correctReading the sent messages against the case recordConfirmed by review; the template has three variables and no free text
What is not tested and not known. There is no delivery or bounce record, so a message that failed to arrive is indistinguishable from one that arrived. There is no skip log, so a skipped row cannot be counted. There is no regression set, so a change in the template or the rules is not automatically verified against previously correct behaviour. A message that arrives and produces no applicant response is also invisible to the workflow.

The test set I would build next

These are proposed tests, not executed ones, and they are small enough to run on a copy of the sheet:

Test caseExpected resultAcceptance rule
A barcode with a complete recordName, address and requirement populate; the row appears on the sender tabAll three fields match the source record
A barcode whose record has a blank requirementThe row is excluded from the send list and no message is producedNo message produced, and the skip is visible in a log
A barcode with no matching caseNo fields populate and the row is not queuedNo message produced, and the row is flagged for review
A second run over an already-sent listNo message is produced for rows marked DoneZero duplicate sends
A queued row whose source data is older than the last refreshThe row is flagged before sendingA stale row is never sent silently
A run interrupted part-wayThe remaining rows are identifiable and can be resumedNo case is sent twice and no case is silently dropped

I. Business Impact and Performance Measurement

MetricBaselineResultEvidence statusValidation method
Effort to prepare and send one reminder cycle≈ 1 employee-dayOne reviewed button press; ≈ 5 minutes of machine timeEstimated (owner-reported) / ReportedA 30-minute time-and-motion sample of one manual cycle would convert the estimate into a measured baseline
Reminders sent per runOne applicant at a time250–300 in a single runReportedCount of Done flags on the sender tab
Machine time per runNot applicable≈ 300 seconds, paced at ≈ 1 s per messageReported / ObservedScript execution log
Pending cases awaiting a document≈ 150 to 500 cases≈ 150 to 500 casesReportedPending-document feed; the workflow changes the effort, not the queue
Records assembled per reminderThree sources joined by hand per caseOne barcode entry; every other field formula-drivenDocumentedInspection of the tab structure
Records with missing dataNot applicableSkipped; no message sentDocumentedA deliberate blank in a test copy, with a skip log
Repeat sends within a cycleNot applicablePrevented by the Done flagDocumentedRun twice against a test list
Delivery to the applicant's inboxNot recordedNot recordedNot measuredMail service log — proposed
Applicant response within three days of a reminderNot measuredNot measuredNot measuredCompany case system joined to send records — proposed
Share of due reminders sent inside the three-day windowNot measuredNot measuredProposed KPISend dates against the reminder date on the working sheet
Cases closed within the cycleNot measuredNot measuredProposed KPICompany case system — proposed
ESTIMATE — OWNER-REPORTED, NOT AUDITEDFigure 8
Effort to run one reminder cycle Before — prepared and sent by hand ≈ 1 employee-day (8 hours) After — one reviewed batch ≈ 5 minutes (300 seconds) — about one hundredth of the manual effort 02 h4 h8 h What this comparison does and does not show • The manual figure is my own estimate of past work, not a timed measurement; the automated figure is the observed run time of a full batch. • It compares preparation and sending effort only. It says nothing about the number of cases in the queue, which is unchanged by the workflow. • It is not a headcount, cost or capacity claim, and it is not added to any other estimate of saved effort elsewhere in the operation.

Figure 8 — Manual preparation and sending effort compared with the runtime of one batched cycle. The baseline is an owner-reported estimate and is labelled as such on the figure.

What the business case still needs

The effort comparison is the part of this project I can defend, and it is enough to justify the work on its own. The stronger claim — that continuous, correctly timed contact gets documents to applicants faster — is not yet supported by anything I can point to, because the workflow does not record whether a message arrived or whether the applicant responded. Three measurements would close that gap, and each has a simple source:

KPIFormulaData sourcePeriod and target
Application rateReminders sent ÷ reminders that were dueSender tab and pending-document feedPer cycle; a complete cycle is the target
Cycle adherenceReminders sent within 3 days of the last reminder ÷ reminders dueReminder date column against run datesPer cycle; target set after the first four cycles
Response within the cycleUploads ÷ reminders sent, within 3 days of the reminderCompany case system joined to send recordsPer cycle; establishes the outcome effect

Until those exist, the correct statement of the outcome is the one I make in the summary: the workflow removed close to a full employee-day of repetitive preparation and sending per cycle and made the contact consistent, and the effect on case turnaround is an expectation rather than a measured result.

J. Lessons Learned and Future Roadmap

What I learned

What I would build next

None of these is built today. They are the design I would take to the next version, and each one is deliberately small: the workflow earns trust by being predictable, and that is worth protecting.

K. Skills Demonstrated

CompetencyMy contributionSupporting evidenceBusiness or technical value
Requirements definition and business analysisTurned "remind applicants about missing documents" into a specification: three inputs, one join key, two tab structures, three template variables, a validation rule and two state write-backsWritten specification; the sheet structure; the templateThe specification is what makes the workflow reproducible and maintainable by someone other than its author
Root cause analysisIdentified the structural cause — reminder content split across three exports with only the barcode as a shared key — and ruled out the obvious explanations of team speed and applicant behaviourComparison of the three feeds; the join design that followedPrevents solving the wrong problem, and explains why the design is a join rather than a mail merge
Systems and workflow designDesigned the full path from barcode to sent message, including the review step, the skip rule and the state write-back that makes a repeat run safeThe live workflow; the control matrixReplaces a manual cycle with one that is repeatable, auditable and safe to re-run
AI-directed developmentSpecified the behaviour, used AI to write and revise the Apps Script, evaluated the generated code against the specification, tested it against live data, and directed the changesThe specification and the built scriptDelivered a working system inside the Google Workspace environment the operation already used
Risk judgement and control designKept the send trigger human to prevent unnecessary applicant contact, and added the checks that make an automated message safe to sendThe trigger decision; blank-field skip; Done flag; pacingProtects the applicant relationship, not just the process — the cost of a wrong reminder falls on the applicant
Operational process managementRan and maintained a three-day cycle for roughly fourteen months, and kept two performers working from the same sheetContinuous operation since August 2025Turns a workflow into a routine that survives without constant attention
Data analysis and measurementEstablished the operating scale of the queue and the cycle, and identified precisely which measures do and do not existVolume and runtime figures; the KPI plan in section ISeparates what the project achieved from what it still needs to prove
Confidentiality and responsible disclosureKept the client, applicants, cases and barcodes out of the published material, and labelled every visual as a reconstructionThis document; the status labels on every figureThe case study can be shared publicly without exposing the client or any applicant

How the competencies combine

The project is not a collection of skills applied in sequence; it is one chain. Business analysis produced the specification, the specification made the AI-directed development possible, the development produced controls that made the workflow safe to run every three days, and the operating routine is what turned a script into something with fourteen months of continuous use. The root cause analysis is the hinge: it is the reason the work was a data join rather than a mail merge, and the reason the control set is shaped around what a script cannot know — namely, whether a reminder is still required.

Note on data and evidence. The client, applicants, cases and barcodes are not identified in this document. Figures marked as owner-reported are my own estimates or recollections and were not independently audited; figures marked as observed come from the running system. Every figure in this document is labelled with its status: reconstructed process diagram, reconstructed architecture diagram, reconstructed control matrix, reconstructed timeline, illustrative mockup with synthetic data, or an owner-reported estimate. No screenshot of the live sheet appears, because the live environment cannot be captured for publication; the sheet and message views shown are faithful reconstructions of the documented structure with synthetic values, and the three API feeds and the client system were existing company services that I did not build or modify.

Prepared by Khaled Medhat — Team Leader, Case Validation — October 2026.