for Trailmark Fund Solutions

File Intake & Client Organization

Step 2 of the nightly reporting pipeline — how each new file gets from fund accounting into the right client folder in SharePoint, renamed and logged, without anyone pulling files by hand.

The new intake

Fund accounting delivers the night's files over SFTP into Azure Blob storage — a delivery path we set up as part of this work.

From there each file flows automatically into three SharePoint libraries: a visible RAW data copy, then a renamed copy sorted into a folder per client in the Working library. The arrival is written to a Run Log, so the team works in SharePoint with a dashboard.

Inside Step 2 — how intake works

Step 2 is the single intake step in the seven-step pipeline. Under the hood it runs as a short sequence, all automatic:

1
A blob trigger fires. Power Automate's "When a blob is added or modified (properties only)" trigger fires when a new file lands in the Blob container. It connects with a dedicated service account (Microsoft Entra ID Integrated — token-based, no access key) and watches the container root only (see the auth note below).
2
Copy to the RAW data library. The file is copied as-is into a client-visible RAW data library — no parsing, no renaming, original name and format kept. The team can see exactly what arrived, in one place, instead of logging into the SFTP.
3
Parse the filename. The dot-delimited name is split into Report Type, Reporting Date, and Fund / Ticker Code. Real names are more complex than a simple sample and there can be several files per fund per day, so the parser picks the newest by the created timestamp.
4
Look up the client. The parsed Fund / Ticker Code is matched against the Clients list to resolve which client the file belongs to and which Working folder it lands in.
5
Rename & copy into Working / {client}. The copy going into Working / {client} is renamed to Trailmark's standard convention, with Report Type, Reporting Date, and Fund Code kept as metadata columns. The RAW data original keeps its Fundguard name, untouched.
6
Write the first Run Log row. Intake appends a row to the Run Log SharePoint list recording what arrived for this client and run — the first status of the night, which later steps update as the run progresses and the dashboard shows.
One-time cutover backfill
The managed blob trigger watches only the container's root folder (matching the flat-container decision) and ignores any blobs that already existed before it was switched on. At cutover we run a one-time backfill for whatever is already sitting in the container, or the trigger will never see it.

Where things will be stored

Storage is three separate SharePoint document libraries — not folders inside one library, and not a library per year:

Fund accountingSource system
SFTPNew — we build this
Azure BlobRaw files land here
RAW data libraryFlat — originals untouched
Working libraryRenamed & sorted, folder per client
Archive libraryYear / date folders

The RAW data library stays flat and keeps every original under its own Fundguard name. The Working library holds one folder per client, where the renamed copy lands. Once a night's cycle is done, its files are archived into the single Archive library under year and date folders (e.g. Archive / 2026 / 2026-07-14). The SFTP endpoint itself is only turned on for the nightly delivery window — see “Running the SFTP endpoint only when needed” below for what switches it on and off.

RAW data (library — flat, originals untouched) gryphonprod1.…usvc…created_2026_07_14_21_19_25.xlsx ← original name kept chmp.abor.chmp___champion_nightly_reports….pdf Working (library — one folder per client) ├── USVC/ USVC Nightly Reports 7.14.2026.xlsx ← renamed to your convention ├── Champion/ Champion Nightly Reports 7.14.2026.pdf └── … one folder per Active row in Clients Archive (library — year / date folders) └── 2026/ └── 2026-07-14/ … the night's files, moved here automatically once done

Library and folder names and the renamed-file convention shown here are illustrative — please confirm they match your current layout.

Running the SFTP endpoint only when needed

SFTP on Azure Blob storage carries a per-hour charge for every hour the endpoint is enabled — a passive cost that applies even when nothing is being transferred (it is not a per-file or per-GB fee).

The cost lever
Left on 24×7 the SFTP endpoint runs roughly ~$0.30/hour ≈ ~$216/month (exact rate on the Azure Blob Storage pricing page). Because fund accounting only delivers once a night, we enable SFTP just for the nightly delivery window and disable it the rest of the day — so we pay for a few hours, not the whole month.
How we automate the window
An Azure Automation Account runbook (PowerShell, Set-AzStorageAccount -EnableSftp) runs on two schedules — enable before the window, disable after — signing in with a Managed Identity scoped to just this storage account (no stored keys). Cost is effectively $0/month: two roughly 1-minute jobs a night sit well inside Azure Automation's 500 free job-minutes per month.

Note: this windowing assumes the current once-a-night cadence. If reports ever need to run closer to real time, the SFTP window can't be as tight — a point to weigh against the Cadence open item. Storage, SFTP hours, and licensing are totalled in the separate cost document.

The Clients list

One simple SharePoint list decides which folder a file belongs in. It is separate from the notification and recipient lists — this one answers "which folder," not "who gets emailed." Onboarding a new client is a new row, not a developer task.

Clients — fields schema
FieldTypePurpose
Client KeyText (unique)The shared key the notification lists also reference — same identity, different concern
Client NameTextFull display name for logs and manual review
Fund / Ticker CodesText (multi)Codes as they appear in the filename — used to match incoming files
Working FolderTextThe folder under Working this client's files are copied into
ActiveYes / NoWhether this client is processed — an inactive row's files route to review instead

The Clients list maps each client to its Working folder. That mapping is the whole point of Step 2's "look up the client" move.

Sample rows two real clients
Client KeyClient NameFund / Ticker CodesWorking FolderActive
USVCUSVCusvcWorking / USVCYes
CHMPChampionchmpWorking / ChampionYes

The Fund / Ticker Codes are the filename prefixes the parser matches on (e.g. usvc.abor.…, chmp.abor.…). One incoming file → matched to its client → the renamed copy is dropped into that Working folder. Onboarding a new client is just a new row here.

What the new intake handles

The flow covers every piece of file handling end to end:

BehaviorNote
Detect arrival & parse filenameBlob trigger ("When a blob is added or modified (properties only)") + filename parse, fired the moment a file lands over the new SFTP delivery
Strip invalid filename charactersHandled as part of the automated rename
Rename to standard conventionHappens at intake: the RAW data original keeps its Fundguard name; the Working copy is renamed to the standard convention, plus metadata columns
Sort into a per-client folderCopy into Working / {client}, resolved via the Clients list
Avoid overwrite via (1)/(2) suffixExplicit check-if-exists + rename logic built into the flow — Power Automate's Copy action has no automatic (1)/(2) renaming
Per-run status summaryRun Log rows + central logging, giving per-run status in SharePoint

Open items to confirm

Unmatched files
What should happen to a file whose Fund / Ticker Code matches no Active row in Clients? Recommended: route it to a Needs Review folder in the RAW data library and log it, rather than blocking the run or guessing a destination.
Clients list ownership
Recommended: Operations owns the Clients list directly — adding a client is a new row, not a developer task. Still to confirm: who specifically holds edit rights.

What stays the same

How the intake authenticates
The Blob and SharePoint connections run under a dedicated service account via Microsoft Entra ID Integrated (token-based, no access key) — or a service principal. So there's no stored storage-account key, but there is a stored delegated connection tied to the service account. Passwordless Managed Identity is used where it's available: the Azure Function (email) and the Automation Account (SFTP window), both Azure resources.
Report, don't drop silently
A file that matches no Client row is logged and left for manual triage, never silently dropped or misfiled.
Central logging
Beyond the business-facing Run Log, every copy and routing decision is logged centrally (Application Insights), the same principle as every other step in the pipeline. Infrastructure and running costs for this step are covered in a separate document.