Notes / Build logs

Technical build logs.

Short build logs from this portfolio: what changed, what broke, the tradeoffs, and the next fix. Start with the case studies for full context, or browse selected work.

Archive

Recent build logs.

Web Paint

Building a browser canvas editor without a framework

Date
Related project
Web Paint browser canvas drawing tool
Problem
A browser drawing editor has to feel immediate while keeping tool settings, pointer input, canvas pixels, history, imports, and export actions predictable in plain JavaScript.
Tool state
Web Paint treats canvas pixels as the document and keeps the active tool, brush size, colors, selection bounds, zoom, drag start, preview, and status in JavaScript state.
Canvas rendering
Pointer events are converted into canvas coordinates and committed through Canvas 2D. Shape previews and resize work stay temporary until the pointer action ends.
Undo/redo
History uses capped ImageData snapshots after meaningful commits. The model is simple and reliable for a browser editor, but large canvases make every snapshot expensive.
Import/export
Imports check MIME type, file size, and pixel count. Exports use PNG download, Clipboard APIs where available, local save/load, and permission fallbacks.
Text and shape tools
Text, rectangle, circle, line, fill, pencil, eraser, and selection modes share one loop: capture a start point, preview the draft, commit pixels, then save history.
Mobile/touch constraints
Touch drawing needs large controls, compact panels, stable canvas sizing, pointer capture, and touch-action: none so strokes do not become page scrolls.
Nonvisual limitations
The shell has labels, focus states, status output, and grouped tools. The drawing is still pixel data, so a stronger version needs shortcuts, layers/objects, and nonvisual descriptions.
Technical takeaway
Without a component framework, the hard part is keeping event handling, UI state, pixel commits, history, and browser API failures small enough to reason about.
TraverseOps

Designing field operations around maps, inspections, and work orders

Date
Related project
TraverseOps field-operations map and work-order sample app
Problem
Field operations break down when crews locate assets in one tool, record inspections somewhere else, and turn follow-up work into notes that have to be reconciled later.
Why maps help
A map-first interface makes location the organizing layer. Crews can find nearby hydrant-style assets, scan condition, select one record, and move into inspection or work-order tasks.
Asset state
Each asset has identity, location, status, inspection history, and open-work indicators. Status filters keep the map useful when there are too many points to scan manually.
Inspections
Inspection screens model the field path: pick an asset, record condition, capture notes, and leave a timestamped trail for status changes.
Work orders
Work orders turn inspection findings into assignable tasks tied to the selected asset, current status, and supervisor review path.
Imports
The import screen stays inside sample data. A real system would need schema checks, duplicate detection, coordinate validation, rollback behavior, and row-level errors.
Empty states
Field tools often start with no selection, filtered-out results, missing reports, or no work assigned. Those moments should show the next valid action instead of a blank panel.
Production gaps
A real deployment would need auth, role permissions, offline sync, audit logs, import validation, error handling, security review, device testing, and dependable map/data sources.
Technical takeaway
The useful part of TraverseOps is not only rendering points on a map; it is tying spatial context to state changes, inspection history, follow-up work, and operational guardrails.
MovieBot

How the Twitch MovieBot turns chat votes into OBS playback

Date
Related project
StreamCinema Vote Bot / MovieBot
Problem
Running a Twitch movie night by hand means reading chat, counting votes, resolving ties, finding the local movie file, and updating OBS while the stream is live.
Chat command flow
Viewers send !vote title, !results, !currentmovie, !time, and !movies. TwitchIO routes each command into Python handlers before playback state changes.
Vote state
The bot keeps per-viewer votes and movie totals. Changed votes decrement the old title before counting the new one, preventing duplicate vote inflation.
Tie handling
When a poll closes, the bot sorts vote counts, detects ties, and picks among tied titles. If nobody votes, it can choose a random movie instead of stalling.
Movie folder scanning
The scanner walks the configured movie folder, refreshes the in-memory catalog, avoids symlinks, and falls back when duration tools or files are unavailable.
OBS WebSocket control
After a winner is selected, the bot normalizes the path, updates the OBS media source through WebSocket, switches scenes, and restarts playback.
Token refresh/reconnect
Long sessions use token refresh, Twitch IRC health checks, guarded OBS calls, media handoff retries, and scheduled-task cleanup on shutdown.
What changed
The portfolio now explains the bot as an automation pipeline rather than just a chat command project: chat input, state management, local file discovery, OBS control, and reconnect behavior are shown as one system.
Technical takeaway
The interesting work is not the command syntax; it is keeping chat, local media, OAuth, OBS WebSocket calls, and failure recovery coordinated in a long-running Python process.
What would improve next
Add an operator dashboard, dry-run mode, structured logs, health indicators for Twitch/OBS, stronger integration tests, and safer queue controls for live stream operations.
Portfolio site

Hiring-focused homepage and metadata pass

Date
Related project
Portfolio site / GitHub Pages developer portfolio
Problem
The homepage was not giving recruiters a fast enough read on Zac's role, strongest projects, resume path, and technical evidence.
What changed
Reworked the HTML/CSS/JavaScript homepage around selected work, resume/contact CTAs, stronger project cards, social preview metadata, canonical URLs, and shorter paths to case studies.
Technical takeaway
A GitHub Pages portfolio still needs product-level information architecture: obvious primary actions, stable metadata, indexable project pages, keyboard-friendly links, and no broken recruiter paths.
MovieBot

Stream room and searchable voting catalog split

Date
Related project
StreamCinema Vote Bot / MovieBot and Movie Library
Problem
The live Twitch room and the movie queue were trying to serve different jobs: watching the stream, reading bot commands, browsing titles, and copying valid vote text.
What changed
Kept movie-night.html focused on the stream and bot flow, then moved title discovery into movie-library.html with search, result counts, lazy posters, copyable !vote commands, and a no-JavaScript list.
Technical takeaway
Separating the stream room from the catalog keeps pages simpler, improves mobile usability, and gives the bot system better QA and fallback boundaries.
TraverseOps

Sample-data boundaries and field-ops framing

Date
Related project
TraverseOps field-operations map and work-order sample app
Problem
A map-heavy sample app can look like a UI mockup unless the page explains records, roles, sample-data limits, and production risks.
What changed
Reframed TraverseOps as a MapLibre field-operations app designed around a Supabase-style data model, with sample records, asset filters, inspection/work-order screens, imports, reports, roles, and a deeper case study.
Technical takeaway
For operations software, the page has to show data ownership, user roles, edge cases, and deployment constraints. That context separates a credible prototype from a visual-only project.

Next step

Connect the build notes to the work.

Use the notes as implementation context, then jump into the project sections that show the finished interfaces and technical decisions.