Jefferson
Gakuya

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. Architecture is not a phase — it is the ongoing discipline of managing complexity so that each new capability costs less than the last.

Architecture

Designing a Dual-Payment Gateway

The core challenge was integrating two payment providers — Peach Payments and iPay — without coupling business logic to either vendor's API contract. I modelled the domain around a PaymentPort interface, keeping the application layer fully ignorant of which adapter was in use at runtime.

Each provider was encapsulated in its own adapter class — PeachAdapter and iPayAdapter — both implementing the same PaymentPort. The domain layer emitted PaymentInitiated and PaymentSettled events regardless of provider, enabling clean audit trails and idempotent retry logic at the infrastructure boundary.

This boundary isolation meant swapping or extending providers required zero changes to business rules, reducing provider-switch risk from a multi-week re-architecture to a single adapter implementation with a passing test suite.

Domain LayerPaymentPortPeachAdapteriPayAdapter

Multi-Tenant E-Commerce at Scale

Operating at 10,000 concurrent users required tenant isolation that did not compromise query performance. I chose a schema-per-tenant PostgreSQL strategy: each tenant receives a dedicated schema, with a shared public schema for cross-tenant metadata.

A Tenant Resolver middleware reads the subdomain on every incoming request and sets the active search_path before the ORM layer executes any query. Connection pooling was implemented with PgBouncer in transaction mode, ensuring schema affinity without exhausting connection limits under peak load.

The caching layer sits above the resolver: tenant-scoped Redis key namespacing prevents cache poisoning while enabling per-tenant TTL policies. The system sustained 99.9% uptime across a six-month observation window.

RequestTenant ResolverPgBouncerIsolated SchemaRedis · tenant-namespaced keys

Microservices with Go and Node.js

The system was decomposed into bounded contexts aligned with business capabilities: Order, Inventory, Notification, and Analytics. Go handled the performance-critical Inventory and Order services; Node.js managed the event-rich Notification service.

Services communicate exclusively through a message bus. No service calls another directly over HTTP in the happy path, eliminating tight temporal coupling. Schema contracts for events are enforced at the bus boundary using versioned Avro schemas.

Domain events — OrderPlaced, StockReserved, NotificationQueued — flow in one direction through the bus. Each service owns its own datastore, meaning Inventory uses PostgreSQL while Analytics projects into a read-optimised ClickHouse instance.

Event BusOrder (Go)Inventory (Go)Notification (Node)Analyticsversioned Avro schemas at bus boundary

Offline-First Mobile Architecture

The application was required to function fully without connectivity in field environments. I designed a local SQLite store as the primary source of truth for all reads and writes. The UI never queries the remote API directly.

A Sync Engine runs as a background process. It queues mutations locally, serialises them with a monotonic sequence ID, and flushes to the remote API when connectivity is detected. Conflict resolution uses a last-write-wins strategy at the field level, with a merge fallback for structured list fields where LWW would cause data loss.

The sync engine exposes a status observable that drives the UI's connectivity banner — syncing, pending, error — giving users clear signal without requiring them to understand the underlying replication protocol.

SQLiteprimary storeSync Enginequeue · flush · statusLWW + merge conflict resolutionRemote APIREST · idempotent

Toolbox

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

Writing

Essays on system design, distributed patterns, and engineering trade-offs. Coming soon.

Contact