Available for new opportunities

Crafting scalable Backend & Web systems.

Full Stack Developer with 8+ years of experience in React, Next.js, and NestJS. Expert in building scalable web applications, managing monorepo architectures (Turborepo), and running a disciplined multi-model AI workflow — agent operating docs, structured prompting, and machine-enforced review gates.

Technical Expertise

Languages

TypeScriptJavaScriptPythonPHPSQL

Frontend

Next.js (App Router)ReactVue.jsTailwind CSSRadix UIStorybook

Backend

NestJSExpressJSDjangoLaravelStrapiContentful

Cloud / AI

GCPAWSTurborepoPrompt Engineering (CO-STAR)Multi-Model AI Workflow (Claude / Grok / Cursor / Gemini)Agent Tooling (skills, hooks, subagents)

How I Work With AI

AI assistants are fast and confidently wrong. The leverage comes from what surrounds them — written ground truth, explicit standards, and gates a machine can check.

ClaudeGrokCursorGemini

Agent operating docs

Maintain repository-level operating manuals that give coding agents an authoritative file map, documented architectural patterns, and context-efficiency rules — so an agent starts from ground truth instead of re-deriving the codebase every session, and gets the architecture right the first time.

Structured prompting over prompt luck

Frame requests with CO-STAR (Context, Objective, Style, Tone, Audience, Response) and a defined engineering persona: scope discipline, blast-radius checks before touching shared code, explicit one-way-door callouts, and a rollback path for risky changes.

Multiple models, chosen per task

Work across Claude, Grok, Cursor, and Gemini rather than committing to one, and use a second model for an independent read on design and review calls where a single confident answer is the failure mode.

Machine-enforced review gates

Every AI-assisted change goes through the same branch, pull request, and lint/test/build gate as hand-written code — plus repo-specific CI checks that turn review conventions into build failures, so the standard holds regardless of who or what wrote the diff.

Extending the toolchain

Build custom skills, prompt-submit hooks, and plugins that encode process rules directly into the environment — for example, a hook that forces a feature branch before any edit can land on a protected branch.

Output is a draft, not a deliverable

Re-verify agent findings against the code before acting on them, require stated tradeoffs and rejected alternatives instead of a single confident answer, and write decisions and their reasoning back into the repo so the next session inherits the context rather than re-litigating it.

Professional Experience

A timeline of my professional career.

Backend Developer (Freelance)

Unicept Richmond, BC (Remote)
Aug 2026 - Present
  • Led the migration of Genie Player — an AI video platform that generates translated captions — from a TypeScript API and media worker to Go, porting shared business-logic packages, the auth/teams/workspace layer, and Stripe billing service by service rather than in a single cutover.
  • Replaced Prisma schema management with sqlc and goose, shipping a cutover that auto-adopts pre-cutover Postgres data on container start so existing environments migrate without a manual reset.
  • Introduced River, a Postgres-backed job queue, for the AI translation pipeline, and reported job progress incrementally within each stage instead of only at stage boundaries.
  • Built the cross-platform Docker Compose development stack and added Go build stages and CI for the API and worker services.
  • Gave the OpenAI/Groq providers a shared pooled HTTP client, removing per-request connection churn under concurrent translation jobs.
  • Tracked the migration as a documented epic with numbered sub-issues, merging each phase through its own reviewed pull request.

Full Stack Developer

Apply Digital Ltd. Vancouver, BC (Remote)
Sept 2021 - Present
  • Architect consumer-facing web applications using Next.js App Router and Turborepo monorepos.
  • Developed specialized internal LLM skill agents using the CO-STAR prompting template to automate repetitive ticket analysis and code suggestion tasks.
  • Lead Contentful CMS integration via GraphQL and reusable UI adapters to decouple business logic from presentation.
  • Leverage AI-augmented engineering for complex PR reviews and refactors, holding every AI-assisted change to the same review, test, and lint standards as hand-written code.
  • Engineer NestJS backend services with automated GCP deployments via Bitbucket Pipelines.

Full Stack Developer

BC Public Service Victoria, BC (Remote)
Jan 2021 – Sept 2021
  • Implemented enterprise ETL processes using Oracle Data Integrator (ODI).
  • Designed complex ODI mappings for large-scale data transformation and warehousing.
  • Modernized legacy data flows by integrating ODI with RESTful APIs.
  • Managed Jenkins/SVN pipelines for secure government application deployments.

Backend Developer (Freelance)

Yozify Burnaby, BC
Nov 2019 – Feb 2020
  • Architected RESTful and GraphQL APIs using Strapi (Node.js).
  • Managed cloud resources on AWS (S3/EC2) and implemented GitHub Actions CI/CD.

Full Stack Developer

Reason Investment Inc. Richmond, BC
Dec 2018 – Jan 2021
  • Aggregated real-time listing data from REBGV and BCRES using ExpressJS.
  • Developed custom RSVP and notification systems (SMS/Email) using AWS.

Backend Developer

Inverse Technology Inc. Vancouver, BC
Apr 2017 – Sept 2018
  • Led backend development for HackHub.com using Python (Django).
  • Managed cross-region data consistency and implemented microservices on AWS.

Full-Stack Developer (Freelance)

Store Ticket Management Burnaby, BC
2015 & 2018
  • Developed a custom PHP/Laravel record management system to digitize and optimize ticket retrieval for retail clients.
  • Architected a responsive dashboard using jQuery UI to provide faster data entry and search capabilities compared to legacy systems.
  • Collaborated directly with stakeholders to gather requirements and deliver recurring product demonstrations.
  • Optimized MySQL database queries to handle thousands of historical records with sub-second search latency.

Selected Projects

Self-directed work, built and maintained end to end.

car-radar

Serverless car-listing alert pipeline

Jul 2026 - Present
TypeScriptNetlify FunctionsSupabaseIMAPVitest
  • Watches saved-search alert emails from AutoTrader and Kijiji over IMAP, extracts listings, filters them against a budget, deduplicates against prior runs, and persists a digest log to Supabase.
  • Resolved Kijiji click-tracking redirects to obtain a stable listing identity after the original deduplication key proved unstable in production — a course correction made mid-build rather than shipped as a known defect.
  • Rewrote the AutoTrader adapter against real alert markup once production email HTML diverged from the fixtures the parser was built on.
  • Pings an external monitor at the end of every successful run, so a pipeline that stops firing is visible rather than silent.
  • Specification-first: product brief, PRD, and architecture written before implementation, then broken into numbered stories each shipped as its own pull request.

et-misc-usage

Self-hosted personal platform — auth, media tracking, file storage

Nov 2022 - Present
Next.js App RouterTypeScriptMongoDBZodVitestOpenAPI
  • Migrated a legacy NestJS and Create React App codebase to a single Next.js App Router application, keeping the legacy tree as read-only reference for behavioural parity during the port.
  • Built authentication without a JWT library: HMAC-signed session tokens with key rotation, scrypt hashing, and a database-backed signin throttle that runs before the password hash so response timing cannot be used as an oracle.
  • Closed a user-enumeration vulnerability where deactivated accounts responded differently than unknown emails, confirming which addresses were registered before any password was checked.
  • Implemented zero-knowledge one-time secret sharing — AES-256-GCM encryption in the browser with the key carried only in the URL fragment, plus atomic delete-on-read — so the stored record alone can never be decrypted.
  • Enforced quality through a single CI gate: lint, unit tests, production build, and a custom script that fails the build when any API route is missing from the OpenAPI spec.