Case study · RegTech / compliance
artAML
Embedded frontend contractor on a production anti-money-laundering (AML) and KYC compliance SaaS, the platform financial and regulated businesses use to run customer due-diligence questionnaires, screening and reporting. My remit spans the main Angular application, two customer-facing satellite apps and the build/CI tooling, with occasional work into the Scala backend where a feature crosses the wire.
- Angular 18→20
- TypeScript (strict)
- ng-zorro-antd
- RxJS
- LESS / SCSS
- Auth0
- Scala backend
- Cloudflare Pages
- GitHub Actions
Selected work
What the engagement involved
White-label theming system
The flagship workstream: a full, tenant-configurable theming system so each organisation can present the platform in its own brand.
- A 4-variant theme model (light, dark and two alternate brand palettes) that ships on only two compiled CSS bundles. Rather than doubling the pre-built ng-zorro payload for every new palette, the alternate variants are expressed purely through CSS custom properties applied at the document root, reusing and re-tinting the base bundles at runtime.
- Migrated the UI from hard-coded styles to a token-driven system, refactoring component styles onto a central set of design tokens so the brand can be re-skinned without touching component code.
- Built the theme-admin experience: a tabbed, categorised editor over ~116 theme tokens, with every token mapped to its actual consumer. Because ng-zorro themes from compiled LESS bundles rather than the SCSS layer, most tokens look dead; auditing across both layers showed only 7 of 116 were genuinely unused (removed), with a few genuinely-used ones rewired.
- Solved tenant logos and assets via a backend contract that expects base64 data-URLs, with aliases maintained so existing tenants' stored themes never broke.
Customer-facing satellite apps
Two standalone Angular apps sit alongside the main product: a secure document-request portal and a remote identity-verification app, reached by customers through one-time-passcode links.
- Extended the theming system so each satellite carries the organisation's brand, delivered in the OTP link payload rather than baked into the app.
- Diagnosed and fixed a subtle projection bug: the satellites are 2-variant, but organisations can select one of four brand variants per user, so customers were seeing default styling instead of the brand they chose. I introduced a 'selected-series' projection that collapses the four variants to the correct light/dark pair for whoever created the session.
Dashboard & questionnaire features
- Ongoing feature and bug work across the dashboard and the questionnaire engine, a WebSocket-driven flow where the backend drives what the UI renders, including navigation improvements and task-list behaviour.
Framework & dependency modernisation
Owned a full toolchain and framework migration, one major at a time, keeping the test suite (1,200+ specs) and production build green at every step.
- Node 18 → 22 across local, CI and Cloudflare build environments.
- Angular 18 → 19 → 20, moving ng-zorro, the CDK and markdown/rendering libraries in lockstep with the breakages each major introduced: component-library module removals, an ES2022 browser-support baseline shift, and template-API changes.
- Scoped Angular 21 out with evidence: took it to a working build, found that v21's stricter change-detection would require an app-wide test migration, and made the call to land on a fully-supported v20 with v21 documented as a scoped follow-up, rather than block delivery.
- Brought the wider dependency set to latest-where-safe, holding back the majors that warranted their own ticket.
Engineering quality & process
- Worked within an automated code-review setup, triaging findings on their merits: applying genuine fixes (including a real, test-escaping bug where an upgraded component control had changed behaviour) and pushing back, with evidence, on false positives (several of which were later withdrawn).
- Added regression tests, held the codebase to a strict no-any TypeScript standard, and kept engineering notes so the next contributor inherits the context.
Across the engagement
How I worked
-
Depth over patching
Repeatedly chose to fix the underlying mechanism, a variable-driven theme layer or a documented backend contract, rather than layer on special cases.
-
Risk-managed delivery
Incremental, independently-verifiable steps, and knowing when to stop short of the newest version to protect a shippable result.
-
Full-stack awareness
Reading the backend to understand a contract before 'fixing' the frontend.
Need this kind of frontend depth on a contract?