Software Engineer — Systems & Architecture
I design systems where the boundaries are explicit, the contracts are enforced, and the failure modes are understood before the first line of code is written.
I don't just write code — I architect systems that scale. My work lives at the intersection of domain-driven design, distributed systems, and clean architecture. I think in bounded contexts, communicate through event buses, and sleep better when there's 90%+ test coverage.
Every system I touch starts with one question: "How do we make the next feature cheaper than the last?"
Languages TypeScript · Go · JavaScript
Architecture Domain-Driven Design · Clean Architecture · Event-Driven · Microservices
Infrastructure Docker · Kubernetes · AWS · CI/CD
Quality Test-Driven Development · 90%+ Coverage · ESLint · Prettier
These aren't just projects — they're systems with stories. Each one taught me something about boundaries, trade-offs, and the cost of complexity.
💳 Dual-Payment Gateway — Ports & Adapters Pattern
Integrated two payment providers (Peach Payments + iPay) without coupling business logic to either vendor's API. Modelled the domain around a PaymentPort interface with provider-specific adapters. Domain events (PaymentInitiated, PaymentSettled) flow regardless of provider — swapping providers requires zero changes to business rules.
Key insight: The best abstractions make vendor lock-in a non-issue.
🏢 Multi-Tenant E-Commerce — 10K Concurrent Users, 99.9% Uptime
Schema-per-tenant PostgreSQL strategy with tenant-scoped Redis key namespacing. A TenantResolver middleware reads the subdomain and sets the active search_path before any ORM query. PgBouncer in transaction mode ensures schema affinity without exhausting connections. Sustained 99.9% uptime across six months.
Key insight: Isolation is cheap when you design for it from day one.
⚡ Go + Node.js Microservices — Event-Driven Decomposition
Bounded contexts (Order, Inventory, Notification, Analytics) decomposed by business capability. Go handles performance-critical services; Node.js manages event-rich Notification. Services communicate exclusively through a message bus with versioned Avro schemas — no direct HTTP in the happy path. Each service owns its datastore.
Key insight: If your services need to talk synchronously, they're not really separate services.
📱 Offline-First Mobile — Local-First Sync Engine
Local SQLite as the primary source of truth. A background Sync Engine queues mutations with monotonic sequence IDs, flushing to the remote API on connectivity. Conflict resolution uses last-write-wins at the field level with merge fallback for structured lists. The sync engine exposes a status observable driving the UI's connectivity banner.
Key insight: The network is a detail, not a dependency.
- Writing about system design, distributed patterns, and engineering trade-offs ✍️
- Pushing deeper into Go for high-throughput backend services
- Building developer tools that enforce architectural boundaries at compile time
- How to decompose a monolith without losing your mind (or your data)
- Domain modelling that actually survives contact with production
- The art of making infrastructure invisible to your business logic
- Why your "microservice" might actually be a distributed monolith
Architecture is not a phase — it is the ongoing discipline of managing complexity so that each new capability costs less than the last. 🚀



