I design systems that outlive frameworks — combining strategic architecture with operational discipline.
For more than 25 years I have turned complex business requirements into production systems for banks, telecom operators, parishes, and enterprises — from raw wire protocols up to complete products — then guided those systems through years of operational evolution. Core platforms designed in 2009 remain in active production today, on their original architecture.
Four habits, formed over 25+ years, that make my systems different — and make them last.
Comfortable below the library line: SMPP binds to mobile operators, SNMP across server fleets, SIP/Asterisk telephony, SMS over raw serial tty, hand-built HTTP and SMTP stacks. When no library fits, I write the protocol layer myself.
Saturn and Kaliber: ~17 years in continuous production with sustained operational oversight. Framework-free Java — no Spring, no ORM — embedded Jetty and direct JDBC keep the dependency surface tiny and every line accountable.
OpenID Connect across every product. WebAuthn/FIDO2 passkeys, TOTP, and JWT in daily use. QR-verified digital documents replacing scanned signatures. IPSec and pfSense/OPNsense at the network edge.
Local LLM agents (Ollama) embedded into real products: agentic file operations with tool-calling, AI-assisted document metadata, a natural-language assistant inside a database console. Private by architecture — no data leaves the server.
Good software is not measured by how quickly it is written. It is measured by how quietly it keeps operating years later.
architecture over implementationAnalysis, architecture, and operation sit with the same person on these systems — so the questions that decide whether one survives get asked before the first line is written.
Requirements arrive as symptoms, not specifications. The first work is separating the problem from the solution someone already picked.
Failure scenarios before features. What degrades, what must never stop, and what a human has to do at 3 a.m.
I plan on a ten-year horizon because I have been the person on the other end of it. Every dependency is a debt someone inherits.
A small dependency surface is a design constraint, not a preference. Fewer moving parts I do not control means fewer forced rewrites later.
Deployment is not a phase after the build. I run the virtualization, the servers, and the backups for what I design, so operations shapes the architecture.
Systems earn their keep by absorbing new modules without a rewrite. If a requirement five years out would force one, the design is wrong now.
Implementation begins only once those are settled. AI coding agents have transformed that second half of the work further than most people expected even two years ago: writing code no longer consumes the attention that architecture, integration, and operational resilience require. Implementation is now directed and reviewed rather than typed line by line. Productivity has stopped scaling with hours spent at the keyboard.
Long-lived systems come from a handful of choices taken early and revisited often. These are those choices, written down.
The architecture began in 2005, in an open-source project rather than a client system. jWebDBAdmin was published on SourceForge with a single design goal: stay lightweight. One Portal servlet resolved a command name to a bean, populated that bean from the request, ran it, and handed the result to one template. Spring 1.0 was about a year old at the time and had not yet become the default it later was — this was a choice made before the standard settled, not one made against it.
When Gaharu needed a new support system in 2009, that foundation had already proven itself in the open. Kaliber was built on it rather than on something new. Every re-evaluation since has been a genuine one: Spring, Maven, and Gradle have each been revisited several times, most recently in 2024, and the conclusion has held.
The trade-off is close to even, and that is precisely the reason it holds. When something breaks in code written here, that code gets read. When something breaks inside a framework, the fix requires learning that framework's internals to solve a problem that was never yours — and the timeline belongs to somebody else. The same applies to build tools: Maven would mean maintaining Maven, rather than the library actually needed.
None of it was free. What a framework would have supplied had to be written instead, and that became GeneralLib — grown incrementally, driven by need rather than designed up front. Its database layer is the clearest example: a connection pool that validates and recycles connections, and a wrapper implementing java.sql.Connection so it drops in anywhere, tracks every statement it creates, and closes all of them when released. Two classes remove the entire leaked-cursor class of bug, with no ORM anywhere. The SMS layer started from a GPL PDU library, extended for UDH ports, alternative character encodings, and custom acknowledgement; the SMTP and TCP servers were written here.
The payoff is visible in the lineage: jWebDBAdmin (2005) → Kaliber (2009) → Saturn → yakobusOne → AppKTG → aether.ing (2025). The presentation layer changed completely along the way, from HTTP request/response to a single-page application. The core did not — twenty years on, aether.ing still resolves a request through a Portal, a Command, and a BeanObject, the same three pieces the 2005 source defines. Kaliber has never been fundamentally rebuilt; modules were added throughout, and its most notable change in seventeen years was Indonesia's VAT moving to 11%, then to 12% applied as 11/12 of the base.
The cost, honestly. The architecture is uncommon, so a developer joining it has to learn it — historically the real price of this decision. The same decision holds today all the same, and that objection has weakened: AI coding assistants absorb an unfamiliar codebase's idiom quickly, so an uncommon framework costs a newcomer far less than it used to. What still matters is the architecture underneath — the part that decides whether a system can flex and scale.
Applications are expected to be smarter every year, and increasingly that means putting a language model inside them. The question is not whether to add one, but where it runs. These products touch data that has no business leaving the building: parish documents sitting in an approval workflow, database schemas and the rows inside them, private files on someone's own storage. A hosted API would have been faster to integrate. The models run in-house instead.
Privacy is the easy half of that argument, and the half everyone states. The harder half was cost behaviour. Per-token billing scales with use, and these deployments are a parish office and small self-hosted installations — places where a surprising month is a real problem rather than a line item.
That argument does not win outright, and presenting it as though it does would be dishonest. Hardware capable of running useful models is not cheap either, and it depreciates whether it is busy or idle. At low or bursty volume, a hosted API is very likely cheaper. The data boundary is the requirement here; predictable cost is a secondary benefit, not a proof of savings.
So the decision was built to be reversible. The integration targets an OpenAI-compatible interface rather than one vendor's SDK, which keeps the model an operator's setting rather than a rewrite. In the user-facing applications it is configured once and never surfaces to the person using it — the feature is the document check or the query assistant, not the model behind it. In aether.ing, where the agent is the product, the provider is chosen at deployment: a local runtime by default, a hosted endpoint if one is ever needed.
The limits are real. Self-hosted models are still weaker than the best hosted ones, and some tasks are simply worse for it. The hardware becomes an operational responsibility alongside everything else. And the distance between local and hosted moves month to month — which is the strongest argument for keeping the boundary swappable rather than betting on either side of it.
The same decision holds today, because the data boundary is a requirement rather than a preference. An application without that constraint could reasonably choose the other way.
Three companies, one long arc: developer → manager → architect — and never out of the code.
ISP billing, prepaid dial-up, customer self-service web, restaurant ordering–kitchen–billing chain. First production systems.
Client relationships and delivery leadership: systems for Pfizer, Dexa, Telkom, Bayer, Metronet, Tabloid Bintang, and more.
End-to-end system architecture: interfaces, databases, security, and production operation on KVM high-availability virtualization.
The omnichannel communications platform and the billing/customer-care system I designed, built, and actively steward in production.
WordPress OpenID plugins, WhatsApp Business chatbot, Google Workspace for Nonprofits, COVID-19 case reporting.
Mass ticketing in the pandemic, QR check-in identity, and Jubilee Year 2025 attendance certificates with digital seals.
Folding self-hosted LLM agents into production platforms. Year 28 of a career, shipping newer ideas than year one.
A summary reads in a minute; every entry expands for engineers who want the how. Status chips tell you what is alive right now.
ChallengeClients were running a different tool for every product and every channel — messaging in one place, voice in another, billing somewhere else again.
ResultOne platform where a client does everything, for any product or service. The name is the point: many functions orbiting a single site, like the many moons of Saturn. Seventeen years on, it is still what the other systems synchronise with.
The flagship. One platform carrying WhatsApp, Telegram, and SMS chat-bots with a shared knowledge base, agent live-chat, SMPP connectivity straight into mobile operators, and Asterisk/AudioCodes voice broadcast. Roughly 840 source files — designed, built, and continuously operated for over 17 years.
Where the money is counted. Voice/CDR rating and PDF invoicing, payments, credit limits, suspend/expire lifecycle, and automated dunning through templated email and SMS. Seventeen years in production alongside Saturn — modules added throughout, the architecture never rewritten to accommodate them.
Revenue assurance, hunted in packs. Four cooperating services that trap GSM sim-box gateways intercepting interconnect traffic — the fraud that silently rebills international calls as local ones.
ChallengeThe bank needed access to seven years of voice recordings held across more than 400 branch sites, reachable only over interconnections that carry live banking traffic through the working day.
ResultA voice recording management platform, and the consolidation that filled it: three months of nightly eight-hour runs, pausing before business hours so branch operations continued undisturbed. 430+ sites brought into one searchable web explorer, with health monitoring across the same estate.
Enterprise scale for major national banks. Architected and delivered core telephony and voice management infrastructure:
Purpose-built internal foundation. Essential operational systems engineered in-house to maintain zero third-party lock-in:
Operators search a room extension, unsettled calls surface, rates apply by destination prefix and trunk, and a taxed invoice settles the calls on payment. Pure Java 11 on Jetty 11 — no frameworks, dependencies hand-managed, the whole system auditable in an afternoon.
A parish run like a product. For the Parish of Puspa Gading — Church of St. Andreas Kim Tae-gon — and architected so neighbouring parishes can join next:
Fixing software you don’t control. SAPA is the Archdiocese of Jakarta’s (KAJ) programme-governance system for tracking and monitoring the execution of Program Karya across parishes. This extension — published on the Chrome Web Store and Firefox Add-ons — layers an attention dashboard over it: pending program proposals, progress updates, and accountability reports that require action surface the moment you log in, alongside form-usability and contrast fixes throughout. Built and supported personally; used across the diocese. eprokar.gaudium.casa →
ChallengeAttendance caps during the pandemic were handled by belarasa.id, the archdiocese's own booking app. The painful part was downstream: getting the resulting tickets to the people who held them — volunteers above all — was a manual job that fell on parish administrators, every single Mass.
ResultA companion system that let a booking's belarasa ticket be found and viewed by the person who made it, without an administrator in the middle. It grew from there — and was retired on time when the need ended.
Software with a life span designed in. Born alongside belarasa.id to put pandemic mass tickets in their holders' hands, it grew into QR check-in identity records, then closed its arc issuing Jubilee Year 2025 attendance certificates with digital seals — including Porta Sancta visit tracking. Served the St. Yakobus and St. Andreas Kim Tae-gon churches, then was retired, its purpose fulfilled.
Cloud storage that thinks locally. One web interface unifying local disks, SSH/SFTP, and Google Drive — then what no storage UI has: an LLM agent that actually works on your files. Through tool-calling it reads, writes, and patches them, greps across whole trees, and runs commands on the remote host — with a full browser terminal over WebSocket alongside. Any OpenAI-compatible endpoint drives it, self-hosted Ollama included, so nothing has to leave the machine. Embedded Jetty 12, Jakarta stack, OpenID Connect. Privacy is not a setting; it is the architecture. aether.ing → github.com/peprasetya/aether.ing →
A DBA tool that answers in plain language. One WAR, dropped into any servlet container: a web console that works against any database with a JDBC driver. OpenID Connect sign-in, and an AI query assistant backed by a local Ollama model — your schema and data never leave the machine. github.com/peprasetya/jWebDBAdmin →
A media server light enough to forget. Streams video directly from Google Drive, pCloud, FileLu, and OneDrive — HLS playback, on-the-fly MP4 box indexing, cover art and thumbnails, and subtitle handling. No transcoding farm, no database sprawl. github.com/peprasetya/Vibrefy →
“Low & high” means I have implemented the protocol myself and used it at product level.
While the industry debates AI adoption, my production systems already run it — self-hosted, private, useful: an LLM agent managing files in aether.ing, AI-suggested metadata in AppKTG’s document workflow, a natural-language database assistant in jWebDBAdmin. Twenty-eight years of shipping taught me exactly which new things are worth shipping.