Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions src/pages/portfolio/archparser.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 'ArchParser: Architectural Drawing Analysis Platform'
portfolioOrder: 3
card:
title: "ArchParser"
summary: "Architectural drawing analysis platform for OCR-based architectural drawing management."
summary: "The only designer, researcher, and developer on a tool that turns <strong>500+ page drawing sets</strong> into structured metadata. Non-technical users build their own OCR templates, and every extraction shows a confidence score."
image: "/assets/img/archparser_dashboard1.webp"
imageAlt: "ArchParser dashboard"
badges: ["Development", "Claude Code"]
Expand All @@ -23,7 +23,10 @@ customCss: slides.css
<h2 class="text-h2 no-underline">Project Overview</h2>
<div class="card">
<p>
<span class="text-h6 mr-1">Role:</span>Product Designer &amp; Full-Stack Developer
<span class="text-h6 mr-1">Role:</span>Sole Product Designer, Researcher &amp; Full-Stack Developer
</p>
<p>
<span class="text-h6 mr-1">Team:</span>Solo. No second designer, researcher, or developer.
</p>
<p>
<span class="text-h6 mr-1">Type:</span>Personal Project (originally intended as a CAS tool)
Expand All @@ -44,26 +47,41 @@ customCss: slides.css
<li>Revision tracking and real-time progress updates support long-running jobs on large drawing sets</li>
</ul>
</section>
<section>
<h2 id="myrole">What I Did Alone</h2>
<p class="text-callout">ArchParser had one person on it, so every layer of the product went through me, from the first interview to the last test.</p>
<div class="card mb-4">
<p>
<span class="text-h6 mr-1">Research:</span>I interviewed project planners and managers about how they pulled metadata from drawing sets, then turned what I heard into the requirements, including support for title block layouts that vary by architectural firm.
</p>
<p>
<span class="text-h6 mr-1">Design:</span>I designed the template creator, the confidence and review model, the dashboard, and the drawing review screens, and I kept them consistent with patterns users already knew.
</p>
<p>
<span class="text-h6 mr-1">Build:</span>I built the React and Vite frontend with RadixUI, the NestJS backend, and the OCR pipeline, with Claude Code as a development partner. The backend has 14 test suites with 53 tests, and the frontend and backend share TypeScript types.
</p>
</div>
</section>
<section>
<h2 id="designdecisions">Key Design Decisions</h2>
<p class="text-callout">The technical work is summarized further down, but the choices that shaped how people actually use ArchParser were design decisions. Four mattered most.</p>
<div class="card mb-4">
<div class="card-body">
<h3 class="mb-2">1. Let users build templates, not developers</h3>
<p>Every OCR template tells the system where to look for a drawing number, title, date, and revision. The alternative was to have developers configure each template. I rejected it for two reasons. Title block layouts vary with file types, architectural firms, and project size, so the number of templates was never going to be small or stable. Projects also move fast, and waiting on a developer for every new layout would have slowed the very projects the tool was meant to help. The visual template creator lets a project manager draw the regions on a sample page and export the template themselves.</p>
<p>Every OCR template tells the system where to look for a drawing number, title, date, and revision. The alternative was to have developers configure each template. I rejected it for two reasons. Title block layouts vary with file types, architectural firms, and project size, so the number of templates was never going to be small or stable. Projects also move fast, and waiting on a developer for every new layout would have slowed the very projects the tool was meant to help. The visual template creator lets a project manager draw the regions on a sample page and export the template themselves. Because I was designing and building it, I could ship it as a standalone offline tool instead of writing a spec for someone else to interpret.</p>
</div>
</div>
<div class="card mb-4">
<div class="card-body">
<h3 class="mb-2">2. Design for confidence and review, not blind trust</h3>
<p>OCR is never perfect on architectural drawings, so I designed the error handling around confidence and the ability to review. Each extraction shows a confidence score out of 100. In practice, when confidence was around 75, users generally proceeded with what the system provided, and they still reviewed a random sample of files to check it. Anything wrong could be corrected inline. The goal was to make a wrong result easy to spot and cheap to fix, and to let users decide how much to trust the output.</p>
<p>OCR is never perfect on architectural drawings, so I designed the error handling around confidence and the ability to review. Each extraction shows a confidence score out of 100. In practice, when confidence was around 75, users generally proceeded with what the system provided, and they still reviewed a random sample of files to check it. Anything wrong could be corrected inline. The goal was to make a wrong result easy to spot and cheap to fix, and to let users decide how much to trust the output. Since I owned the whole stack, I could carry that decision from the OCR output through to the inline correction in the review screens.</p>
<!-- TODO: add a screenshot showing the confidence score in the drawing list or detail view -->
</div>
</div>
<div class="card mb-4">
<div class="card-body">
<h3 class="mb-2">3. Consistency over novelty, even with an AI partner</h3>
<p>Claude Code suggested changes to button placement and some layouts. I rejected them because they differed from what was already present in the system, and changing familiar patterns would have hurt usability for people who already knew the interface. Claude Code sped up implementation, but judgment about the user's existing context stayed with me.</p>
<p>Claude Code suggested changes to button placement and some layouts. I rejected them because they differed from what was already present in the system, and changing familiar patterns would have hurt usability for people who already knew the interface. Claude Code sped up implementation, but with no second designer to review the call, judgment about the user's existing context stayed with me.</p>
</div>
</div>
<div class="card mb-4">
Expand Down Expand Up @@ -167,6 +185,7 @@ customCss: slides.css
<li><strong>Test with realistic data from the start.</strong> The first version worked on small PDFs and failed on real 500+ page sets. Building with realistic data earlier would have surfaced the memory problem sooner.</li>
<li><strong>Empowering users beat clever engineering.</strong> The visual template creator did more for adoption than any backend optimization, because it removed a bottleneck.</li>
<li><strong>An AI partner speeds implementation, not judgment.</strong> Claude Code accelerated architecture work, debugging, and boilerplate, but the decisions about consistency and what users already know were mine to make.</li>
<li><strong>Owning every layer shortens the loop, and removes the reviewer.</strong> When real-world testing exposed the memory and path problems, I could change the design, the frontend, and the backend in one pass instead of handing a ticket across a team. The tradeoff was that nobody else was checking my work, which is why I leaned on tests and shared types.</li>
</ol>
</div>
</div>
Expand Down
23 changes: 19 additions & 4 deletions src/pages/portfolio/casim.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 'CASim: Making Years of Inconsistent Construction Data Answerable'
portfolioOrder: 1
card:
title: "CASim: Internal AI Assistant"
summary: "Designed and architected an internal AI assistant, built on a custom MCP server, that makes years of inconsistent construction data answerable. Currently in UAT and beta testing."
summary: "The only designer, researcher, and front-end developer on an internal AI assistant, built on a custom MCP server, that makes years of inconsistent construction data answerable. Currently in UAT and beta testing."
image: "/assets/img/casim-dashboard.webp"
badges: ["AI", "MCP", "Enterprise"]
group: "Professional"
Expand All @@ -20,14 +20,26 @@ eleventyNavigation:
<section>
<h2 class="text-h2 no-underline">Project Overview</h2>
<div class="card">
<p><span class="text-h6 mr-1">Role:</span>Creative Lead &amp; Architect (design, MCP server, agents, prompts, and tooling)</p>
<p><span class="text-h6 mr-1">Role:</span>Sole Designer, Researcher &amp; Front-End Developer, plus Creative Lead &amp; Architect (MCP server, agents, prompts, and tooling)</p>
<p><span class="text-h6 mr-1">Team:</span>Solo on design, research, and front end. The development team updated the source data once the naming decisions were made.</p>
<p><span class="text-h6 mr-1">Type:</span>Internal Tool</p>
<p><span class="text-h6 mr-1">Stack:</span>TypeScript MCP server, Claude Desktop, MCP Inspector, custom web interface</p>
<p><span class="text-h6 mr-1">Status:</span>In Progress · Currently in UAT and beta testing</p>
</div>
</section>

<section>
<h2>What I did alone</h2>
<div class="card">
<p>I was the only designer, researcher, and front-end developer on CASim, and I also architected the MCP server, agents, prompts, and skills behind it. One person carried the work from the first question to the interface people use every day.</p>
<p><span class="text-h6 mr-1">Research:</span>I interviewed stakeholders about the question that was nearly impossible to answer, audited years of data to find where names, dimensions, and identifiers had drifted, and tested tool behavior in MCP Inspector and Claude Desktop before judging how it felt in the interface.</p>
<p><span class="text-h6 mr-1">Design:</span>I designed how the assistant reasons about project data and the access model that decides what it can reach.</p>
<p><span class="text-h6 mr-1">Build:</span>I built the MCP server and the front end of the custom interface. The development team's part was updating the source data, after the naming decisions were made.</p>
</div>
</section>

<section>
<h2>The problem</h2>
<div class="card">
<p>
One question was close to impossible to answer at our company: how did a project's budget compare to its final financials once every work order, change order, and supply markup was counted? All of that information existed in our system. Nothing connected it, so answering took manual assembly across screens, and most people didn't try.
Expand All @@ -46,15 +58,15 @@ eleventyNavigation:
<p>We had two realistic paths. The first was to build a terminology file, a definitions layer that mapped every variant name and dimension to a canonical meaning so the assistant could translate on the fly. The second was to work with the executive team to decide what the defaults should be, then have the development team update the data and database to match.
</p>
<p>
The terminology file was the faster, lower-risk option, and it was tempting for that reason. I rejected it because it would have hardened the mess into a permanent dependency. Every new variant would need a new mapping, someone would have to own that file indefinitely, and the assistant's answers would only be as good as the last person who updated it. We chose the harder path of returning to a single consistent naming convention and fixing the source.
The terminology file was the faster, lower-risk option, and it was tempting for that reason. I rejected it because it would have hardened the mess into a permanent dependency. Every new variant would need a new mapping, someone would have to own that file indefinitely, and the assistant's answers would only be as good as the last person who updated it. We chose the harder path of returning to a single consistent naming convention and fixing the source. The research behind that call was mine, so explaining it and answering for what the cleanup might miss was my job too.
</p>
</div>
</section>

<section>
<h2>What I built</h2>
<div class="card">
<p>I was the creative lead and architect for CASim, and I built the core pieces myself. That includes the MCP server, the agents, prompts, and skills that shape how the assistant reasons about project data, and the tooling that connects it all. The server runs against three clients: Claude Desktop for daily use, MCP Inspector for testing tool behavior directly, and a custom interface for the people who will use CASim day to day. Keeping those three in play meant I could check whether a tool behaved correctly in isolation before judging how it felt in the interface.
<p>I was the creative lead and architect for CASim, and I built the core pieces myself. That includes the MCP server, the agents, prompts, and skills that shape how the assistant reasons about project data, and the tooling that connects it all. The server runs against three clients: Claude Desktop for daily use, MCP Inspector for testing tool behavior directly, and a custom interface for the people who will use CASim day to day. Keeping those three in play meant I could check whether a tool behaved correctly in isolation before judging how it felt in the interface. With design, research, and the front end all in my hands, a bad answer could be traced to the tool, the prompt, or the data without waiting on a handoff.
</p>
<!-- IMAGE: Architecture diagram of the MCP server connecting to Claude Desktop, MCP Inspector, and the custom interface, with the project data sources behind it -->
<p>
Expand Down Expand Up @@ -89,6 +101,9 @@ eleventyNavigation:
Looking back on the beginnings of the project, I would have researched and tested more before diving into creation. There were many times where I had to stop, research, and backtrack in order to cover either a gap that I had in the system, or a concern that wasn't addressed in the original architecture. While this did not delay the project, it did cause unnecessary churn that could have been avoided by taking a little extra time with research.
</p>
<p>
Working alone sharpened that cost. Nobody else was positioned to catch the gaps in my research, so the checks had to live in how I worked, which is why testing each tool in isolation in MCP Inspector mattered so much.
</p>
<p>
Additionally, the pushback on data inconsistencies was unexpected although it should not have been. With a system that is 20+ years old, there are bound to be drifts in how data is stored and what has been entered by the thousands of users of the years.
</p>
</div>
Expand Down
Loading