Solution design · U.S. Bank · Oct 2024 – Jun 2025 · Palantir Foundry

Collections Management System — Real-Time, Event-Driven Collections Platform on Foundry

Replaced a legacy Oracle BRM batch collections engine with an end-to-end Foundry platform — moving eligibility evaluation from a daily batch cycle to event-driven, near-real-time triggers while preserving full idempotency and auditability across every state transition.

Oracle BRMCDC + batch mergePySpark transforms ontology objectseligibility functions collection records & actionsAutomate lifecycle email / CSR overrides ↩ property-change monitors re-evaluate eligibility instantly — no overnight wait
921K
Billing accounts
19.7M
Invoice records
24h → 0
Time-to-action
8
Object types
15+
Ontology Functions
26,749
Actions (first sweep)
00

Overview

problem → platform

The legacy collections engine ran as a nightly Oracle BRM batch job. Accounts that crossed eligibility thresholds overnight waited until the next batch window before any collection record or action existed — a 24-hour time-to-action that left delinquency unmanaged for a full business day.

The Foundry platform reverses that model. Source changes land through CDC and batch merges, materialise into a governed ontology, and fire Automate property-change monitors that invoke TypeScript Ontology Functions. Eligibility is re-evaluated as soon as bill-unit or bill-summary properties change. A daily sweep covers the edge case of bills that become past due overnight without any object mutation.

Two design decisions shape the whole system. First, transform-backed objects stay read-only mirrors of source truth, while action-managed objects own platform lifecycle state — so source refreshes never clobber in-flight collections. Second, every create and transition path is idempotent: existence checks for active and paused records run before creation, so parallel Automate triggers cannot double-open a collection.

SOURCE — ORACLE BRM INGESTION — CDC + BATCH MERGE TRANSFORMS — PYSPARK / SQL ONTOLOGY — TRANSFORM-BACKED + ACTION-MANAGED FUNCTIONS + AUTOMATE OPERATIONS — EMAIL · CSR OVERRIDES · AUDIT Bill Units Bill Summaries Profiles Account Master + 2 BRM tables 6 source tables total CDC stream timestamp supersedes batch Batch snapshot LEFT ANTI JOIN merge Merged governed datasets deduped · lineage retained Profile resolution 4-table NULL coalesce Incremental bill units 19.7M+ · derived ageing Hierarchy FK resolve parent-child billing Bill Unit transform-backed Bill Summary transform-backed Collection Record action-managed Eligibility Fn idempotent create Automate 11 monitors Mailgun dispatch CSR overrides Promise-to-pay · disputes Audit writeback
End-to-end lineage from Oracle BRM through ontology, functions, and operational writeback
Source / transform-backed Action-managed / ops Ontology Functions Automate monitors
01

Ingestion — CDC & Batch

six Oracle BRM tables

Source of truth remains Oracle BRM. Foundry does not become a second ledger — it becomes the operational brain that reacts to ledger state. Six BRM tables feed the platform through a dual-path ingest: continuous CDC for low-latency deltas, and scheduled batch snapshots for catch-up and recovery.

Merge contract

CDC wins

LEFT ANTI JOIN merge with timestamp-based deduplication

CDC path
Streams changed rows as they land; always supersedes batch state for the same primary key when the CDC timestamp is newer.
Batch path
Full or windowed snapshots for initial load, backfill, and CDC gap recovery.
LEFT ANTI JOIN
Batch rows are admitted only when no CDC row already covers the key — preventing stale batch from overwriting fresher change events.
Deduplication
Timestamp comparison chooses a single winner per key; reprocessing the same window is safe.
Lineage
Every merged dataset retains provenance so a disputed balance can be traced to BRM source rows.
Invariant For any primary key present in both streams, the CDC row with the latest timestamp is authoritative. Batch never silently wins a race.
02

Transforms & Analytics

Python · PySpark · SQL

Multi-table PySpark pipelines turn merged BRM tables into ontology-ready datasets. Derived analytics columns — days overdue, ageing bucket, days to close — are computed once in transforms so every downstream function and monitor reads the same numbers.

Key transform chains

pipelines
Profile resolution
Four-table join chain with NULL-coalesced fallback logic so every bill unit resolves to a collection profile even when intermediate keys are sparse.
Incremental bill units
Incremental transforms over 19.7M+ bill unit records — only changed partitions rebuild, keeping schedule SLAs achievable at month-end volume.
Derived analytics
Days overdue, ageing bucket, and days-to-close computed as first-class columns rather than ad-hoc Workshop calculations.
Hierarchy FK resolve
Foreign-key resolution across parent-child billing hierarchies so collection actions can cascade correctly to child accounts.
Idempotent rebuilds
Transforms are safe to re-run; snapshot vs incremental strategy selected per table based on volume and change rate.
03

Ontology Model

eight object types

The ontology is the system of record for collections operations. Transform-backed objects mirror BRM truth and stay read-only. Action-managed objects own lifecycle state that only Ontology Functions may edit — protecting in-flight work from source refreshes.

Object catalogue

8 types
Bill Unit
Transform-backed. Core billing entity with ageing analytics and profile linkage.
Bill Summary
Transform-backed. Aggregated balance and due-date view that drives eligibility triggers.
Account / Hierarchy
Transform-backed. Parent-child billing relationships for cascade behaviour.
Collection Profile
Editable / configurable. Per-segment and per-currency escalation paths (e.g. suspend at 30 days, write-off at 60).
Collection Record
Action-managed. Opened when eligibility fires; owns the dual-state lifecycle for the account.
Collection Action
Action-managed. Scheduled step in the escalation path — email, call, suspend, write-off.
Promise to Pay
Action-managed. Linked commitment that can pause escalation until expiry or fulfilment.
Dispute
Action-managed. Linked exception that freezes standard paths until resolution.
Link types Full link-type relationships connect records to bill units, actions to records, and promise-to-pay / dispute objects to the parent record — enabling cascading side effects in a single Ontology transaction.
04

Dual State Machine

records · actions · cascades

Collections is not a single status field. It is two coordinated state machines — one for the collection record, one for each collection action — with cascading side effects when either machine exits.

Collection Record

5 states · 10 transitions
Open Active Paused Exited Historical

Record exit triggers bulk action cancellation, orphan closure, and linked promise-to-pay / dispute resolution in one atomic Ontology transaction.

Collection Action

7 states · 12 transitions
Scheduled Ready In Progress Completed Cancelled Blocked Historical

Sequential gate logic enforces step-order promotion — an action cannot advance until its predecessor reaches a valid terminal state (completed, cancelled, or historical).

Cascading exit

atomicity
Smart exit
Record exit cancels outstanding actions, closes orphans, and resolves linked promise-to-pay and dispute objects together.
No partial exit
Side effects run as Ontology edits in one function invocation — no half-exited records left for the next monitor cycle.
Auditability
Every transition is attributable to a function invocation or Automate trigger, preserving the trail the legacy batch job never had.
05

Eligibility Rules Engine

profiles · filters · thresholds

Eligibility is data-driven, not hard-coded. Collection profiles are editable object types supporting per-segment and per-currency escalation paths. The engine evaluates five static filters plus an aggregation threshold against 962 profile-action mappings.

Evaluation model

real-time
Static filters
Five fixed predicates (account status, balance presence, exclusion flags, etc.) that must all pass before profile matching.
Aggregation threshold
Balance / ageing threshold check against the resolved profile — the gate that previously waited for nightly batch.
Profile-action map
962 mappings define which escalation actions schedule when a profile matches — including suspend-at-30 / write-off-at-60 style paths.
Existence guard
Before creating a record, the function checks for active or paused records on the same bill unit — eliminating duplicates under parallel triggers.
Historical migration
On first eligibility, standing overdue balances can seed a record with historically accurate action schedules rather than starting cold.
Batch retirement After cutover, the daily eligibility transform was retired. Real-time property-change monitors plus a past-due overnight sweep fully replaced it — zero standard-path manual intervention.
06

TypeScript Ontology Functions

15+ production functions

Ontology Functions are the only writers of action-managed state. They encapsulate eligibility, creation, scheduling, external dispatch, and CSR overrides — each designed for idempotent, concurrent-safe execution.

Function catalogue (representative)

TypeScript v1
evaluateEligibility
Runs static filters + threshold against profile mappings; returns create / skip / update intent.
createCollectionRecord
Idempotent create with historical migration of standing overdue balances into the action schedule.
scheduleActions
Materialises the profile-action path as sequenced Collection Action objects with gate predecessors.
promoteAction
Sequential gate validation — advances an action only when predecessor terminal state is valid.
dispatchEmail
Renders Mailgun templates by action name, sends, and writes receipt / completion state back.
exitCollection
Atomic cascading exit across actions, promises, and disputes.
csrOverride
Operator-driven pause, resume, skip, or force-complete with full audit attribution.
resolvePromise / resolveDispute
Closes linked exception objects and resumes or exits the parent record per policy.
07

Automate Orchestration

11 monitors · zero manual standard path

Automate is the event bus. Property-change monitors catch live mutations; entered-set and scheduled monitors cover lifecycle progression and the overnight past-due edge case.

Real-time entry (3)

triggers
Bill unit changes
Property-change monitor — re-evaluates eligibility when unit-level fields that affect ageing or balance change.
Bill summary changes
Property-change monitor — catches aggregate balance / due-date updates that may not mutate the child unit.
Daily past-due sweep
Scheduled — covers bills that become past due overnight without any object mutation (pure calendar crossing).

Lifecycle monitors (8)

automation
Entry
Creates records / actions when eligibility first fires.
Exit
Runs cascading exit when balances clear or policy exits apply.
Scheduling
Promotes queued actions when their schedule date arrives.
Execution
Drives in-progress actions through dispatch and completion writeback.
Promise-to-pay expiry
Resumes escalation when a promise window lapses unpaid.
Dispute resolution
Releases freezes when dispute objects reach terminal state.
+ supporting monitors
Additional monitors cover pause/resume hygiene and historical archival so the active set stays lean.
Concurrency Parallel trigger execution is expected. Existence checks and Ontology edit semantics keep evaluation idempotent — duplicate active records cannot be created under race conditions.
08

Integrations

Mailgun · CSR · audit

External email delivery

Mailgun
Template rendering
Templates selected by action name so each escalation step has a governed message body.
Receipt tracking
Delivery receipts written back to the action object for operator visibility.
Completion writeback
Successful dispatch advances action state; failures leave the action retryable rather than silently lost.

Operator controls

CSR overrides
CSR override functions
Pause, resume, skip step, or force-complete with attributed actor — automation never blocks human judgment on exception paths.
Profile editing
Collection profiles remain editable objects so business can adjust escalation paths without a code deploy.
09

Parallel-Run Migration

safe cutover · rollback ready

Cutover did not flip a single switch. Legacy batch and real-time monitors ran in parallel so outcomes could be compared before retiring the batch path.

Cutover strategy

risk control
Parallel run
Legacy batch eligibility and Foundry real-time monitors operated simultaneously against the same population.
Validation
Record and action creation rates compared; discrepancies investigated before batch retirement.
Branch-based promotion
Functions validated through Git-backed branch development and peer review before production promotion.
Rollback capability
Batch path remained available until real-time monitors proved stable — cutover was reversible.
Batch retirement
Daily eligibility transform retired only after confidence; overnight past-due sweep retained as the calendar edge-case safety net.
10

Production Outcomes

first sweep · steady state
1,917
Collection records
Created in the initial production sweep from standing overdue balances.
26,749
Collection actions
Scheduled escalation steps materialised in the same first sweep.
~0
Time-to-action
Down from a 24-hour batch window to near-real-time on property change.
0
Manual standard path
Eight lifecycle monitors cover entry through dispute resolution without human intervention.

Environment

stack
Platform
Palantir Foundry — Ontology, Automate, Foundry Transforms, TypeScript Ontology Functions (v1.4.3)
Data
Oracle BRM, PySpark, SQL
Integrations
Mailgun, Git-backed Code Repositories, JIRA, Agile/Scrum
11

Design Invariants

what must never break

These are the rules the architecture is built to defend. If a change violates one of them, it is not a feature — it is a regression.

CDC beats batch
For any key, a newer CDC row always supersedes batch state. Never invert the merge.
Source objects stay read-only
Transform-backed mirrors of BRM must not be edited by functions; lifecycle lives only on action-managed types.
One active record per unit
Existence checks before create — parallel Automate fires cannot open duplicate collections.
Sequential gates hold
Actions do not promote past an incomplete predecessor. Escalation order is policy, not suggestion.
Exit is atomic
Record exit cascades to actions, promises, and disputes in one transaction — no orphaned in-flight steps.
Calendar edge covered
The overnight past-due sweep exists because pure date crossings produce no property-change event.
Cutover stays reversible
Until batch is retired with evidence, parallel-run comparison and rollback remain available.