Back

Case studyTechnical Lead · Sep 2026 – Present

Fourteen days at Gemaxiom.

A multi-tenant SaaS built fast with an AI coding tool — live on AWS, but with no tests, no infrastructure-as-code, no environments and no deployment pipeline. The core product was one 42,465-line JavaScript file driving a 20,766-line HTML page, with near-identical copies of pages side by side and no way to tell which was live. I was hired to make it production-ready.

Pull requests merged
~300
Commits
1,100+
Versioned releases
135
Automated checks, from zero
~6,650

Sep 16–29, 2026, from git log. Line counts include moved and generated files. The engagement is ongoing.

Sep 16 → Sep 29, 202614 days
  1. Sep 16First commit

  2. Sep 16–22First week: Terraform dev environment, CI/CD, 0 → 91 tests

  3. Sep 20–28React migration: 42,465-line monolith → ~40 routes behind parity tests

  4. Sep 28GitHub Actions stops starting jobs — spending limit reached

  5. Sep 29Full CI gate rebuilt locally; 5 releases reach dev in 3 deploys

The arc — each step made the next one safe

  1. Audit→
  2. Dev environment & CI/CD→
  3. Tests→
  4. Monorepo & dead code→
  5. Local dev→
  6. React migration→
  7. AI agent features→
  8. Staging next

One process, every PR, every agent

  1. Issue→
  2. Worktree→
  3. Semver bump→
  4. Independent reviewer model + self code-review→
  5. Full test suite→
  6. Merge→
  7. Watch the deploy
  1. 01

    Assessment

    • ▸Ran a production-readiness audit of the live multi-tenant SaaS, producing 55 tracked findings across security, infrastructure, architecture and testing.
    • ▸Much of the work was archaeology: establishing what the code actually did, which of several near-identical files was live, and which claims in the tracker were still true — then making the repository state its own answers.
  2. 02

    Infrastructure and delivery — the first week

    • ▸Designed and built a complete AWS development environment entirely in Terraform — ECS Fargate (Spot), CloudFront over a private S3 bucket, an internal ALB reachable only from CloudFront, RDS Postgres 17, Cognito, and a self-healing NAT instance — for ~$35/month.
    • ▸Replaced laptop-run deploy scripts with trunk-based CI/CD in GitHub Actions: every merge to main runs the test suite, builds an immutable image, deploys to dev and smoke-tests the real sign-in flow against it.
    • ▸AWS is reached through OIDC federation with no stored credentials, on a role scoped to a single branch.
    • ▸One image per commit, promoted unchanged between environments, with ECS circuit-breaker rollback.
  3. 03

    Testing, from zero

    • ▸91 checks in the first week, ~6,650 by day 14: 1,236 end-to-end and screenshot-parity specs plus ~5,400 unit tests.
    • ▸They run on every pull request with no AWS access or secrets required — covering multi-tenant isolation asserted directly against Postgres row-level security, session and CSRF handling, environment isolation, role-based permissions and deployment-artefact integrity.
    • ▸Post-deploy smoke tests exercise real Cognito sign-in, which local tests cannot reach.
  4. 04

    Security hardening

    • ▸Moved login sessions from DynamoDB to Postgres and hardened cookie, CSRF and MFA handling around them.
    • ▸Removed secret values from Terraform state and task definitions using write-only secrets, and separated IAM roles so the application cannot read the database master credential.
  5. 05

    Codebase and developer experience

    • ▸Restructured a repository whose root was the website into a monorepo (apps/web, apps/api), moving ~715 files with zero changes to application code — each step proven by byte-comparing the deployed artefact before and after.
    • ▸Deleted 311,000 lines of superseded and unreferenced code, each verified unreferenced before removal.
    • ▸Created a local development environment that did not exist before: database, API and frontend with one command, seeded users for every role, and a command to switch role in the browser.
    • ▸Wrote the architecture decision records (16 by day 14) and the documentation set the team and its AI agents work from.
  6. 06

    React migration

    • ▸Retired the 42,465-line JavaScript monolith and its 20,766-line HTML page in 8 days (Sep 20 → Sep 28), porting the product to ~40 React/TypeScript routes.
    • ▸Every port was held to a parity test first: the legacy page's screenshots, rendered on Linux, were committed before any React code, and the React side had to match them.
  7. 07

    AI features

    • ▸Built the agent layer on the OpenAI Agents SDK: an objective becomes portfolios, programs and projects, level by level.
    • ▸Each level is decided by a three-sample vote over a fixed ontology — so the same objective gives the same plan — then researched on the web with cited sources, then written. An attention check flags what is kept but not aligned with the objective.
    • ▸Jobs run in the API with leases, so a crashed task's work is recovered.

Day 13 → 14

Shipped faster than the CI budget.

Every pull request ran a sharded pipeline of ~50 runner-minutes. On the evening of Sep 28, GitHub Actions stopped starting jobs — the spending limit had been reached.

By the next morning the whole pipeline ran locally: a gate that runs exactly what CI ran, in Linux containers on an isolated stack, including 500+ pixel-exact screenshot comparisons on Apple silicon (the one mismatch traced to a missing fallback font), plus local squash-merge and deploy commands.

That day, five releases (0.129.0 → 0.131.0) reached dev in three deploys, each through the full gate, and the dev smoke test passed.

Method

How the agents worked.

  • ▸Many Claude Code agent sessions in parallel — 30 git worktrees at the peak — each on its own branch, all on one strict per-PR process.
  • ▸The process, the repository map (AGENTS.md) and every decision lived in shared docs, skills and memory, so agents didn't redo each other's archaeology.
  • ▸Speed never came at the cost of checks: parity-first ports, mandatory review, and a required test gate on every change.
  • ▸Cost was an explicit constraint throughout, so every design decision carried a monthly figure.

§09Contact

Hiring a senior engineer or a tech lead? Let's talk.

Open to senior full-stack and technical-lead roles, permanent or contract, with a preference for long-term collaboration. Based in Istanbul, Turkey; remote-first.

[email protected]
LinkedIn
in/tntfx256
GitHub
tntfx256
Medium
@tntfx256