About Cody

I'm a software engineer in New Brunswick, Canada, building practical web software from the interface down to deployment.

I like clear user flows, readable code, and systems I can operate with confidence. Most of my work sits where product details, backend logic, and infrastructure all have to line up.

Portrait of Cody Woolaver

How I Work

I usually start by making sure I understand the actual problem, not just the requested change. From there I care most about correctness, maintainability, and leaving the next developer with enough context to keep moving.

This site is also a working example of that. It is an older Pyramid app that I am modernizing piece by piece, which makes it a useful place to show how I handle tradeoffs, migrations, dependency updates, UI cleanup, and deployment work over time.

What I Bring

  • Patient debugging and a habit of finding the root cause before widening the fix.
  • Care for existing systems, especially when modernizing code that already works.
  • Comfort moving between backend Python, templates, JavaScript, CSS, Docker, and deployment details.
  • Product sense: asking what the user actually needs and keeping the implementation grounded in that.

Featured Project

Why Minesweeper?

Minesweeper has stuck with me for a long time. When I was younger, I would work through boards on paper just to find the next logical move. I liked that a small grid could turn into a real reasoning problem: what is known, what is implied, what is safe, and where probability starts once logic runs out?

The version on this site keeps game state on the server and includes a solver-assisted hint system. The solver looks at the visible board, evaluates neighbouring cells, and identifies moves that are logically forced. It is a small project, but it pulls together constraints, state, interaction, and algorithmic thinking in a way I still enjoy.

The board itself is intentionally simple: a fixed-length string plus row and column counts. The dimensions map each index back to an x, y position, and the backend expands that representation into a grid when it needs to reason about neighbours.

A separate uncovered mask controls what the player can see. The full field knows where every mine and number lives, while the mask lets the UI reveal only the current state. When a player uncovers a zero, the server walks outward through adjacent safe cells and updates the mask to produce the familiar cascade.

It represents the kind of work I like: clear rules, visible logic, and a usable experience built around a small but interesting core.

Try the Minesweeper project

About This Site

How This Website Is Built

What powers the backend?

This site is a Python web application built with Pyramid. It uses server-rendered Jinja templates, SQLAlchemy for the application models and database access, Alembic for schema migrations, and MySQL for the production database.

What powers the frontend?

The frontend is intentionally modest: Less for application styles and CoffeeScript for the older browser behavior. CoffeeScript was a popular choice when I first built pieces of this site, before React and TypeScript became the default shape of many frontend projects. I would not choose it for a new build today, and I plan to rewrite that layer as part of the ongoing modernization work.

Why Pyramid?

Pyramid was the main framework I worked with at SurveyMonkey, and it shaped how I think about web applications. I originally came from Django, where the framework gives you a large built-in stack, including the ORM. Pyramid is smaller and more explicit: it handles routing, views, configuration, requests, and responses well, while leaving room to choose the rest of the application structure.

That fit this site well. The app could stay small, but I could still wire together the pieces I wanted: SQLAlchemy models, explicit migrations, server-rendered pages, admin tools, a few interactive projects, and deployment code I understand end to end.

How is the data handled?

The site has its own production database on a centralized MySQL instance shared by my personal projects. Other projects use the same database service, but not the same database. Development has a separate database, so I can test changes without touching production data.

Schema changes are managed with Alembic in both development and production. On deploy, the container runs migrations before starting the app, which keeps the deployed code and database schema aligned.

How is it hosted and deployed?

I build changes on a separate local machine, push them to a self-hosted Gitea instance, then pull them on my Unraid server alongside the current Docker image. The app runs through Docker Compose, with public traffic coming through a dedicated cloudflared container and then into SWAG, which provides the nginx reverse proxy layer. From there, nginx routes requests with proxy_pass to the portfolio container.

The current deploy process has a short downtime window. That is fine for this portfolio, but for a production service I would move toward blue-green or rolling deployment, health-gated container replacement, and traffic shifting only after the new instance is ready.

How do I think about operations?

I keep operations lightweight because this is a personal site: Docker health checks, regular check-ins, and simple deploy steps I understand. I do not have paging for the portfolio, and I do not need it. I have worked with PagerDuty and on-call rotations before, so I know the difference between a personal project and a service that needs a real incident response path.

I like staying close to infrastructure, not only application code. That shows up in small maintenance work: replacing outdated dependencies, keeping migrations in sync, tightening UI copy, and making the project easier to run and deploy.

What I Am Looking For

I am interested in teams that value clear communication, practical ownership, and steady improvement. I do my best work where correctness matters, maintainability is treated as part of the product, and engineers are encouraged to understand the business problem behind the ticket.

If that sounds useful for your team, I would be happy to talk.

Contact me