GMT+7
Backend systems
that hold when the
parts underneath do not.
I design and ship fault-tolerant microservices for financial and enterprise platforms — and I build them around the constraints nobody is allowed to remove. Spring Boot, Kafka, Redis, event-driven architecture, across Alibaba Cloud, Google Cloud and Azure.
Three systems, and the
trade-offs they cost.
2024
Sales Performance Dashboard
On-demand recomputation against a slow, unmodifiable legacy system was taking about three minutes per page load and spiking database CPU at peak reporting hours. No direct DB access was permitted, the legacy app could not be changed, and it had no push mechanism. I chose Change Data Capture over API polling, reusing existing Kafka infrastructure at near-zero cost, and wrote pre-aggregated results ahead of the request.
Trade-off: eventual consistency. Worst-case lag ~10 s, shown to users as a last-sync timestamp.
2025
ATS / HRIS Connector Platform
Moving a candidate to the background-check stage inside a client's own Workday or Manatal now creates the screening request automatically — no re-entry in a second portal. Built as a configurable platform rather than per-client code: runtime UI-configured field mapping lets every client keep its own DTO schema, with idempotency, concurrency handling, rate limiting and per-contract attachment rules. Onboarding needs no engineering work from the client — an API token or a permission-scoped service account is enough.
2025
AI-Assisted Delivery Pipeline
A delivery pipeline on Azure DevOps where a high-capability model plans from the bug ticket, cheaper models implement and raise the merge request, and the planner then reviews the diff against its own plan. Routine fixes run autonomously; anything complex is gated on manual approval. The interesting part was not the models — it was deciding where the gate belongs.
Java 25
encrypted-search-service
Java 25 · Spring Boot 4.1Encrypt a name and you lose the ability to search it; leave it searchable and you lose the encryption. The usual escape — decrypt a million rows and string-compare — is not an escape. This service refuses the trade by never reversibly encrypting at all: each field is normalized, split into overlapping 2- and 3-character n-grams, and every n-gram is HMACed with a versioned, field-scoped key. Only those hashes reach OpenSearch. No key turns an index document back into a name, because the transform was never built to run backwards.
Field-scoping is the part that holds up under attack rather than merely under normal use: the same n-gram hashes differently depending on which field produced it, so a token from email can never correlate with one from name, by construction.
Designed against Indonesia's UU PDP, generic underneath, and built on a zero-trust assumption — the database will leak eventually, so protection belongs at the data level. Your application stays the system of record; the service answers only which record ids match this partial query. It holds no credentials to your database, which is what makes the authorization story a construction rather than a convention.
Your app then runs SELECT ... WHERE id IN (ids) — your authorization, your database, your data.
Trade-off: a bigger index, and n-gram frequency leakage inherent to any substring-searchable scheme.
{
"id": "b1f9c2:name",
"originId": "b1f9c2",
"fieldName": "name",
"tokens2": ["9f...", "3a...", "77..."],
"tokens3": ["9a7bf83c2e", "3a19c9a22a", "77d8e12f92"],
"keyVersion": 1
}An attacker holding this cannot reconstruct the value, cannot tell which tokens came from another field, and cannot reuse a version-1 token against anything written after a rotation.
The field name goes into the HMAC input, so cross-field correlation is impossible rather than merely prevented by query logic. One document per (originId, fieldName) is what makes it queryable.
Writes use one active version; reads accept any listed version — AND within a version, OR across them. Add the new key, let writes drift onto it, drop the old one when nothing depends on it.
Functionally close cousins. Elasticsearch's licensing history sits badly under a project whose whole premise is contribute freely, so the stack stays Apache-2.0 end to end.
The original sketch cached token computation. HMAC-SHA256 over a handful of n-grams costs microseconds — not worth a second stateful service to run and secure. Cut from v1, not forgotten.
The full reasoning behind encrypted-search-service: why decrypting a million rows to run a string compare is not a workaround, what n-grams buy and what they leak, why the field name belongs inside the HMAC input, and how versioned keys turn rotation from an outage into a config change.
Software Engineer · Integrity Asia
Enterprise ERP platform migration. Senior-scoped in a flat title structure — I mentor and technically direct two junior engineers, and act as the primary translator between business requirements and buildable system design.
Senior Backend Developer · Berijalan Technocenter
Architected and shipped five microservice platforms of three to nine services each — real-time messaging, CRM, telephony, vehicle insurance, sales performance — on Alibaba Cloud. Promoted to Senior after twelve months.
Senior Backend Developer · Bank Saqu
Client placement via Berijalan. Designed and delivered virtual account features on Google Cloud for a digital bank, and hardened core banking services under banking-grade security and audit requirements. The only engineer to pass the technical assessment.
Java · Kotlin · TypeScript · C#
Spring Boot · Spring Cloud · .NET · Node.js · gRPC · REST
Kafka · Redis · Change Data Capture pipelines · relational databases
Resilience4j — circuit breaker, retry, bulkhead · eventual-consistency design
Alibaba Cloud · Google Cloud · Azure · Docker · Jenkins · Argo CD
React · TypeScript · Angular · JUnit · Mockito