Etobicoke · Ontario · Canada Open to full-time roles

Chibuchi VictoryOffia

Full-Stack Software Engineer

I build production systems end to end — the Postgres schema and the authorization rules that guard it, the FastAPI and Next.js services on top, the React front ends people actually use, and the deployment automation that puts all of it on a server. Most recently at a cybersecurity compliance SaaS company, where I was principal author of seven backend services and the federated front end that consumes them.

10Backend services shipped
970+HTTP API endpoints authored
14Front ends & micro-frontends
239Postgres tables modelled
10Languages localised

Counted in August 2026 from my own repositories — route decorators for endpoints, table declarations for tables, locale files for languages. Nothing here is an estimate, and I can show you the commands.

Selected work

Six projects · 2024–2026

Enterprise Security & Compliance Platform

In production

Backend & front-end engineer · Feb 2025 – Aug 2026 · Commercial employer · described at a high level, without product names or internal detail

A multi-tenant cybersecurity and compliance SaaS sold to companies that must prove where their employees’ data physically lives and control who inside the organisation can see what. I worked across the whole system: the event-driven Python services that hold the data, and the federated React front end that presents it.

On the backend that meant an org tree — company, group, branch, department, employee — where every score, report and policy decision is scoped to the caller’s own tenant and slice. Services never call each other for domain data; every cross-service fact arrives as a Kafka event and is materialised into a local read model. I also built a multi-region data-residency control plane that moves an entire tenant’s data between geographic zones on demand, with four fail-closed regions and an eight-state migration lifecycle.

The last of these services is a metered AI assistant: it answers questions from live product data through nineteen hand-written tools, and it holds no service credential of its own — every tool call goes out with the asking user’s own token, so the product API stays the only authorization boundary and the assistant can never read a row that person couldn’t open themselves. Billing a streaming answer whose cost isn’t known until it finishes meant a reserve-then-commit ledger: set aside the worst case before the first token, commit the real figure at the end, so a balance can’t go negative and an abandoned stream expires instead of quietly eating credit. Across the eight services I was sole or principal author of seven and co-developed the eighth with a colleague.

The hard part

Both product homepages rendered a white screen on iPhone — and only on iPhone. Nothing returned a 500, no build failed, curl was green, and no React error boundary ever fired.

I traced it to Module Federation shared-dependency drift. Every app carried ^19.2.x, so each npm install had resolved a different patch of React. Federation collapses a shared singleton down to one copy — and whichever copy won the load race got paired with another app’s renderer, throwing React error #527 before anything could mount. Desktop Chrome happened to win the race; WebKit did not. The fix was to pin every shared singleton to one exact version across all four codebases, move the federation share strategy to loaded-first so the entry chunk stops waiting on a preload of every remote, and add a version assertion to the deploy scripts so the drift can never come back silently. I reproduced it with Playwright’s WebKit engine, because Chromium never showed the bug.

  • Python 3.13
  • FastAPI
  • SQLAlchemy 2
  • Pydantic v2
  • PostgreSQL 17
  • Apache Kafka
  • Redis
  • React 19
  • Module Federation
  • Vite
  • TypeScript
  • i18next
  • Anthropic Claude
  • Google Gemini
  • PM2
  • nginx
  • GCP
Services
8
Endpoints
778
Tables
155
Kafka consumers
55
Front ends
9
Locales
10

Company code lives on a private GitLab, so it isn’t linkable. Sign-in, the API gateway, DNS and TLS were owned by teammates — I built the services and the product front ends that sit behind them. Happy to walk through any of it in an interview.

Offia’s Studio

Live

Sole developer · Jun – Aug 2026 · My own web practice · offiastudio.tech

The storefront for my own web-design practice. A business owner can click through twelve working sample websites built for their own industry, submit a project brief that an AI helper will tidy up for them, and then follow the build on a live status page with a delivery countdown, a deliverables vault and a support thread.

Because the person editing the site isn’t a developer, ninety-six pieces of public copy — plus services, pricing, portfolio, testimonials, FAQs and navigation — are editable from an admin dashboard rather than a code deploy. The content editor mounts the real public page components inside the admin shell and feeds them the unsaved draft, so what you preview is the actual page, not a re-implementation of it.

The hard part

I audited the app before launch and found a way to make myself an administrator. The signup trigger copied the new user’s role straight out of raw_user_meta_data — which is attacker-controlled input, because anyone can pass arbitrary metadata to signUp(). Any visitor could have registered as an admin.

I fixed it in depth rather than at one layer: the trigger now hard-codes role = 'client' and deliberately does not update the role on conflict, so re-registering can’t escalate or downgrade an existing account; a separate guard trigger reverts any client-side attempt to write the column; and the row-level INSERT policy pins all eight privileged fields, so a client can only ever create a clean, owned, pending request. That was one of twelve findings I wrote up and remediated in a migration before the site went out.

  • React 18
  • TypeScript
  • Vite 5
  • Tailwind
  • TanStack Query
  • Framer Motion
  • Supabase
  • PostgreSQL + RLS
  • Vercel serverless
  • Google Gemini
Lines of TS
38,556
Tables
21
RLS policies
57
Routes
43
Demo sites
12
Serverless fns
4

No application server: the browser talks to Postgres directly and every authorization decision is a row-level-security policy. The twelve demo sites are self-contained samples with mock data, not delivered client work.

Luamé

Live · client

Sole developer · Jun – Jul 2026 · Braiding salon, Mississauga ON · luame.vercel.app

A braiding and natural-hair salon in Mississauga was taking every appointment through Instagram DMs: no published availability, no way for a customer to see which slots were already gone, and a real chance of promising the same hour to two people. Luamé is a public booking site plus an owner-only portal. The customer picks a style, sees live availability, books, and confirms over WhatsApp — deliberately, because that is the channel her customers actually use. The owner accepts, reschedules or completes in one tap, edits her own price menu, and blocks days off. It is live and serving her real prices today.

The hard part

Two customers can open the booking page at the same moment, see the same free slot, and both submit. A check-then-insert in JavaScript loses that race, and the owner turns up to a double-booked Saturday.

I made the database the arbiter instead of the client: a partial unique index on (appointment_date, appointment_time) restricted to active statuses, so Postgres rejects the second insert atomically — and because the index is scoped to pending and confirmed, cancelling a booking frees the slot again with no extra code. The UI catches the 23505 unique violation, re-fetches availability and tells the customer the slot just went. Showing live availability then collided with the privacy model, since row-level security correctly stops one customer reading another’s bookings — so a SECURITY DEFINER function returns only the busy time strings, and by its return type alone can never emit a name, an email or a phone number.

  • Next.js 14 App Router
  • React 18
  • TypeScript
  • Tailwind
  • Supabase Auth
  • PostgreSQL + RLS
  • Vercel
Tables
6
RLS policies
13
Routes
10
Custom API endpoints
0

Zero API endpoints is the design, not a gap — server components and the browser client read Postgres directly under RLS. WhatsApp is free click-to-chat deep linking, not the Business API.

RankAfrica

Live · pre-launch

Sole developer · Jun – Aug 2026 · Client project · rankafrica.org

Nigerian institutions grade on 4.0, 5.0, 7.0 and raw-percentage scales with very different rigour, so a 4.2/5 at one school cannot honestly be compared to a 4.7/5 at another. RankAfrica standardises every credential onto one 100-point index, adds discipline-appropriate evidence scoring on top, and publishes a leaderboard that vetted recruiters can search. Students build their own profile and apply to opportunities; administrators run submission cycles, verify evidence and approve who appears publicly. One repository deploys as two separate projects — a FastAPI backend and a React front end.

The hard part

A flat ratio conversion would have let a weak school’s First Class outrank a strong school’s. I wrote a five-stage equivalency engine instead: resolve the native grading scale, classify into the local class-of-degree band, project onto a WES-style US 4.0 band by piecewise-linear interpolation rather than a ratio, apply an institutional-rigour factor with a floor so no school can be scored into the ground, and emit an auditable breakdown at every stage.

A second problem was reproducibility: four students on an identical 38.5 were being rendered as ranks 1, 2, 3, 4 from an unstable sort. I rewrote rank assignment as standard competition ranking — 1, 2, 2, 4 — with the student id as a deterministic secondary key, and reused that one routine across all four ranking scopes. The AI-scored components are computed once and stored on the row, so a full leaderboard recompute is pure arithmetic with zero model calls. That single decision is what makes recomputing the whole board affordable.

  • Python 3.11
  • FastAPI
  • SQLAlchemy 2
  • Pydantic v2
  • PostgreSQL
  • JWT + RBAC
  • React 18
  • Vite
  • Zustand
  • OpenAI gpt-4o-mini
Endpoints
149
Tables
28
Front-end routes
48
Lines of Python
12,609

Publicly live and pre-launch: the leaderboard stays hidden behind an administrator toggle until the first submission cycle closes. Authorization here is FastAPI dependency checks, not RLS — the browser never touches Postgres.

PaceRace

MVP · 139 tests

Sole developer · May – Aug 2026 · Personal product · FastAPI + Expo React Native

Fitness trackers are asynchronous: you record a run, upload it, and compare numbers afterwards. PaceRace makes it synchronous — several people start the same distance at the same moment and everyone sees a live per-second leaderboard of who is ahead while they are still running. Solo athletes race a “ghost” replayed from their own fastest previous effort. The backend and the mobile app share a hand-written TypeScript mirror of the Pydantic WebSocket contract, so a change to a message type breaks the build rather than the race.

The hard part

N runners each sending GPS once a second naively produces N² socket writes per second, per race — and every one of those writes costs somebody’s phone battery.

I capped it in two places. Each participant is admitted at most once per second, and a single background ticker per race broadcasts a coalesced leaderboard only when the state is actually dirty — so the broadcast rate is one per second for the whole race no matter how many people are in it. Across multiple server workers, frames fan out over Redis Pub/Sub with a per-worker origin tag, so a worker skips its own re-published frames and every client receives each message exactly once. A subtler bug came later: finishing positions were being assigned by the order frames arrived, so a slower runner on a faster connection could be ranked ahead. Positions are now derived from finish time, in both the in-memory hub and the database re-rank — because those two have to agree.

  • Python 3.11
  • FastAPI
  • WebSockets
  • async SQLAlchemy 2
  • PostgreSQL 15
  • Redis 7 Pub/Sub
  • Alembic
  • Docker Compose
  • Expo / React Native
  • TanStack Query
  • pytest
  • mypy --strict
Automated tests
139
Routes
28
Tables
10
Lines of code
12,100

72 pytest + 67 Jest tests, all passing, with mypy --strict clean across 48 source files — this is the project where I own the test suite. Complete MVP; not deployed and not submitted to an app store.

Amarex

Built

Sole developer · Jul 2026 · Client project · Next.js 14 + Supabase + Paystack

A paid trading-education membership platform. Paystack collects the subscription, a private course library and live market signals sit behind it, and Claude turns each uploaded course PDF into a per-student assessment that is timed, monitored by a browser extension, auto-graded and then reviewed by a human. Rejecting a paper mints a brand-new personalised set from the same question bank, so a retake is never the same exam twice.

The hard part

In an architecture where the browser queries Postgres directly, an exam answer key is one hand-written request away from the student sitting the exam. Row-level security wasn’t enough, because the row a student is permitted to read is the row that contains the key.

I moved the boundary from rows to columns. The question bank is fully revoked from the anonymous and authenticated roles, and the assignment table has ALL revoked with an explicit GRANT SELECT on only its ten non-key columns — so select('*') raises permission denied for everyone, and the key can be read only by the server route that grades the paper. The same instinct governs money: the price always comes from the plans table rather than the request body, and Paystack is verified twice server-side — an HMAC-checked webhook and a return-trip verify — both converging on one idempotent activation function, so a closed tab or a dropped webhook still activates exactly once.

  • Next.js 14 App Router
  • React 18
  • TypeScript
  • Radix UI
  • Supabase Realtime
  • PostgreSQL + RLS
  • pg_cron
  • Paystack
  • Anthropic Claude
  • Zod
  • Chrome MV3 extension
Tables
19
RLS policies
49
Editable copy fields
125
Zod schemas
23
Scheduled jobs
3

Built and type-clean, awaiting the client’s production environment. The proctoring extension is a deterrent that records ten event types into a reviewable timeline — it is not, and is not claimed to be, tamper-proof invigilation.

Skills

Depth — measured, not asserted

Languages

  • Python
  • TypeScript
  • SQL
  • JavaScript
  • HTML & CSS
  • Bash / PowerShell

Backend

  • FastAPI
  • SQLAlchemy 2 (sync + async)
  • Pydantic v2
  • Next.js route handlers
  • WebSockets
  • Node.js (serverless, tooling)
  • Alembic

Front end

  • React 18 / 19
  • Next.js 14 App Router
  • Vite
  • Module Federation
  • TanStack Query
  • Tailwind CSS
  • i18next (10 locales, RTL + CJK)
  • React Native / Expo

Data

  • PostgreSQL
  • Supabase (Auth, RLS, Storage)
  • Apache Kafka
  • Redis (cache, pub/sub, limits)
  • SQLite

Security

  • JWT auth + refresh rotation
  • Row-level security design
  • RBAC & permission catalogues
  • Multi-tenant isolation
  • Payment verification (HMAC)
  • Ed25519 signing & JWKS

AI integration

  • Anthropic Claude (tool calling)
  • Google Gemini
  • Retrieval-augmented generation
  • Provider-agnostic abstraction
  • Token metering & cost control
  • OpenAI API

Infrastructure

  • Linux VM operations
  • nginx reverse proxy
  • PM2 process management
  • Release automation & rollback
  • Git
  • Vercel
  • Docker Compose

Also worked with

  • PHP & Laravel — production backends at Eleastar Technology, 2024–25
  • Java SE 8 — Oracle OCA & OCP coursework, 2024
  • Oracle 12c — fundamentals & administration, 2024
  • CompTIA A+ — hardware, OS and endpoint support, 2024

Listed separately on purpose: these are real, but they are not what I have been shipping this year. Everything in the columns to the left is backed by code in my own repositories.

Daily — I reach for this first Strong — shipped it repeatedly Working — used it in production, still growing

How I work

Authorization belongs in the database

UI checks are a courtesy; the real boundary should be a policy, a grant or a constraint that holds even when someone bypasses my code entirely. Three of these projects have no application server at all — every rule is enforced by Postgres, and I have found and fixed real escalation bugs in my own schemas by assuming an attacker skips the front end.

Let the database win the race

Correctness that depends on a read-then-write in JavaScript is correctness you lose under concurrency. Unique indexes, atomic constraints and idempotent activation functions turn whole categories of bug into an error code I can handle, instead of a support call from a customer who was double-booked or double-charged.

Measure it, then claim it

Every number on this page came from a command I ran against my own repositories, and I kept the commands. The same habit applies to bugs: I reproduced an iOS-only white screen in Playwright’s WebKit engine rather than guessing, because a fix you cannot demonstrate is a fix you cannot trust.

Build the pipeline you don’t have

Where there was no CI, I wrote the release tooling myself — roughly four thousand lines of deployment automation with health checks, atomic swaps, version assertions and rollback, so shipping was a repeatable command rather than a careful afternoon. I would rather join a team that already has this, and I know exactly why it matters.

Experience

Feb 2025 – Aug 2026

Security Software Engineer

Emutare Technologies Pty Ltd
  • Designed and shipped event-driven Python microservices for a multi-tenant cybersecurity and compliance platform, plus the React front ends that consume them.
  • Built a multi-region data-residency control plane letting a customer relocate an entire tenant’s data between geographic zones, with fail-closed regions and a resumable migration lifecycle.
  • Integrated LLM providers behind a single swap point for policy checking and reporting, with a circuit breaker so a provider outage degrades the feature instead of the product.
  • Localised the product suite into ten languages, including right-to-left and CJK, across a shared language bus.
  • Performed security review of authorization paths and closed privilege-escalation and cross-tenant data-exposure defects.
  • Wrote the deployment automation — health checks, atomic releases, version assertions and rollback — for a self-managed Linux estate.
Jun 2025 – Jun 2026

IT Executive (NYSC)

Swiss International Rancho Valeria · Warri, Nigeria
  • Led day-to-day IT operations and aligned technology initiatives with business priorities.
  • Oversaw infrastructure upgrades and digital-transformation work across the property.
  • Established IT governance, cybersecurity and data-protection practices.
  • Improved processes through automation and system optimisation; mentored a cross-functional IT team.
Jun 2024 – Jan 2025

Software Developer

Eleastar Technology Limited
  • Built backend systems and APIs in PHP and Laravel for production web platforms.
  • Designed responsive interfaces and integrated third-party services.
  • Wrote unit, integration and system tests; debugged, optimised and refactored existing systems.
Jan 2023 – Jun 2024

Web Development Tutor

NIIT Warri · Global Adpis Computers Ltd.
  • Taught modern web development to learners at very different levels of experience.
  • Covered APIs, SQL and NoSQL databases, authentication, Node.js and Django, plus responsive design and version control.
  • Wrote lesson plans and materials that made complex concepts land, and mentored students through debugging and portfolio projects.
2023

IT Support / Software Trainee

Modasco Nigeria Limited
  • Supported internal IT operations and software projects; recognised with a Certificate of Appreciation.

Education & certifications

Education

  • BSc, Software Engineering Babcock University · Ilishan-Remo, Nigeria · 2020–2024 Software design and architecture, algorithms and data structures, database systems, web technologies, project management. Final-year capstone covering end-to-end delivery.

Certifications

  • Python Programming & Web Development NIIT Warri · Mar 2025 Python, Django, SQLite, MySQL and application deployment.
  • Multi-Track IT Program New Horizons Worldwide · Jul 2024 CompTIA A+ Core 1 & 2, Certified Secure Computer User, Oracle 12c Fundamentals & Administrator, Java SE 8 OCA & OCP.

Recognition

  • Certificate of National Service NYSC · Jun 2025 – Jun 2026
  • Certificate of Recognition Swiss International Rancho Valeria · May 2026
  • Certificate of Appreciation Modasco Nigeria Limited · 2023

Get in touch

I’m looking for a full-stack or backend engineering role in the Greater Toronto Area or remote across Canada. If you want to dig into any of the work above — the schema, the failure, the decision I’d make differently now — I’d enjoy that conversation.

Location
Etobicoke, Ontario
LinkedIn
chibuchi-offia

Figures on this page were counted from my own git repositories in August 2026: endpoints from route decorators, tables from model and schema declarations, tests by running the suites, locales from locale files. Work done for my employer is described at a high level without product names, and its code is not linkable because it lives on a private company GitLab. Where a project is built but not deployed, this page says so.