Blogs

A space for thoughts, observations, and things worth documenting. Covering technology, creativity, workflows, ideas, and everything in between.

24 posts · page 1 of 3

Deploying UmimaClean: AdonisJS on a VPS with GitHub Actions

Taking a real AdonisJS 7 and Inertia application from a push on master to a running production service - what `node ace build` produces, a two-stage Containerfile, Postgres and the app as Quadlet units, a CI pipeline that builds to GHCR and deploys over SSH, and the proxy detail that silently breaks rate limiting.

adonisjsgithub-actionsdeploymentpodman
The UmimaClean Stack, Part 13: Testing an Inertia App with Japa

The final part - three suites split by what each proves, asserting on Inertia props instead of parsing HTML, factories with states that name business situations, organising tests by role because that is what breaks, and an honest account of what is not covered.

japatestingadonisjsplaywright
The UmimaClean Stack, Part 12: Auth, Shield, Limiter, and Drive

The security layer in full - phone-number identity, why a signed-cookie session still has to be revocable, the passwordChangedAt trick, CSRF with a webhook exception, five rate limiters keyed on different things, private file storage with signed URLs, and the accounts that cannot be deleted.

adonisjssecurityauthenticationrate-limiting
The UmimaClean Stack, Part 11: Tailwind 4, Base UI, and Recharts

The frontend layer in detail - config-in-CSS and what disappeared with tailwind.config.js, why components are copied rather than installed, cva variants over prop soup, atomic-design folders that actually answer a question, and charts that theme themselves through CSS variables.

tailwindcssreactbase-uirecharts
The UmimaClean Stack, Part 10: ExcelJS, Exports, and the Timezone Bug Nobody Notices

Building spreadsheet exports an owner actually uses - why numbers must be numbers, the UTC-components bug that shifts every date by a day, a generic sheet builder that erases its own type parameter, frozen headers and autofilters, and why the export must never stop at the current page.

exceljsreportingadonisjsluxon
The UmimaClean Stack, Part 9: Fonnte, WhatsApp, and a Notification Channel With No Email

Building on WhatsApp because that is where the customers are - why there is no email field anywhere, the unofficial API trade-off, an endpoint that returns HTTP 200 to report failure, signed URLs that carry their own identity, and why reminders are sent by hand.

fonntewhatsappadonisjsnotifications
The UmimaClean Stack, Part 8: Midtrans and QRIS Payments End to End

Integrating an Indonesian payment gateway properly - Core API versus Snap, why the Midtrans order id cannot be your order number, the SHA-512 webhook signature that is the whole security of the flow, mapping five gateway statuses onto four of your own, and the escape hatch for the callback that never arrives.

midtranspaymentsqrisadonisjs
The UmimaClean Stack, Part 7: Leaflet, Pinpointing, and Geospatial Rules

Building an address picker people can actually use on a phone - why the marker is fixed and the map moves, react-leaflet hooks, the tile layer licensing corner, Haversine distance for route ordering, and a service area that is not a circle.

leafletreactmapsgeospatial
© 2026 r3p.dev. All rights reserved.