Skip to content

bedardandy/AR_RPA

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

Annual Report Automation: Multi-Variant Browser RPA Against a Government Portal

A case study in production Power Automate development for a regulated industry. Anonymized writeup of a pipeline I designed and built in early 2025 to draft and stage several hundred Maine annual reports per filing season for a law firm's 1,000+ entity registered-agent book.

Executive summary

  • Problem: recurring annual-report drafting across a large registered-agent book, with multiple entity-type variants, no submission API, and a high-liability review boundary.
  • Scale: 1,000+ entities in the registered-agent book; several hundred annual-report drafts per filing season.
  • Stack: Power Automate cloud flows, Power Automate Desktop attended UI automation, SharePoint/Excel registry, Word mail merge, Outlook, iManage.
  • My role: designed and built the registry, entity-type routing, attended desktop workers, exception handling, logging, and downstream mail-merge handoff.
  • Key constraint: the automation drafts and stages packages for attorney/client review; it deliberately does not auto-submit legal attestations.
  • Outcome: reduced clean-case review to roughly one minute per drafted package while improving registry data quality and auditability.

Disclaimer: This writeup describes a system I designed and built professionally. It contains no client information, no proprietary code, no credentials or selectors, and no employer-specific configuration details. The architectural patterns are documented at a level appropriate for portfolio review: concrete enough to be credible, abstract enough to keep both client confidentiality and operational details intact.

Problem

Every commercial law firm that serves as registered agent for corporate clients has the same recurring problem: state annual report filings. Each entity must file, the deadlines are staggered, the data largely doesn't change year to year, but each filing requires:

  1. Logging into the secretary of state portal
  2. Looking up the entity by name or ID
  3. Clicking through a multi-step contact wizard
  4. Confirming or updating directors, officers, registered agent, principal office address
  5. Reviewing the draft
  6. Saving for attorney review (the firm doesn't auto-submit; attorneys sign off)
  7. Triggering downstream client communications: notices, invoices, cover letters, and in some cases corporate minutes

Manually, each entity takes 5-10 minutes. At the volume in question (several hundred drafts concentrated in spring filing season) this works out to hundreds of hours of paralegal time per year, with high error rates and a limited audit trail.

Before the automation, the firm tracked these filings the way most small-to-mid law firms do: a sprawl of Excel spreadsheets, plus a handful of Word documents with tables that loosely emulated those spreadsheets. Data was siloed by registered agent. Each clerk or attorney serving as registered agent maintained their own files, with no shared schema, no validation, and no enforced fields. There was no CRM, no contact-management system, and no centralized database. Building any kind of automation meant first building the registry itself.

Constraints

I built this in early 2025, and the tooling envelope (both internal and external) shaped every architectural decision that follows.

Internal stack. The firm ran on Microsoft 365 Business Standard, with on-premise iManage as the document management system and Outlook as the communications layer. I was issued a Power Automate Premium license, which unlocked Power Automate Desktop, and that was the toolbox. Anything outside that envelope was off the table: no third-party RPA platforms, no paid API services, no external databases.

iManage was effectively read/write only via the GUI. iManage exposes APIs, but our support vendor required a certified developer to perform any integration work, and the firm was not going to retain one for this project. So although iManage held the source-of-truth client documents, I had to drive it through its desktop UI rather than programmatically. That constraint pushed certain document-handoff steps back to attended execution.

No unattended license. I did not have an unattended ("robot") license. The flow ran attended, on my own workstation, during the workday. I couldn't kick off a batch overnight and walk away. That changed the throughput target (what can finish during a normal workday while a paralegal is also using the machine) and pushed the architecture toward small, idempotent, resumable units of work rather than a single long-running job.

External: no submission API on the state's end either. Maine's filing portal is InforME. The read side does have structured export: I can pull a CSV/TSV roster of every entity that lists a given registered agent, with charter number, status, and appointment date, which is genuinely useful for keeping the registry in sync. The submission side has nothing equivalent. No POST endpoint, no XML or CSV batch upload, no programmatic filing path of any kind. The two sanctioned ways to submit a filing are the web wizard itself, or a printed paper form mailed in with a check (with a multi-week processing window and meaningfully higher per-filing cost). Browser automation against the wizard was the only digital filing path available.

Several choices in the architecture below are constraint-driven rather than ideal. SharePoint as the registry is the most prominent example: I wouldn't design a system of record around a SharePoint list from scratch, but it was the closest thing inside the license envelope, with native Power Automate connectors. Without it, the project doesn't ship in a single season. (See "What I'd do differently" for what I'd choose with more freedom.)

Why this is a non-trivial RPA problem

The naive framing, "just automate the form fill," misses several real constraints:

The portal is a legacy government web application. Maine's filing portal (InforME) provides structured CSV/TSV roster exports on the read side, but the submission side has no API of any kind. The only digital filing path is the web wizard, with paper-and-postage as the sole alternative. Forms render server-side, with HTML tables that vary subtly based on entity type. Some fields appear conditionally based on prior selections. Session state is fragile. Common error modes include rate-limiting on the unauthenticated path, session timeout mid-flow, and silent UI changes between filing seasons.

Eight-plus entity-type variants. Maine alone has Domestic Business Corporation, Foreign Business Corporation, Domestic LLC, Foreign LLC, Domestic Nonprofit, Foreign Nonprofit, Limited Partnership, Limited Liability Partnership, and several less common types. Each has a different wizard flow, different required fields, and different validation rules. There are also per-type quirks worth knowing: nonprofits, for example, do not have their brief statement of business character carried forward from the prior year's filing, even though every other entity type does. The nonprofit worker has to refetch and repopulate that field every year. A single flow that works for all of these variants is a routing problem, not just a fill-form problem.

First-year filings for newly-formed entities are nearly empty. Maine formation documents do not require officer, director, or principal-office information at the time of formation; the entity exists with little more than a name, a charter number, and an obligation to file an annual report. So entities formed in the prior calendar year arrive at filing time with effectively no carry-over data on the portal. The flow has to treat "fill from scratch" as a distinct first-year path, not a degenerate case of "confirm or update what's already there." For ongoing entities, the prior-year filing carries everything forward and the data is well-normalized; the awkward case is the new entity, not the old one.

The portal's own confirmation PDFs aren't a reliable source of truth. Maine's filings are produced by a Tyler Technologies platform that uses an Oracle reporting tool to emit native PDFs. They render correctly visually, but native text extraction loses the layout. Column alignment vanishes, multi-row entries collapse into ambiguous strings, and the underlying structure shifts depending on how many officers, directors, members, or shareholders the entity has. Two filings for the same entity in different years can produce text dumps that diff against each other in spurious ways. Layout-aware OCR can in principle reconstruct the data, but OCR introduces a probabilistic step that's hard to defend in a system that produces legal records, where I want deterministic extraction. So the prior-year confirmation PDF doesn't reliably serve as the source of truth for what's currently on file, and any RPA against this portal that needs to compare prior state to new state has to extract live from the wizard's HTML rather than from the rendered confirmation document.

Liability requires human-in-the-loop, twice. Annual reports contain registered agent acceptance and officer confirmations: legal attestations. Auto-submission is not appropriate. The flow drafts and saves; the attorney reviews the draft along with the client-facing documents; the client then reviews their package for accuracy and any changes they want; adjustments come back through the flow; only then does the attorney submit. The system has to support iteration with two distinct human reviewers, not one-shot submission. That shapes everything downstream of the draft.

Downstream workflows compound the value. A finished draft needs to trigger a mail-merge: client notice, invoice, cover letter, and (for entities that adopted bylaws requiring them) corporate minutes. Doing the filing without doing the downstream is half the work.

Architecture

The pipeline has two halves. A scheduled Power Automate cloud flow handles orchestration, queueing, and routing on the server side; a Power Automate Desktop flow handles the actual browser automation on my workstation. That separation matters because of the unattended-license constraint above: cloud flows can run on a schedule (they're server-side), but PAD execution has to be attended, so the cloud side queues work and the desktop side picks it up during my workday session. SharePoint hosts the entity registry. Run progress and per-entity errors are appended to plain-text log files written from the flow itself, not stored in a database.

┌─────────────────────────────────────────────────────────────┐
│                     ENTITY REGISTRY                         │
│        SharePoint list (Excel-backed): entity book          │
│  fields: name, state ID, type, due date, last filed,        │
│          officers, registered agent, status                 │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│              CLOUD ORCHESTRATOR (server-side)               │
│  Scheduled cloud flow: queues entities due in 30d window,   │
│  routes each by entity type to its PAD worker, logs runs    │
└─────────────────────────────────────────────────────────────┘
                              │
                  ┌───────────┴────────────┐
                  ▼                        ▼
          ┌──────────────┐        ┌──────────────┐
          │  WORKER #1   │        │  WORKER #N   │
          │  (Domestic   │  ...   │  (Foreign    │
          │   LLC flow)  │        │   Corp flow) │
          └──────────────┘        └──────────────┘
                  │                        │
                  └───────────┬────────────┘
                              ▼
┌─────────────────────────────────────────────────────────────┐
│           BROWSER AUTOMATION (attended-only)                │
│  Power Automate Desktop, runs in workday session:           │
│  - Navigate to InforME portal                               │
│  - Look up entity                                           │
│  - Walk wizard (entity-type-specific path)                  │
│  - Extract current values from rendered HTML tables         │
│  - Compare to registry; flag deltas                         │
│  - Populate updates                                         │
│  - Save draft (do NOT submit)                               │
│  - Capture screenshots at key checkpoints                   │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│              ERROR HANDLING (append + continue)             │
│  - Missing field (regex match "is missing") → log + skip    │
│  - Generic portal error → log + retry past                  │
│  - Session timeout (rare) → re-login + resume               │
│  - Already-filed / ineligible status → log + skip           │
│  - Unknown wizard state → halt + alert                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│              DOWNSTREAM MAIL MERGE                          │
│  - Generate client notice (Word template + entity data)     │
│  - Generate invoice (filing fee + service fee)              │
│  - Generate cover letter                                    │
│  - Conditionally generate corporate minutes                 │
│  - Stage for attorney + client review                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│              ATTORNEY + CLIENT REVIEW                       │
│  Attorney reviews draft + client-facing documents           │
│  Client reviews package; requests changes if any            │
│  Adjustments fed back to flow; attorney submits             │
│  Marks complete in registry → updates last-filed date       │
└─────────────────────────────────────────────────────────────┘

The data layer: why Excel-on-SharePoint, and what I rejected

The natural reaction to "registry for a 1,000+ entity book with mail-merge fields and run history" is "use a real database." I considered it. Inside the constraints, every option failed for a different reason.

SQLite via Power Automate Desktop's Python 3 action. PAD ships a Python 3 runtime, and SQLite is in the standard library, so a local SQLite file was technically reachable. I ruled it out for three reasons. First, integration: a local SQLite file is invisible to cloud flows, so the orchestrator could not query the registry from the cloud side without a custom connector I wasn't permitted to build. Second, persistence and backup: the file would live on my workstation, and if the drive failed mid-season, the registry went with it. There was no sanctioned cloud-sync path for a binary file iManage didn't already manage. Third, ODBC: I did not have rights to install ODBC drivers, which closed the door on most database connectivity from outside Python itself.

Microsoft Access. Looks like the M365-friendly answer until you actually try to use it for this. Access gives you SQL semantics without proper concurrency, fragility comparable to Excel without Excel's universal compatibility, and the same single-file-on-a-workstation persistence problem as SQLite. iManage already handled document versioning and sharing for everything else, and bolting a flat Access file outside that system's reach wasn't viable.

Excel on SharePoint Online. What I shipped on. It loses points on schema, validation, and concurrency, and it's slow at scale. It wins on every constraint that mattered: native cloud-flow connectors, automatic versioning and backup via SharePoint, transparent multi-user access, and (most importantly) first-class compatibility with Word mail merge, which the downstream pipeline depended on. The fee schedule and per-client filing data lived in the same workbook, so cover letters, invoices, credit-card authorization forms, and the annual report draft could be collated by a single mail-merge run instead of stitched together across systems.

It wasn't ideal, but it was the option the constraints actually left open, and it carried the rest of the system reliably enough to ship.

Key engineering decisions and what I learned

1. Type-routed workers, not a monolithic flow

My first attempt was a single flow with conditional branches for each entity type. It became unmaintainable within two weeks. A single failure mode meant debugging through eight nested If/Else blocks. Splitting into one worker flow per entity type, with the orchestrator handling routing, made each individual flow shorter, more readable, and independently testable.

The cost was duplication. Some logic (entity lookup, error handling) is repeated across workers. I accepted that tradeoff. In a more mature build I'd extract those into child flows that all the workers call, which Power Automate supports.

2. Extract before fill, from the live wizard

A common RPA mistake is to assume the registry data is current and just fill the form. The actual source of truth is the SOS portal: clients move, officers leave, registered agents change. The flow first extracts all current values from the rendered HTML tables, then compares to the registry, then flags any deltas for paralegal review before drafting.

Because of the Tyler/Oracle PDF issue described above, that extraction has to come from the live wizard's HTML rather than the prior-year confirmation PDF. PDF text extraction looked tempting on day one (it would have been simpler than driving the wizard), but the layout instability across entity sizes made it unsafe as a source of truth.

This added complexity but caught hundreds of stale registry records. It also turned the automation into a data-quality system, not just a filing system.

3. Save, don't submit

The most consequential decision in the architecture. The flow stops at "save draft." It does not submit. Submission is a legal attestation, and an attorney has to make that attestation, not a script. Building this in from day one kept the system on the right side of the liability line and meant attorneys never had to wonder whether something had been auto-filed under their name.

The drafted package then moves through a two-stage review: the attorney reviews the draft and client-facing documents first, then the client reviews the package for accuracy and any changes. Adjustments come back through the flow, and only then does the attorney submit. The flow's success criterion is therefore "draft and client package staged for review," not "filing complete," and the system has to be comfortable with iteration. Metrics and dashboards reflect that.

4. Screenshot every checkpoint

Power Automate Desktop UI flows are brittle when the underlying portal changes, and the portal does change. Quietly, mid-season, with no warning. The flow takes screenshots at every key checkpoint: login success, entity found, wizard step N, extraction complete, draft saved. When something breaks at scale, having those captures cuts diagnosis from days to hours.

5. Append and continue, not halt on every failure

The dominant error mode on InforME isn't rate-limiting (I haven't observed it on the authenticated path, and the flow files in an authenticated session) and isn't session timeout (it happens, but rarely). The dominant error mode is a generic "sorry, something went wrong with your transaction" page that doesn't kill the session and that the flow can usually retry past on the next attempt.

The flow's response to most errors is uniform: append the entity, the failure type, and any matched error text to a plain-text log file, advance the counter, and continue. For the rarer cases (expired session, missing field, dissolved or ineligible entity), the flow records the specific reason and either retries after re-login or skips and continues. No individual entity failure halts the whole batch. The text log becomes the record of everything that needs human attention when the run completes.

This is less elegant than a retry-with-backoff scheme. For an attended single-operator workflow, where I'm at my desk and reviewing the log when the run finishes, it's enough. Simple to reason about, easy to debug, and consistent with the fact that the human is still in the loop.

6. The downstream pipeline is half the value

The filing draft is one document. The downstream mail-merge produces several more per filing: a cover letter customized to the attorney serving as registered agent for that entity, an invoice driven by the per-client fee schedule maintained in the same Excel registry, a credit-card authorization / return form for clients who pay that way, and (for entities whose bylaws require them) corporate minutes. Because the registry and the fee schedule lived in the same workbook, a single mail-merge pass could generate and collate the full client package in one shot rather than stitching documents across systems.

Tying all of this to the same orchestrator means the paralegal opens one ticket instead of five, and the attorney reviews everything together. That bundling is what made the rest of the team actually use it.

7. Coordinate-based clicks are fragile under multi-monitor docking

The flow ran on a laptop that docked to external monitors at the office and ran undocked elsewhere. Power Automate Desktop's UI automation falls back to screen coordinates when selectors fail or are ambiguous, and the Maine portal had several spots (duplicate buttons rendered conditionally, OCR matches with multiple hits on the same string, dynamically positioned form controls) where coordinate or image-anchored interaction was the most reliable approach.

The problem: every dock/undock cycle, every monitor swap, every Windows display-scaling change shifted the coordinate space. A flow that worked perfectly on Monday could click into empty whitespace on Tuesday morning if I'd taken the laptop home overnight.

What I landed on: pin a known-good display configuration before runs, anchor coordinates to detected UI elements (find-image-then-offset) instead of raw screen positions wherever possible, and put explicit screen-resolution checks at the top of each worker flow that halt if the active display doesn't match the recorded configuration. None of these are elegant. They all caught real misclicks during testing.

8. Pragmatic manual edits at the edges

Several entity-type variants have rare, awkward edge cases: historical formations with non-standard officer formats, address fields with embedded suite numbers the wizard parses wrong, optional-but-conditionally-required fields whose validation rules I couldn't reproduce reliably. I considered automating every one of these. I didn't.

When a class of edit was uncommon and idiosyncratic, the flow flagged it and handed control back to me at the GUI rather than trying to handle it programmatically. Every additional special case I considered adding doubled the surface area for breakage when the portal changed mid-season, and the discrepancies between corporation types compounded fast. Keeping the automation tight on the common path, and finishing the long tail by hand (or, in a small number of cases, falling back to paper filing), kept the failure rate low and the system maintainable by one person. Routine cases paid back the manual time on edge cases many times over.

Failure modes the flow handles

A summary of the production failure modes the flow actually encounters, with how it detects and responds to each. The general pattern is append the failure to a plain-text log file and continue, with halts reserved for cases the flow can't safely move past.

Failure mode How the portal signals it Flow response
Entity already filed for the year Red text on charter-number entry showing the date the current year's annual report was filed Append to log, skip entity, advance counter
Entity status not eligible Red text on charter-number entry: "not eligible to file until next year," or "this entity has been dissolved / cancelled / suspended" Append the specific reason to log, skip entity, advance counter
Existing saved draft from prior run Run progress tracked in a text file; counter set manually based on last processed entity, or registry "to be filed" → "filed" field movement Resume from last processed entity
Required field missing Regex match for "is missing" against the rendered page text Append the missing field to log, skip or halt depending on field
Generic portal transaction error Page returns a "sorry, something went wrong with your transaction" message without killing the session Append to log, retry past on next attempt
Session timeout / expired authentication (rare) Redirect to login or session-expired page Re-authenticate, resume from the last entity processed
Display scaling / coordinate mismatch Pre-run resolution check fails against recorded display configuration Halt before any clicks; reset display configuration before continuing
Unknown wizard state Selector and image-anchored fallback both fail at a step Halt, append context to log, escalate for human review

Common thread: the text log is the source of truth for what needs human attention after a batch run. Anything that can be safely skipped is skipped; anything that can't is the small number of cases I look at when the run finishes.

Integrations I evaluated and didn't ship

A few adjacent automations didn't make it past evaluation. The reasoning behind not shipping them is part of the picture, so they're documented here alongside what did ship.

DocuSign for corporate minutes. The downstream pipeline produces corporate minutes for entities whose bylaws require them, and DocuSign was the obvious fit for collecting officer signatures programmatically. DocuSign offers a robust API and a Power Automate plugin, so the technical integration was straightforward. Two things killed it: per-envelope cost was prohibitive at the volume in question, and accessing the Power Automate plugin would have required IT approval cycles and procurement steps that didn't fit the project's runway. Signed minutes still go out under the existing manual signature workflow.

Microsoft Forms for client confirmation. Before drafting each filing, it would be useful to send the client a short form asking them to confirm or update their officer list, principal office, registered agent, and similar fields. That data could then drive both the filing and the client-facing package, removing a back-and-forth round-trip. I evaluated Microsoft Forms for this and ruled it out for three reasons. First, the forms felt unwieldy to template at scale within the license available; I couldn't find a clean way to prefill each form with the client's prior-year data. Second, the forms looked unlike normal correspondence from the firm, and I was concerned clients (especially older ones) would read them as suspicious or phishing-adjacent. Third, the data coming back from a Form would have to be reconciled against the registry and the portal's PDF, and I was worried about drift between the two representations. The current process keeps client confirmation in human-mediated email and letter form.

AffiniPay / ClientPay QR codes on invoices. AffiniPay (and its legal-vertical product ClientPay) supports customized per-invoice payment links that can pre-scope the destination account (IOLTA versus operating) for a given charge. The build I sketched would have generated a custom link per invoice, dropped a QR code plus a clickable short link onto the printed invoice, and routed payments to the correct account without the manual reconciliation step that follows the current process. Implementation was effectively free on top of the existing payments processor.

It died for non-engineering reasons. Attorneys were skeptical of QR codes; they read as confusing or scam-like to older clients. And the finance group did not want to make credit-card payment more frictionless, because the 3%+ card-processing fee comes out of firm margin on every charged invoice. A short-link-only variant would have addressed the QR concern but not the payment-friction concern, so the proposal stayed on the shelf.

In a different organizational context, both would be worth revisiting. Inside this one, the objections were reasonable and the fights weren't worth picking.

Outcomes

I won't share specific numbers because the firm's book of business and per-entity revenue isn't mine to disclose. Directionally:

  • Time per entity: dropped from 5-10 minutes manual to ~1 minute of paralegal review on the drafted package.
  • Error rate: registry data quality measurably improved; the flow surfaced stale records that had been wrong for years.
  • Coverage: the system handles every entity in the firm's registered-agent book, across all common entity types, in a single coordinated run.
  • Maintenance burden: roughly 4-8 hours per filing season to handle portal changes and edge cases. Low enough that the build pays for itself easily.

What I'd do differently

Extend the orchestrator end-to-end. The current pipeline stops once the filing draft and client documents are staged. The natural extension is to fold notice assembly, payment tracking, and finance handoff (submitting the client's check or card charge to accounting) into the same orchestrator. Right now those steps are still manual hand-offs, and they account for a meaningful share of the leftover paralegal time.

Use a more robust RPA platform if licensing allows. UiPath's selectors, exception handling, and orchestrator are better-suited to sustained portal work than Power Automate Desktop. (n8n and Zapier weren't yet major platforms in early 2025; today I'd at least evaluate them, though browser automation against a legacy government portal isn't really their wheelhouse.) The firm wasn't going to add a paid RPA platform on top of M365 Premium, so the realistic choice at the time was PAD or nothing. This is part of why I'm targeting UiPath roles next.

Build out regression testing within what's actually possible. A full sandboxed mock of InforME would be ideal, but it's genuinely hard: I don't own the portal, I don't have specs for its validators, and I can't enumerate every conditional path the live system exercises. Short of that, there's still room for improvement. A small set of known-good entities used as a regression suite, plus saved HTML snapshots of each wizard step that selectors can be verified against offline, would catch most of the regressions I currently catch only at runtime against real filings.

Move the registry off Excel, but not to Access. A proper relational store (Dataverse, or an external SQL backend) would handle history, audit, and joins more cleanly than Excel-on-SharePoint. Microsoft Access (the obvious M365-bundled answer) is the worst of both worlds: SQL semantics without proper concurrency, Excel fragility without Excel's universal compatibility, and a single-file persistence model that doesn't play well with iManage's versioning. The right next step is Dataverse, with the existing Excel sheet kept as a mail-merge view.

Build a more robust audit log. The current run log captures success/failure per entity. A more granular per-action log (every wizard step, every extracted value, every retry, every coordinate-anchor resolution) would let me diagnose mid-season degradations before they become season-ending breakages, and would give the firm a defensible audit trail per filing.

Replace halts and fixed waits with loops and bounded retries. Some of the brittleness in the current flow comes from fixed-duration waits and explicit halts on uncertain states. Polling loops with bounded retries (wait until the page is in a known state, then proceed) are more tolerant of portal latency variance and would shorten total runtime meaningfully. Halts should be reserved for genuinely unknown states, not for "the page might still be loading."

Refactor toward shared sub-flows. The type-routed-worker design ships nine separate worker flows, and several share substantial logic (login, entity lookup, draft save, screenshot capture). Today, when I find a bug in one, I have to fix it in N. Pulling shared steps into reusable child flows (which Power Automate supports natively) would cut maintenance burden, reduce drift between workers, and let me iterate on each entity-type variant without retreading work I already did elsewhere.

Add agentic decision-making at error boundaries. When the flow encounters an unknown wizard state, it halts and alerts. With the right human-in-the-loop architecture, an LLM could classify the error, suggest a remediation, and keep going on the routine cases, escalating only the genuinely novel ones. That's the direction my independent work is heading now.

Tooling

  • Microsoft Power Automate (cloud flows + desktop UI flows, attended mode only)
  • SharePoint Online (entity registry, Excel-backed)
  • Plain text files (run logs, per-entity failure records, run progress)
  • Microsoft Word (mail merge templates)
  • Microsoft Outlook (downstream client communications)
  • iManage (on-premise document management, source/destination for client-facing deliverables)

A note on the flow files

I am deliberately not publishing the exported Power Automate Desktop flow files (.robin) in this repository, even though I produced them. The architectural patterns, design decisions, and operational lessons documented above are mine; the implementation artifacts themselves were produced as work product during my employment and belong to the firm. The appropriate place for those files is inside the firm's own systems, not a public portfolio. Knowledge is portable. The implementation is not.

For the same reason, this repository contains no selectors, no URLs, no credentials, no portal-specific configuration, no Word mail-merge templates, no fee-schedule data, and no client-identifying information of any kind.

If a hiring manager or technical reviewer would find a code-level walkthrough useful in an interview context, I'm happy to walk through how the flows are structured at a whiteboard level. The patterns are general and transfer cleanly to UiPath, n8n, or any other RPA platform. Most of what's interesting here is in the design choices, not in the specific Power Automate syntax.

About this writeup

I wrote this in 2026 as part of a portfolio for automation engineering roles. If you're considering this kind of work for your own firm or organization, I'm happy to discuss tradeoffs. Feel free to reach out via LinkedIn.

A note on AI assistance: I prepared this writeup with the help of an LLM (Claude) for formatting, structure, and prose cleanup, working from notes and recorded explanations I produced about the project. The engineering decisions, rationales, mistakes, and lessons are mine; the polish is AI-assisted.

About

Case study: Power Automate RPA pipeline drafting and staging several hundred Maine annual reports per filing season for a law firm's 1,000+ entity registered-agent book.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors