Evtrify
Founding Engineer · Backend, Platform & Mobile
Engineering ownership
My work at Evtrify spans both sides of the product: the backend platform that owns charging and reservation state, and the Expo/React Native application that drivers and charging-station operators use. I have contributed across station discovery, bookings, charging sessions, confirmation and release flows, disputes, ratings, trips, notifications, authentication/onboarding, design-system work and the client integration of those contracts.
The consistent engineering principle is that the client renders authoritative state rather than inventing it. Ownership, lifecycle eligibility, idempotency, concurrency control and sensitive transitions remain server-enforced, while the mobile layer handles identity-scoped caching, loading and stale states, unknown network outcomes and high-fidelity interaction design.
Scope at a glance
Go/PostgreSQL domain work across charging stations, bookings, charging sessions, ratings, disputes, trip planning, notifications and connector contracts.
Expo, React Native, TypeScript, Expo Router and TanStack Query across driver, operator, auth, onboarding, reservation, charging and recovery experiences.
Database transactions, lock ordering, uniqueness backstops, deterministic retry behaviour, BOLA/RBAC, bounded queries and explicit ambiguous-outcome recovery.
OCPI integration research and architecture for connecting Evtrify with external CPO/eMSP platforms, CPMS systems and roaming networks.
Backend domain foundations
I helped establish and extend the backend domains around the charging-station experience rather than treating the product as a collection of isolated endpoints.
- Bookings and reservations: owner-scoped booking creation and reads, connector conflict protection, historical station/connector snapshots, reservation state, conflict alternatives and recovery actions.
- Charging stations: station/connector contracts, catalog convergence, public reads, ownership boundaries and compatibility with downstream bookings and trips.
- Charging sessions: secure confirmation PIN verification, authoritative session start, progress, termination and operator release boundaries.
- Ratings and disputes: relationship/evidence checks, completed-session rating eligibility, public/admin reputation reads and transaction-safe dispute workflows.
- Trip planning: station selection and routing-domain integration with bounded request/query behaviour and connector compatibility.
- Notifications: transactional product-notification persistence, deterministic event identity and durable outbox delivery foundations.
Charging lifecycle and server-authoritative state
The charging workflow was extended into a real state machine that can support both driver and operator experiences:
Client screens do not mark charging as started or ended from timers, navigation state or optimistic flags. The API remains the source of truth for session status, occupancy and whether an actor may perform a transition. That same persisted evidence is then reused for downstream behaviour such as station-rating eligibility.
Idempotency, retries and unknown outcomes
A major part of my backend work has been making state-changing operations safe to repeat. Booking creation uses idempotency identity and request fingerprints so a legitimate retry converges on the original booking while conflicting reuse is rejected. Charging-session termination and charger release return persisted terminal state on replay rather than repeating side effects.
The notification pipeline follows the same model with deterministic correlation, notification, attempt and outbox identities. On mobile, ambiguous timeout/network/server outcomes are reconciled by refetching authoritative server state instead of claiming success or failure from local assumptions.
Concurrency, transactions and race conditions
Charging infrastructure is inherently concurrent: two drivers can target one connector, multiple station devices can act on the same booking, and end/release/start operations can race across participants. The backend therefore treats concurrency as part of the domain model.
Booking creation locks the contested station/connector relationship before occupancy and overlapping-reservation decisions are made.
Charging lifecycle work follows a compatible station/connector → booking → session lock order to reduce contradictory state and deadlock risk.
Database constraints protect invariants such as one logical session per booking and one active charging session occupying a connector.
Repeated driver/operator actions converge on persisted state; the mobile client invalidates and refetches participant-scoped cache identities after mutations.
Authorization, BOLA and sensitive relationships
User-scoped routes validate the authenticated principal against the path user, while station, booking, session and rating relationships are re-checked at persistence boundaries. Route parameters, hidden buttons and notification metadata are never treated as authorization.
- Cross-user and cross-station object probes are rejected without trusting guessed UUIDs.
- Station operations require the authenticated operator to own the persisted station/booking relationship.
- Driver actions are scoped to the authenticated booking/session owner.
- Rating eligibility binds the current driver, completed charging session and target station rather than trusting navigation state.
- The mobile cache is keyed by authenticated user, role and exact resource identity so state does not silently carry across principals.
Database and query efficiency
I also worked on reducing unnecessary database work while preserving correctness. The approach is to keep critical paths selective, index-backed and transaction-aware rather than loading broad history into Go and filtering afterwards.
- Replaced count-style evidence checks with targeted SQL existence queries where only existence is needed.
- Moved evidence reads onto the existing transaction connection in rating flows to avoid unnecessary second pool acquisition while a transaction is already open.
- Removed redundant rating aggregate work by reusing the reputation summary's rating count where that value is already authoritative.
- Kept ownership and active-session checks bounded to primary-key/selective lookups rather than list-and-filter application loops.
- Converged older booking/trip connector assumptions on the canonical connector catalog instead of maintaining drifting hard-coded allowlists.
Transactional notifications and durable delivery
I implemented and integrated transactional product-notification infrastructure so booking and lifecycle events can be persisted atomically with the domain change that created them. Delivery work is represented through deterministic identities and an outbox boundary, allowing retries without multiplying the logical event.
On mobile, the driver notification inbox, unread badge and actionable booking notifications consume those server-owned resources. Notification text and resource IDs provide navigation context only; every booking/recovery mutation re-enters authenticated owner-scoped API paths where authorization is evaluated again.
Mobile foundation and frontend engineering
My frontend scope is broader than individual screens. I built the original EV-driver mobile foundation and later continued substantial product work on top of the shared architecture.
- Expo + React Native + strict TypeScript foundation with Expo Router navigation and TanStack Query server state.
- Shared design system and reusable UI primitives rather than screen-specific component forks.
- Driver onboarding, station discovery/detail, reservation flows, booking management, trip planning, ratings, notifications and resilient loading/error/empty states.
- Station/operator workflows including pending-request acceptance, PIN entry/start charging, shared charging progress and authoritative charger release.
- Guest station browsing using public station APIs while auth-gating protected actions without inventing a guest identity.
- Completed-session station-rating flow that derives its target from the authenticated ended session instead of trusting a station ID in navigation.
- Reservation-conflict choice flow that consumes server conflict metadata and retries through normal booking creation rather than client-side locking.
Figma implementation, auth and shared UI
I carried multiple EVTR high-fidelity design revisions into the existing mobile architecture instead of rebuilding the app around isolated mock screens. That work includes splash and authentication redesigns, onboarding, driver and station screens, responsive mobile/web behaviour, bottom navigation, shared button/input/OTP primitives and exact Figma asset integration.
- Built and refined the shared segmented code/PIN input while preserving auth OTP compatibility.
- Added password visibility, disabled CTA states based on required-field completeness, auth-route titles and responsive intro/splash positioning fixes.
- Implemented Nigeria-specific phone-input/normalization behaviour and the associated mobile CI/change-control baseline.
- Maintained accessibility semantics for interactive controls, decorative icons, disabled states and narrow-screen text/layout behaviour.
Client state, caching and failure recovery
TanStack Query keys are scoped around the actual authenticated participant and resource: user, role, station, booking or charging session. Identity transitions clear private cache while public station data can remain shareable because it is identity-independent.
State-changing screens deliberately avoid optimistic domain transitions when the server is authoritative. If a request times out after a possible commit, the UI refetches and lets server state win. This pattern is used across station acceptance, charging termination, operator release, reservation recovery and other mutation-heavy flows.
Verification and delivery controls
Across API and mobile work I added or worked within quality gates covering formatting/lint, strict TypeScript or Go tests, API builds, integration tests, race checks, SQLC and Swagger determinism, dependency/security checks, Expo health/export checks and repository-policy controls.
Where repository runner/policy infrastructure later blocked mobile workflows before any code executed, I documented the exact limitation instead of presenting skipped jobs as green. That distinction is part of the delivery discipline: verification evidence has to match what actually ran.
OCPI interoperability architecture
I researched and designed Evtrify's future OCPI interoperability boundary for connecting with external charging operators and mobility platforms. This is architecture and integration planning, not a claim that a production roaming relationship is already live.
- Version discovery, credentials and counterparty registration/rotation.
- Locations, EVSEs, Connectors, Tariffs, Tokens, Sessions, CDRs and remote Commands.
- Bidirectional synchronization, stable external-to-internal identity mapping and authoritative-source rules.
- Idempotent ingestion/delivery, stale and out-of-order update handling, bounded retries and per-peer failure isolation.
- Durable outbound jobs/outbox behaviour and reconciliation rather than tying external network availability to user HTTP requests.
- Adapter separation so OCPI protocol DTOs remain at the interoperability edge instead of becoming Evtrify's internal booking/session/station model.
Current review work
Some newer lifecycle work remains under review rather than on production main. That includes the shared driver/operator queue lifecycle and the driver's persisted “I'm running late” informational state. I keep those separate from the shipped scope above so the portfolio does not blur implementation status.
Engineering outcome
My EVTRIFY work combines backend state-machine correctness with the product surfaces that consume it: transactional state instead of screen-driven state, persistence-scoped authorization instead of UI trust, database-backed concurrency instead of single-process assumptions, retry-safe side effects, bounded data access, and frontend experiences that reconcile against authoritative server truth.
Discuss comparable engineering work
Open to backend, platform, API, distributed-systems and infrastructure-minded product engineering conversations.
link Book 30min call