diff --git a/.eleventy.js b/.eleventy.js index df8c0433..141a4905 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -55,6 +55,31 @@ module.exports = function (eleventyConfig) { return collection.getAll().filter((item) => item.data.type); }); + // Ordered sequence of portfolio case studies. Set `portfolioOrder` in a page's + // front matter to include it; Previous/Next buttons are generated from this order. + eleventyConfig.addCollection("portfolioSequence", function (collection) { + return collection + .getAll() + .filter((item) => item.data.portfolioOrder !== undefined) + .sort((a, b) => a.data.portfolioOrder - b.data.portfolioOrder); + }); + + // Cards for portfolio listing pages, built from each page's `card` front matter. + eleventyConfig.addFilter("cardList", function (sequence, group, featuredOnly) { + return sequence.filter( + (item) => + item.data.card && + (!group || item.data.card.group === group) && + (!featuredOnly || item.data.card.featured) + ); + }); + + eleventyConfig.addFilter("caseStudyNeighbors", function (sequence, url) { + const i = sequence.findIndex((item) => item.url === url); + if (i === -1) return null; + return { prev: sequence[i - 1] || null, next: sequence[i + 1] || null }; + }); + eleventyConfig.addPlugin(emojiReadTime); eleventyConfig.addWatchTarget("src/sass/*.scss"); diff --git a/.nvmrc b/.nvmrc index d9b04247..dbf2bf20 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v25.9.0 +v26.8.1 diff --git a/social/template.html b/social/template.html index ca1f26f2..799b0f7b 100644 --- a/social/template.html +++ b/social/template.html @@ -6,12 +6,12 @@ Adam Jolicoeur - + diff --git a/src/404.html b/src/404.html index 81d5dd37..3638dd00 100644 --- a/src/404.html +++ b/src/404.html @@ -10,12 +10,12 @@ Adam Jolicoeur - + @@ -34,7 +34,7 @@ /> diff --git a/src/_data/meta.js b/src/_data/meta.js index 5e25d217..b233ddb1 100644 --- a/src/_data/meta.js +++ b/src/_data/meta.js @@ -2,19 +2,19 @@ module.exports = { env: process.env.ELEVENTY_ENV, url: process.env.URL || "http://localhost:8080", siteName: "Adam Jolicoeur", - siteDescription: "Product Designer who ships code—and understands the business side.", + siteDescription: "Product designer building AI-native products, from interaction patterns to the systems that govern them.", siteURL: "https://www.adamjolicoeur.com", authorName: "Adam J. Jolicoeur", siteMeta:"Adam, Adam Jolicoeur, Adam J. Jolicoeur, AdamJ, Jolicoeur, adamjolicoeur.com, www.adamjolicoeur.com, mindreeper2420, Portfolio, Design, Product Designer, UXD, UX Designer, UX Developer, UX Engineer, Design Technologist, Product Mangement, CSS", packageVersion: "packageVersion", blueskyUsername: "adamjol.bsky.social", - blueskyTitle: "Adam Jolicoeur - Product Designer Who Ships Code", - blueskyDescription: "Product Designer who ships code—and understands the business side.", + blueskyTitle: "Adam Jolicoeur: Product Designer for Enterprise Systems and AI", + blueskyDescription: "Product designer building AI-native products, from interaction patterns to the systems that govern them.", githubURL: "https://github.com/AdamJ", githubUsername: "AdamJ", githubDescription: "Follow my work in the open source community.", linkedinURL: "https://www.linkedin.com/in/ajjolicoeur/", - linkedinDescription: "Product Designer | Design Systems Expert | AWS & Red Hat Alum | I design enterprise apps and code prototypes (HTML/CSS/React)", + linkedinDescription: "Product Designer | Design Systems | AI-Native Products | AWS & Red Hat Alum | 15+ years designing complex enterprise software", devtoURL: "https://dev.to/adamj", mastodonUsername: "@adamjol@mastodon.world", codepenURL: "https://codepen.io/AdamJolicoeur", diff --git a/src/_data/redirects.js b/src/_data/redirects.js new file mode 100644 index 00000000..87a9058e --- /dev/null +++ b/src/_data/redirects.js @@ -0,0 +1,14 @@ +// Old case study URLs that moved under /portfolio/. +// Each entry generates a static redirect page (meta refresh plus canonical link). +const moved = { + designs: ["alm", "component-library", "customer-engagement", "dashboard-analytics", "task-it"], + development: ["archparser", "timetracker"], + "case-studies": ["soccertracker", "color-picker"] +}; + +module.exports = Object.entries(moved).flatMap(([dir, slugs]) => + slugs.map((slug) => ({ + from: `/${dir}/${slug}/`, + to: `/portfolio/${slug}/` + })) +); diff --git a/src/_includes/blank.njk b/src/_includes/blank.njk new file mode 100644 index 00000000..a91826c3 --- /dev/null +++ b/src/_includes/blank.njk @@ -0,0 +1,50 @@ + + + + + + {%- set pageTitle %}{% if title %}{{ title }} | {% endif %}{{ meta.siteName }}{% endset -%} + {%- set pageDescription %}{% if description %}{{ description }}{% else %}{{ meta.siteDescription }}{% endif %}{% endset -%} + {%- set pageSocialImg %}{{ meta.url }}/previews/{% if title %}{{ title | slug }}{% else %}home{% endif %}.png{% endset -%} + + {{pageTitle}} + + + + + + + + + + + + + + + + + + + + + +
+ {{ content | safe }} +
+ + diff --git a/src/_includes/case-study-nav.njk b/src/_includes/case-study-nav.njk new file mode 100644 index 00000000..4184e971 --- /dev/null +++ b/src/_includes/case-study-nav.njk @@ -0,0 +1,16 @@ +{%- set neighbors = collections.portfolioSequence | caseStudyNeighbors(page.url) -%} +{%- if neighbors -%} +
+
+ {%- if neighbors.prev %} + + Previous Case Study + {%- endif %} + {%- if neighbors.next %} + Next Case Study + {%- else %} + All Case Studies + {%- endif %} +
+
+{%- endif -%} diff --git a/src/_includes/markdown.njk b/src/_includes/markdown.njk index 96cfc42b..effad0b7 100644 --- a/src/_includes/markdown.njk +++ b/src/_includes/markdown.njk @@ -25,3 +25,6 @@ layout: base.njk {{ content | safe }} {% endif %} + +{% include "case-study-nav.njk" %} + diff --git a/src/_includes/page.njk b/src/_includes/page.njk index 5439237a..4917903c 100644 --- a/src/_includes/page.njk +++ b/src/_includes/page.njk @@ -14,6 +14,8 @@ layout: base.njk {{ content | safe }} +{% include "case-study-nav.njk" %} + {% if customCss %} {% endif %} diff --git a/src/_includes/work-cards.njk b/src/_includes/work-cards.njk new file mode 100644 index 00000000..006c4a64 --- /dev/null +++ b/src/_includes/work-cards.njk @@ -0,0 +1,18 @@ +{%- for item in cardItems -%} +{%- set c = item.data.card -%} +{%- if loop.first %}
{% endif %} +
+{%- if c.image %} +{{ c.imageAlt }} +{%- endif %} +
+

{{ c.title }}

+

{{ c.summary | safe }}

+{%- if c.badges %} +
{% for b in c.badges %}{{ b }}{% endfor %}
+{%- endif %} +View Case Study +
+
+{%- if loop.last %}
{% endif %} +{% endfor -%} diff --git a/src/assets/AdamJolicoeur-Resume.pdf b/src/assets/AdamJolicoeur-Resume.pdf index da849a86..4625ac2c 100644 Binary files a/src/assets/AdamJolicoeur-Resume.pdf and b/src/assets/AdamJolicoeur-Resume.pdf differ diff --git a/src/feed.njk b/src/feed.njk index 6a03694f..fc881d5a 100644 --- a/src/feed.njk +++ b/src/feed.njk @@ -8,7 +8,7 @@ eleventyExcludeFromCollections: true "eleventyExcludeFromCollections": true, "metadata": { "title": "Adam J. Jolicoeur", - "description": "I'm a Product Designer who ships code—and understands the business side. For 15 years, I've designed enterprise applications at Amazon Web Services, Red Hat, and high-growth B2B companies—turning complex, data-intensive workflows into intuitive interfaces that scale.", + "description": "I'm a product designer building AI-native products. For 15 years, I've designed enterprise applications at Amazon Web Services, Red Hat, and high-growth B2B companies, turning complex, data-intensive workflows into intuitive interfaces that scale.", "language": "en", "url": "https://www.adamjolicoeur.com/", "author": { diff --git a/src/index.md b/src/index.md index 09e4cdd4..400ebe9b 100644 --- a/src/index.md +++ b/src/index.md @@ -4,27 +4,27 @@ layout: base.njk

Adam Jolicoeur

-

Lead Product Designer specializing in design systems and enterprise applications. 15+ years at AWS, Red Hat, and high-growth startups.

-

— I design products and code prototypes that ship —

+

Product designer building AI-native products, from interaction patterns to the systems that govern them. 15+ years at AWS, Red Hat, and high-growth B2B.

+

Enterprise product designer. Systems thinker. Builder.

About Me

-

I'm a Product Designer who ships code—and understands the business side.

-

With over 15 years designing enterprise applications at AWS, Red Hat, and high-growth B2B companies, I specialize in design systems and complex, data-intensive interfaces. I've shaped products used by millions of developers and contributed to some of the industry's most respected open-source design systems.

+

Lead Product designer building AI-native products, from interaction patterns to the systems that govern them.

+

15+ years across AWS, Red Hat, and high-growth B2B, including an internal AI assistant, MCP architecture, and design systems used on 100+ construction projects.

What makes me different:

    -
  • I code production-quality prototypes — I build functional prototypes in HTML/CSS/React, which means my designs are validated with real data and ready for engineering handoff. This bridges the gap between design and development, accelerating shipping and reducing costly miscommunication.
  • -
  • I think like a PM — I've managed product roadmaps, prioritized features, and led cross-functional teams. This dual perspective helps me balance user needs with business objectives and collaborate effectively with product managers and stakeholders.
  • -
  • Former PatternFly core contributor — I was a core contributor to PatternFly (2016-2021), Red Hat's open-source design system with 20,000+ GitHub stars, used across OpenShift, Ansible, and 50+ products serving millions of developers worldwide.
  • +
  • I code production-quality prototypes: I build functional prototypes in HTML/CSS/React, which means my designs are validated with real data and ready for engineering handoff. This bridges the gap between design and development, accelerating shipping and reducing costly miscommunication.
  • +
  • I think like a PM: I've managed product roadmaps, prioritized features, and led cross-functional teams. This dual perspective helps me balance user needs with business objectives and collaborate effectively with product managers and stakeholders.
  • +
  • Former PatternFly core contributor: I was a core contributor to PatternFly (2016-2021), Red Hat's open-source design system with 20,000+ GitHub stars, used across OpenShift, Ansible, and 50+ products serving millions of developers worldwide.

Currently: Lead Product Designer at Component Assembly Systems
- Previously: Amazon Web Services, Red Hat, and high-growth startups + Previously: Amazon Web Services, Red Hat, and high-growth B2B companies

-

Archparser

+

ArchParser

Architectural drawing analysis platform for OCR-based architectural drawing analysis management.

DevelopmentClaude Code
- View Case Study + View Case Study +
+
+

Task Management System

+

Lead designer for Task-it, Amazon's internal task management platform. Consolidated 3-4 disparate tracking tools into one unified system, reaching 500 daily active users across AWS within 18 months of launch.

+
+ AWS500+ UsersEnterprise +
+ View Case Study
@@ -128,7 +136,7 @@ layout: base.njk Tooling DX
- TimeTrackerPro + Timetraked

diff --git a/src/pages/about/adam.md b/src/pages/about/adam.md index f670fc9f..9f4d8405 100644 --- a/src/pages/about/adam.md +++ b/src/pages/about/adam.md @@ -3,7 +3,7 @@ layout: "base" title: "About" date: git Last Modified abbreviation: "about" -description: "Driven and passionate senior user experience designer with a background in software development." +description: "Product designer and product manager building AI-native tools for construction, with a background in software development." eleventyNavigation: key: About order: 1 @@ -12,19 +12,19 @@ eleventyNavigation:

Hello!

- UX Designer, Developer, Program Manager. Creating software for the construction world. Previously at Red Hat and AWS. Collector of nerdy things...forever. + Lead Product Designer and Product Manager building AI-native tools for the construction world. Previously at Red Hat and AWS. Collector of nerdy things...forever.

- Adam Jolicoeur is a designer, developer, and program manager in Massachusetts. Starting as a help desk tech, he discovered a desire to create technology, rather than fixing it, which lead to a leap into the software engineering space. + Adam Jolicoeur is a designer, developer, and product manager in Massachusetts. Starting as a help desk tech, he discovered a desire to create technology rather than fix it, which led to a leap into software engineering.

- While working at a small startup, Adam discovered the world of user experience design and realized that his future was before him. With a background in fine arts and knowledge in the software development space (Backbone/Angular, anyone?), Adam took another step forward by becoming the first ux designer at a financial startup. Leading the next-generation of product design for card processors and financial institutions, Adam took that experience and used it to catapult into the world of publicly traded companies. + While working at a small startup, Adam discovered user experience design and realized his future was before him. With a background in fine arts and knowledge of the software development space (Backbone/Angular, anyone?), he became the first UX designer at a financial startup, leading the next generation of product design for card processors and financial institutions.

- With a move to Red Hat (later acquired by IBM), Adam accelerated his career path (and filled up many pages in his passport) by working with industry experts and the open source community on enterprise software experiences. After five years at Red Hat, Adam joined a small team at Amazon in AWS's Safety Engineering group to work on a new issue tracking and management product. While his time at Amazon came to abrupt end during the layoffs of 2023, the knowledge gained from such an environment only strengthened his desire to create in a collaborative and forward-looking space. + At Red Hat (later acquired by IBM), Adam worked with industry experts and the open source community on enterprise software experiences, including as a core contributor to PatternFly. He then joined a small team in AWS's Safety Engineering group to build Task-it, a new issue tracking and management product that grew to 500 daily active users across more than 15 teams.

- Adam has continued his career at Component Assembly Systems as their Lead Program Manager and Head of UX. + Today, Adam is the Lead Product Designer and Product Manager at Component Assembly Systems. He designs and builds AI products for construction teams, including CASim, an AI project management assistant built on MCP, and ArchParser, an OCR-based tool for plan management. He works in Claude Code every day, shipping working prototypes alongside the design system that keeps them consistent. Outside of work, he builds local-first apps under Brimfield Labs.

Education

diff --git a/src/pages/about/resume.md b/src/pages/about/resume.md index 78efc17d..5f4f32f1 100644 --- a/src/pages/about/resume.md +++ b/src/pages/about/resume.md @@ -1,11 +1,11 @@ --- layout: "markdown" title: "Adam Jolicoeur" -description: "Lead Product Designer with 15+ years at AWS, Red Hat, and high-growth B2B companies" +description: "Lead Product Designer and Product Manager with 15+ years at AWS, Red Hat, and high-growth B2B companies" abbreviation: "Resume" date: git Last Modified primaryAction: "View PDF" -primaryURL: "https://www.adamjolicoeur.com/downloads/resume.pdf" +primaryURL: "https://www.adamjolicoeur.com/assets/AdamJolicoeur-Resume.pdf" eleventyNavigation: key: Resume parent: About @@ -17,14 +17,15 @@ eleventyNavigation: contact@adamjolicoeur.com

-

I design enterprise applications and code production-quality prototypes. With expertise in design systems and complex data-intensive interfaces, I've shaped products used by millions of developers and contributed to industry-leading open-source design systems.

+

I design AI-native products, from interaction patterns to the systems that govern them, drawing on 15+ years of enterprise design. With expertise in design systems and complex, data-intensive interfaces, I have shaped products used by thousands of engineers and contributed to industry-leading open-source design systems.

Key Highlights

    -
  • Lead designer for Task-it at Amazon Web Services - reached 500 daily active users across AWS in 18 months
  • -
  • Core contributor to PatternFly design system at Red Hat 20,000+ GitHub stars, used across OpenShift.
  • -
  • Built comprehensive design systems for enterprise construction management and financial services platforms
  • -
  • Code production-quality prototypes using HTML/CSS/React that validate designs and accelerate engineering
  • +
  • Designing and building AI products at CAS, including CASim (an MCP-based AI project management assistant) and ArchParser (OCR-based plan management)
  • +
  • Lead designer for Task-it at Amazon Web Services, which reached 500 daily active users across 15+ teams
  • +
  • Core contributor to the PatternFly design system at Red Hat, used across OpenShift
  • +
  • Built the CAS design system, accelerating development cycles by 25%
  • +
  • Code production-quality prototypes in HTML, CSS, and React that validate designs and accelerate engineering

@@ -33,25 +34,25 @@ eleventyNavigation:

Lead Product Designer & Product Manager
- Component Assembly Systems | 2024 - Present + Component Assembly Systems | 2024 to Present

Previous Experience

- Senior UX Designer — Amazon Web Services (2021-2023) + Senior UX Designer, Amazon Web Services (2021-2023)

- Senior Interaction Designer — Red Hat (2016-2021) + Senior Interaction Designer, Red Hat (2016-2021)

- UX Designer — Saylent Technologies (2014-2016) + UX Designer, Saylent Technologies (2014-2016)

Download Resume (PDF)
- Last updated November 2025 + Last updated October 2026

Also available

diff --git a/src/pages/apps/TimeTrackerPro.md b/src/pages/apps/TimeTrackerPro.md index 02f76c88..2001b535 100644 --- a/src/pages/apps/TimeTrackerPro.md +++ b/src/pages/apps/TimeTrackerPro.md @@ -1,12 +1,12 @@ --- layout: "page" permalink: "apps/{{ abbreviation | slugify }}.html" -title: "Time Tracker Pro" +title: "Timetraked" date: git Last Modified abbreviation: "timetracker" description: "Perfect for freelancers, consultants, and professionals who need to track time, manage projects, and generate invoices." eleventyNavigation: - key: TimeTrackerPro + key: Timetraked parent: Apps order: 5 --- @@ -17,7 +17,7 @@ eleventyNavigation: ## Links -**GitHub:** [AdamJ/TimeTrackerPro](https://github.com/AdamJ/TimeTrackerPro) +**GitHub:** [AdamJ/TimeTrackerPro (repository name)](https://github.com/AdamJ/TimeTrackerPro) **WebApp:** [timetrackerpro.adamjolicoeur.me](https://timetrackerpro.adamjolicoeur.me) diff --git a/src/pages/apps/index.md b/src/pages/apps/index.md index 5a29220f..09a45c68 100644 --- a/src/pages/apps/index.md +++ b/src/pages/apps/index.md @@ -18,7 +18,7 @@ eleventyNavigation: ## Webapps - [Moonsilver Waypoints](moonsilver) -- [TimeTracker Pro](timetracker) +- [Timetraked](timetracker) ## iOS AppStore diff --git a/src/pages/apps/privacy.md b/src/pages/apps/privacy.md index 221fcde5..477f68f3 100644 --- a/src/pages/apps/privacy.md +++ b/src/pages/apps/privacy.md @@ -13,7 +13,7 @@ eleventyNavigation:
-Your data is your data - they say sharing is caring, but it is not recommended to share your data. +Your data is your data. They say sharing is caring, but it is not recommended to share your data. - Your usage analytics is not collected, nor anything else - Anything entered into the apps created by Adam Jolicoeur are stored locally on your device diff --git a/src/pages/apps/taskstat-privacy.md b/src/pages/apps/taskstat-privacy.md index e4731336..97cf26c4 100644 --- a/src/pages/apps/taskstat-privacy.md +++ b/src/pages/apps/taskstat-privacy.md @@ -4,7 +4,7 @@ permalink: 'apps/taskstat-privacy.html' title: 'TaskStat Privacy Policy' date: git Last Modified abbreviation: 'taskstat-privacy' -description: 'Privacy policy for TaskStat - a privacy-first task management app for iOS' +description: 'Privacy policy for TaskStat, a privacy-first task management app for iOS' eleventyNavigation: key: TaskStat Privacy parent: Apps @@ -189,7 +189,7 @@ You have complete ownership and control over your data: ### How to Exercise Your Rights -- **To access your data:** Open TaskStat—all your data is visible +- **To access your data:** Open TaskStat, all your data is visible - **To export your data:** Use the CSV export feature in the task list - **To delete specific data:** Swipe to delete tasks or projects, or use multi-select - **To delete all data:** Delete the TaskStat app from your device diff --git a/src/pages/apps/taskstat.md b/src/pages/apps/taskstat.md index 8c962953..4393ffcc 100644 --- a/src/pages/apps/taskstat.md +++ b/src/pages/apps/taskstat.md @@ -4,7 +4,7 @@ permalink: "apps/{{ abbreviation | slugify }}.html" title: "TaskStat" date: git Last Modified abbreviation: "taskstat" -description: "Privacy-first task management for iOS. Your tasks stay on your device—no accounts, no tracking, no cloud sync." +description: "Privacy-first task management for iOS. Your tasks stay on your device, no accounts, no tracking, no cloud sync." eleventyNavigation: key: TaskStat parent: Apps @@ -15,7 +15,7 @@ eleventyNavigation: ## About TaskStat -TaskStat is a native iOS task management app built with privacy as a core principle. Unlike cloud-based task managers, TaskStat stores all your data locally on your device using SwiftData—ensuring complete privacy and offline functionality. +TaskStat is a native iOS task management app built with privacy as a core principle. Unlike cloud-based task managers, TaskStat stores all your data locally on your device using SwiftData, ensuring complete privacy and offline functionality. ### Key Features @@ -80,7 +80,7 @@ Read the full [Privacy Policy](/apps/taskstat-privacy.html) **Platform:** iOS 18.0 or later -**App Store:** *Coming soon - Link will be added when published* +**App Store:** *Coming soon. Link will be added when published* ## Requirements diff --git a/src/pages/case-studies.md b/src/pages/case-studies.md index 05f137e0..572a83ac 100644 --- a/src/pages/case-studies.md +++ b/src/pages/case-studies.md @@ -6,79 +6,18 @@ description: 'An expanded list of case studies and prior work' eleventyNavigation: key: Casestudies order: 6 +templateEngineOverride: njk,md --- +{% set btnClass = "btn-secondary" %}
-

Professional

-
-
-
-

Task Management System

-

Lead designer for Task-it, Amazon's internal task management platform. Consolidated 3-4 disparate tracking tools into one unified system, reaching 500 daily active users across AWS within 18 months of launch.

-
- AWS500+ UsersEnterprise -
- View Case Study -
-
-
-
-

Weekly AI-Powered Work Summary

-

After archiving my work entries for the week, I found myself running a second, separate tool to generate a weekly summary. Now, I start the day, capture tasks, review, and archive - then summarize using AI.

-
- AIProductivity -
- View Case Study -
-
-
-
-
-

Archparser

-
-

Architectural drawing analysis platform for OCR-based architectural drawing management.

-
- DevelopmentClaude Code -
- View Case Study -
-
-
-

Component Library

-
-

Built comprehensive design system for construction management software spanning web and iOS applications. Created design tokens, component documentation, and prototypes that accelerated development cycles by 25%.

-
- LibraryDesign Tokens -
- View Case Study -
-
-
- +

Professional

+{% set cardItems = collections.portfolioSequence | cardList("Professional") %} +{% include "work-cards.njk" %}
-

Personal

-
-
-

Soccer Game Tracker

-
-

A native iOS app, built by a coach, who needed fast and reliable game tracking without surrendering data to a third-party platform — designed for the sideline, built in Swift.

-
- SwiftUIMobile -
- View Case Study -
-
-
-

Color Picker

-
-

As one of the most up-voted feature requests, the goal was to create an accessible option that combined colors with patterns.

-
- A11yComponents -
- View Case Study -
-
-
+

Personal

+{% set cardItems = collections.portfolioSequence | cardList("Personal") %} +{% include "work-cards.njk" %}
diff --git a/src/pages/designs/designs.json b/src/pages/designs/designs.json deleted file mode 100644 index 99cbd6c1..00000000 --- a/src/pages/designs/designs.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "layout": "page", - "permalink": "/designs/{{ page.fileSlug }}/" -} diff --git a/src/pages/development/archparser.md b/src/pages/development/archparser.md deleted file mode 100644 index c490478a..00000000 --- a/src/pages/development/archparser.md +++ /dev/null @@ -1,377 +0,0 @@ ---- -title: 'ArchParser: Architectural Drawing Analysis Platform' -date: git Last Modified -abbreviation: 'archparser' -description: 'Full-stack TypeScript application for OCR-based architectural drawing analysis and management.' -eleventyNavigation: - key: Development - parent: Development - order: 1 -customCss: slides.css ---- - -
-

Project Overview

-
-

- Project Type:Personal/Open Source -

-

- Role:Product Designer & Full-Stack Developer -

-

- Timeline:2025 (Ongoing) -

-

- Development Partner: - Built with Claude Code (Anthropic's AI development assistant) -

-

- THE CHALLENGE: - Construction project managers at Component Assembly Systems needed a way to efficiently extract metadata from hundreds of architectural drawing PDFs. Manual data entry from title blocks (drawing numbers, revision dates, project names) was time-consuming, error-prone, and didn't scale for projects with 500+ page drawing sets. No existing tools could handle the specialized OCR requirements or support custom title block layouts across different architectural firms. -

-

- MY ROLE: - I designed and developed ArchParser, a full-stack TypeScript application that automates the extraction of drawing metadata using OCR technology. I created both the technical architecture and user experience, focusing on reliability, performance, and flexibility to handle diverse document formats. -

-

- THE SOLUTION: - ArchParser is a monorepo application with a NestJS backend for OCR processing and a React/PatternFly frontend for drawing management. The system features customizable OCR templates with a visual template creator, memory-optimized processing for large PDFs, and an optional AI chatbot for semantic search. The platform successfully processes drawing sets of 500+ pages while maintaining accurate metadata extraction. -

-

- THE IMPACT: -
-

    -
  • Automated metadata extraction from architectural drawings, eliminating manual data entry
  • -
  • Successfully processes 500+ page PDF drawing sets with memory optimization
  • -
  • Visual template creator allows non-technical users to configure OCR extraction regions
  • -
  • Revision tracking system maintains drawing set history and version comparisons
  • -
  • Real-time WebSocket progress updates keep users informed during long-running OCR jobs
  • -
  • Centralized path management system ensures reliability across deployment environments
  • -
  • Open-source project serving as portfolio demonstration of full-stack capabilities
  • -
-

-
-
-
-

The Development Process

-

Unlike traditional design-first projects, ArchParser required simultaneous development of both technical architecture and user experience. The process was highly iterative, driven by real-world testing with large PDF sets and continuous feedback from construction project planners and managers.

-
-

Development approach:

-
    -
  1. Problem validation & requirements gathering -
      -
    • Interviewed construction project planners and managers about their drawing management workflows
    • -
    • Identified pain points: manual data entry, inconsistent title block formats, large file sizes
    • -
    • Determined core requirements: OCR accuracy, template flexibility, performance at scale
    • -
    -
  2. -
  3. Technology stack selection -
      -
    • Chose TypeScript monorepo for type safety across frontend and backend
    • -
    • Selected NestJS for backend (familiar enterprise patterns from AWS experience)
    • -
    • Used React with PatternFly UI (leveraging my Red Hat design system expertise) - later changed to RadixUI
    • -
    • Implemented Tesseract.js for client-side OCR processing
    • -
    -
  4. -
  5. Iterative development with Claude Code -
      -
    • Used Claude Code as a development partner for architecture decisions and implementation
    • -
    • Leveraged AI assistance for complex TypeORM migrations and NestJS module structure
    • -
    • Rapid prototyping of OCR extraction algorithms with Claude's code generation
    • -
    • Collaborative debugging of memory optimization and path management issues
    • -
    -
  6. -
  7. Real-world testing & optimization -
      -
    • Tested with actual 500+ page architectural drawing sets from construction projects
    • -
    • Identified and resolved critical memory constraints through optimization iterations
    • -
    • Refined OCR accuracy through template system improvements
    • -
    -
  8. -
-
-
-

Working with Claude Code as a development partner: -

    -
  • - Architecture & Planning: Claude helped design the monorepo structure, database schema, and path management system. We discussed trade-offs between different approaches (absolute vs. relative paths, synchronous vs. batch processing) before implementation. -
  • -
  • - Code Generation & Implementation: Claude generated boilerplate code for NestJS modules, TypeORM entities, and React components following established patterns. This accelerated development while maintaining consistency. -
  • -
  • - Problem Solving: When facing complex issues (memory leaks in OCR processing, path resolution bugs), Claude helped analyze logs, identify root causes, and propose solutions. The collaborative debugging process was particularly valuable for tricky issues like the path management overhaul. -
  • -
  • - Documentation: Claude assisted in writing comprehensive documentation (CLAUDE.md, README files, inline comments) that explains not just what the code does, but why architectural decisions were made. -
  • -
  • - Testing & Quality: Claude helped write test utilities, fixtures, and unit tests for both frontend and backend. The AI's ability to generate edge cases I hadn't considered improved test coverage. -
  • -
-

-
-
-
-

Technical Architecture

-

ArchParser is built as a TypeScript monorepo with three primary workspaces: backend (NestJS), frontend (React/Vite), and shared type definitions. The architecture emphasizes type safety, memory efficiency, and extensibility.

-

Backend

-

NestJS

-

Core Modules:

-
    -
  • Drawing Processing Service: Handles PDF-to-PNG conversion and Tesseract.js OCR extraction
  • -
  • OCR Template System: Configurable extraction regions for different title block formats
  • -
  • Path Management: Centralized path resolution with environment variable support for deployment portability
  • -
  • WebSocket Gateway: Real-time progress updates during OCR processing
  • -
  • Optional LLM Service: AI-powered semantic search (Claude, OpenAI, or local Ollama)
  • -
-

Database (TypeORM + MySQL):

-
    -
  • Entities: Job, DrawingSet, Drawing, OcrTemplate, KnowledgeChunk
  • -
  • Supports revision tracking through self-referencing DrawingSet relationships
  • -
  • Stores relative paths in database for deployment portability
  • -
-

Frontend

-

React + RadixUI

-

Key Features:

-
    -
  • Dashboard: Job listing with pagination, sorting, and filtering
  • -
  • Upload Workflow: PDF upload with OCR template selection and classification
  • -
  • Drawing Review: Individual drawing detail pages with metadata editing
  • -
  • Real-time Progress: WebSocket-powered progress indicator for OCR jobs
  • -
  • Template Creator: Visual interface for creating OCR extraction templates
  • -
-

UI/UX Decisions:

-
    -
  • RadixUI components for accessibility and consistency
  • -
  • Responsive grid layouts for data-dense tables
  • -
  • Inline editing for quick metadata corrections
  • -
  • Mock server support for frontend-only development
  • -
-
-
Dashboard
-
-
- Image of the archparser dashboard -
-
-
-

Template Creator

-

Standalone Tool

-

Built as a standalone HTML/JavaScript tool using PDF.js, the template creator allows users to:

-
    -
  • Upload a sample PDF and render it in the browser
  • -
  • Draw rectangular regions on the PDF to define extraction areas
  • -
  • Label regions (drawing number, title, date, revision, etc.)
  • -
  • Export template JSON for import into ArchParser
  • -
  • Works offline with no backend dependency
  • -
-

This tool democratizes OCR template creation—construction managers can create templates without developer assistance.

-
-
-
Initial Load
-
-
- Image of the template creator's empty canvas -
Empty canvas, ready for PDF
-
-
-
-
-
PDF Loaded
-
-
- Image of the template creator with a loaded PDF -
Document details loaded and ready
-
-
-
-
-
-
-

Visual Progressions

-

- The visual design of Archparser progressed rather quickly, but a consistent idea was in place from the beginning: get users into their jobs as quickly and easily as possible. -

-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-

Key Iterations & Problem Solving

-

Throughout development, several critical issues emerged that required significant architectural changes. Each iteration improved reliability, performance, or usability based on real-world testing.

-

Iteration 1: Memory Optimization for Large PDFs

-
-
-

Problem: Processing 500+ page PDFs caused memory exhaustion and server crashes. The initial implementation converted entire PDFs to PNG images in memory before processing.

-

Solution: Implemented single-page PDF conversion and dynamic batch processing:

-
    -
  • Convert one PDF page at a time instead of the entire document
  • -
  • Adjust batch sizes based on document size (smaller batches for larger PDFs)
  • -
  • Add memory monitoring and garbage collection tuning
  • -
  • Process OCR regions sequentially to prevent memory spikes
  • -
-

Result: Successfully processes 500+ page documents without crashes. Memory-optimized startup script (start-optimized.sh) provides production-ready performance.

-
-
-

Iteration 2: Path Management System Overhaul

-
-
-

Problem: Processed drawings became disassociated from database records after server restarts. Three root causes identified:

-
    -
  1. Inconsistent path resolution between process.cwd() and __dirname
  2. -
  3. Directory naming mismatch during deletion operations
  4. -
  5. Absolute paths in database made system non-portable across environments
  6. -
-

Solution: Complete path management overhaul with centralized configuration:

-
    -
  • Created storage.config.ts with centralized path constants
  • -
  • Implemented toRelativePath() and toAbsolutePath() utilities
  • -
  • Standardized folder naming: {sanitizedName}_{jobId} format
  • -
  • Updated all services to use centralized path resolution
  • -
  • Wrote migration script to convert 373 existing records from absolute to relative paths
  • -
-

Result: System is now portable across deployment environments. Paths resolve correctly regardless of server startup directory. Database can be migrated to new servers without breaking file associations.

-
-
-

Iteration 3: Dashboard UI Enhancement

-
-
-

Problem: Initial dashboard struggled with high-volume data tables. Users needed better filtering, sorting, and status visualization.

-

Solution: Comprehensive dashboard refactoring:

-
    -
  • Added independent pagination and sorting for Job and Template tables
  • -
  • Implemented date range filtering with "Created" and "Updated" pivots
  • -
  • Added status (Active/Archived) and type (Included/Custom) filters
  • -
  • Created Kanban-style Monitor Dashboard for job status visualization
  • -
  • Added Floating Action Button (FAB) for streamlined task creation
  • -
  • Persisted filter selections in local storage for session continuity
  • -
-

Result: Users can efficiently navigate large datasets. The Kanban view provides at-a-glance status monitoring, while table filters enable rapid data discovery.

-
-
-
-
-

Results & Impact

-

Technical Achievements

-

-

    -
  • Performance: Successfully processes 500+ page PDF drawing sets with memory-optimized batch processing
  • -
  • Accuracy: OCR template system with configurable regions achieves reliable metadata extraction across diverse title block formats
  • -
  • Type Safety: Shared TypeScript interfaces across monorepo prevent runtime errors and improve developer experience
  • -
  • Real-time Updates: WebSocket integration provides live progress feedback during long-running OCR jobs
  • -
  • Portability: Centralized path management enables deployment across different server environments without configuration changes
  • -
  • Test Coverage: 14 backend test suites with 53 tests, plus comprehensive frontend component testing
  • -
-

-

User Experience Wins

-

-

    -
  • Visual Template Creator: Non-technical users can create OCR templates by drawing regions on PDFs—no code required
  • -
  • Revision Tracking: Drawing set relationships enable version comparison and change tracking
  • -
  • Enterprise UI: PatternFly components provide accessible, professional interface familiar to enterprise users
  • -
  • Mock Server: Frontend developers can work independently without backend/database dependency
  • -
  • Flexible AI Integration: Optional LLM features support Claude, OpenAI, or free local Ollama—users choose based on budget and privacy needs
  • -
-

-

Development Process Insights

-

-

    -
  • AI-Assisted Development: Claude Code accelerated Archparer's development 2-3x through intelligent code generation, debugging assistance, and architectural guidance
  • -
  • Monorepo Benefits: Shared types across workspaces to catch integration bugs at compile time rather than runtime
  • -
  • Iterative Optimization: Real-world testing with large PDFs revealed performance bottlenecks that wouldn't have been found in small-scale testing
  • -
  • Documentation-Driven: Comprehensive CLAUDE.md file serves as both an AI context and a developer onboarding guide
  • -
-

-
-
-
Set Details
-
- Image of the drawing set details page -
-
-
-
Drawing List
-
- Image of the drawing list page -
-
-
-
Drawing Details
-
- Image of the drawing details page -
-
-
-
- -
-
-
-

What I Learned

-
-
-

- This project provided valuable insights about full-stack development, AI-assisted coding, and building for real-world constraints: -

    -
  1. Memory constraints require proactive optimization. The initial implementation worked fine for small PDFs but crashed on real-world 500+ page documents. Building with realistic test data from the start would have caught this earlier. Memory profiling and optimization became critical skills.
  2. -
  3. AI development assistance is transformative when used strategically. Claude Code was most valuable for architectural planning, debugging complex issues, and generating boilerplate code. I learned to use AI as a collaborative partner—explaining problems thoroughly, reviewing generated code critically, and iterating on solutions together. The key is maintaining ownership of architectural decisions while leveraging AI for implementation acceleration.
  4. -
  5. Path management is harder than it looks. The path resolution issues taught me that assumptions about working directories break in production. Centralizing path logic and storing relative paths in the database made the system portable and maintainable.
  6. -
  7. User empowerment beats technical complexity. The visual template creator was more impactful than any backend optimization. Enabling non-technical users to configure OCR templates themselves removed a bottleneck and increased adoption. Simple, visual tools often provide more value than sophisticated algorithms.
  8. -
  9. Design system expertise translates across contexts. My experience with design systems paid dividends—I could build an enterprise-grade UI quickly while ensuring accessibility and consistency. Design systems aren't just for design teams; they accelerate solo development too.
  10. -
  11. Monorepo structure enforces discipline. Shared TypeScript interfaces between frontend and backend prevented the API contract drift that plagues many full-stack projects. The initial setup overhead was worth it for the compile-time safety and refactoring confidence.
  12. -
-

-

- ArchParser demonstrated that full-stack development - especially with AI assistance - enables rapid prototyping and iteration. By combining my design background with technical implementation, I could build and refine features based on direct user feedback without handoff delays. The project serves as both a practical tool for construction project management and a portfolio demonstration of end-to-end product development capabilities. -

-
-
-
-
- -
-
- -
diff --git a/src/pages/portfolio.md b/src/pages/portfolio.md index e0ef9bec..38e636f3 100644 --- a/src/pages/portfolio.md +++ b/src/pages/portfolio.md @@ -6,56 +6,10 @@ description: 'Selected projects from AWS, Red Hat, and high-growth B2B companies eleventyNavigation: key: Portfolio order: 1 +templateEngineOverride: njk,md ---
-
-
- Task It project illustration -
-

Task Management System

-

Lead designer for Task-it, Amazon's internal task management platform. Consolidated 3-4 disparate tracking tools into one unified system, reaching 500 daily active users across AWS within 18 months of launch.

-
- AWS500+ UsersEnterprise -
- View Case Study -
-
-
- Task It project illustration -
-

Weekly AI-Powered Work Summary

-

After archiving my work entries for the week, I found myself running a second, separate tool to generate a weekly summary. Now, I start the day, capture tasks, review, and archive - then summarize using AI.

-
- AIProductivity -
- View Case Study -
-
-
-
-
- Archparer dashboard image -

Archparser

-
-

Architectural drawing analysis platform for OCR-based architectural drawing management.

-
- DevelopmentClaude Code -
- View Case Study -
-
-
- Getting Started screen on Storybook -

Component Library

-
-

Built comprehensive design system for construction management software spanning web and iOS applications. Created design tokens, component documentation, and prototypes that accelerated development cycles by 25%.

-
- LibraryDesign Tokens -
- View Case Study -
-
-
- +{% set cardItems = collections.portfolioSequence | cardList(null, true) %} +{% include "work-cards.njk" %}
diff --git a/src/pages/designs/alm.md b/src/pages/portfolio/alm.md similarity index 89% rename from src/pages/designs/alm.md rename to src/pages/portfolio/alm.md index 8eb0d5b9..833f5df6 100644 --- a/src/pages/designs/alm.md +++ b/src/pages/portfolio/alm.md @@ -1,5 +1,12 @@ --- title: 'Application Lifecycle Management' +portfolioOrder: 6 +card: + title: "Application Lifecycle Management" + summary: "Creating seamless IDE integration and workflow tools for developers managing complex environments." + badges: ["Developer Tools", "Enterprise"] + group: "Professional" + featured: false date: git Last Modified abbreviation: 'alm' description: 'Creating seamless IDE integration and workflow tools for developers managing complex environments.' @@ -27,7 +34,7 @@ eleventyNavigation:

THE CHALLENGE: - OpenShift developers were managing work items across 3+ disconnected tools (GitHub issues, Jira, internal tracking systems). This forced constant context-switching between their IDE, browser tabs, and project management tools—slowing development cycles, breaking focus, and creating visibility gaps for project managers. + OpenShift developers were managing work items across 3+ disconnected tools (GitHub issues, Jira, internal tracking systems). This forced constant context-switching between their IDE, browser tabs, and project management tools, slowing development cycles, breaking focus, and creating visibility gaps for project managers.

The fragmentation was especially painful because developers had to:

-
- -
diff --git a/src/pages/portfolio/archparser.md b/src/pages/portfolio/archparser.md new file mode 100644 index 00000000..8e984153 --- /dev/null +++ b/src/pages/portfolio/archparser.md @@ -0,0 +1,196 @@ +--- +title: 'ArchParser: Architectural Drawing Analysis Platform' +portfolioOrder: 3 +card: + title: "ArchParser" + summary: "Architectural drawing analysis platform for OCR-based architectural drawing management." + image: "/assets/img/archparser_dashboard1.webp" + imageAlt: "ArchParser dashboard" + badges: ["Development", "Claude Code"] + group: "Professional" + featured: true +date: git Last Modified +abbreviation: 'archparser' +description: 'Full-stack TypeScript application for OCR-based architectural drawing analysis and management.' +eleventyNavigation: + key: Development + parent: Development + order: 1 +customCss: slides.css +--- + +
+

Project Overview

+
+

+ Role:Product Designer & Full-Stack Developer +

+

+ Type:Personal Project (originally intended as a CAS tool) +

+

+ Stack:TypeScript monorepo, NestJS, React, RadixUI, MySQL, Tesseract.js, built with Claude Code +

+

+ Status:Demo-ready, paused while higher-priority CAS projects took precedence +

+
+

Construction project managers at Component Assembly Systems needed to pull metadata from hundreds of architectural drawing PDFs. Entering drawing numbers, revision dates, and project names from title blocks by hand was slow, error-prone, and impossible to sustain on 500+ page sets, and no existing tool handled custom title block layouts across different architectural firms. I interviewed project planners and managers about their workflows, then designed and built ArchParser to automate the extraction.

+

ArchParser is a TypeScript monorepo with a NestJS backend for OCR processing and a React frontend for managing drawings. Demonstrations have processed over 200 drawings, and users of the current manual process estimated it would save roughly half a day (4 to 5 hours) of manual work per drawing set. That figure is an estimate, not a measured result.

+ +
+
+

Key Design Decisions

+

The technical work is summarized further down, but the choices that shaped how people actually use ArchParser were design decisions. Four mattered most.

+
+
+

1. Let users build templates, not developers

+

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.

+
+
+
+
+

2. Design for confidence and review, not blind trust

+

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.

+ +
+
+
+
+

3. Consistency over novelty, even with an AI partner

+

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.

+
+
+
+
+

4. AI search as an optional add-on

+

I designed the semantic search to be optional, for the point when the company adopts an AI platform. It supports Claude, OpenAI, or a local Ollama model, so a team can choose based on budget and privacy needs. The core product works fully without it.

+
+
+
+
+

The Template Creator

+

The template creator is a standalone HTML and JavaScript tool built with PDF.js that works offline with no backend dependency. Users upload a sample PDF, draw rectangles over the title block, label each region (drawing number, title, date, revision), and export a template file for ArchParser.

+
+
+
Initial Load
+
+
+ Image of the template creator's empty canvas +
Empty canvas, ready for PDF
+
+
+
+
+
PDF Loaded
+
+
+ Image of the template creator with a loaded PDF +
Document details loaded and ready
+
+
+
+
+
+
+

Visual Progressions

+

+ The visual design progressed quickly, but one idea held from the beginning: get users into their jobs as quickly and easily as possible. +

+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+

Working with Claude Code

+

I used Claude Code as a development partner across architecture, implementation, and debugging. We weighed trade-offs such as absolute versus relative paths and synchronous versus batch processing before writing code, and it was most useful on TypeORM migrations, NestJS module structure, and tracking down memory and path-resolution bugs. It also helped draft the CLAUDE.md and README files that explain why decisions were made. Design judgment stayed with me, as in decision 3 above.

+
+
+

Technical Architecture

+

ArchParser is a monorepo with three workspaces: a NestJS backend, a React and Vite frontend built with RadixUI, and shared TypeScript types that catch API contract drift at compile time. The backend handles PDF-to-PNG conversion and Tesseract.js extraction, configurable OCR templates, a WebSocket gateway for live progress, and the optional LLM service. TypeORM and MySQL store jobs, drawing sets, drawings, templates, and knowledge chunks, with self-referencing drawing sets for revision tracking. The frontend includes a filterable dashboard, a PDF upload workflow, drawing review pages with inline editing, and a mock server so the interface can be developed without the backend. The backend has 14 test suites with 53 tests.

+
+
+
Set Details
+
+ Image of the drawing set details page +
+
+
+
Drawing List
+
+ Image of the drawing list page +
+
+
+
Drawing Details
+
+ Image of the drawing details page +
+
+
+
+
+

Key Iterations

+

Real-world testing forced two architectural changes. First, 500+ page PDFs exhausted memory because the first version converted the whole document to images at once. I switched to single-page conversion with batch sizes that adapt to document size, plus sequential OCR processing and memory monitoring, and large sets now process without crashes.

+

Second, processed drawings lost their link to database records after restarts, caused by inconsistent path resolution, a naming mismatch on deletion, and absolute paths stored in the database. I centralized path handling, standardized folder names, stored relative paths, and migrated 373 existing records, which also made the system portable across environments. The dashboard was refined too, with independent pagination and sorting, date and status filters, and a Kanban-style monitor view, after high-volume tables proved hard to navigate.

+
+ +
+
+
+

What I Learned

+
+
+
    +
  1. Test with realistic data from the start. 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.
  2. +
  3. Empowering users beat clever engineering. The visual template creator did more for adoption than any backend optimization, because it removed a bottleneck.
  4. +
  5. An AI partner speeds implementation, not judgment. Claude Code accelerated architecture work, debugging, and boilerplate, but the decisions about consistency and what users already know were mine to make.
  6. +
+
+
+
+
+ +
diff --git a/src/pages/portfolio/casim.md b/src/pages/portfolio/casim.md new file mode 100644 index 00000000..0b6bed2f --- /dev/null +++ b/src/pages/portfolio/casim.md @@ -0,0 +1,63 @@ +--- +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." + badges: ["AI", "MCP", "Enterprise"] + group: "Professional" + featured: true +date: git Last Modified +abbreviation: 'casim' +description: 'How I designed CASim, an internal AI assistant for a construction software company, and the MCP-based framework that decides what it can reach.' +eleventyNavigation: + key: CASim + parent: Portfolio + order: 1 +--- + +
+

Project Overview

+
+

Role:Creative Lead & Architect (design, MCP server, agents, prompts, and tooling)

+

Type:Internal Tool

+

Stack:TypeScript MCP server, Claude Desktop, MCP Inspector, custom web interface

+

Status:In Progress · Currently in UAT and beta testing

+
+
+ +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. + + + +I assumed the hard part would be the AI. It was the data. Over the years, data entry had drifted from consistent inputs to a loose, sometimes conflicting set of values. Construction supplies were the clearest example: names slipped, dimensions were written several ways, and multiple identifiers meant the same product with no link between them. An assistant that sits on top of that data inherits every inconsistency, and it answers confidently regardless. + +## The decision + +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. + +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. + +## What I built + +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. + + + +I also designed the access model around a simple principle I later presented to IT leadership: gate the connectors and data scope, not the creativity. A working server made the argument concrete, because leadership could see exactly what the assistant could reach and what it couldn't. + + + +## Outcome + +The decision was not universally popular. There was real pushback about how the data was being handled and about what information might be missed, forgotten, or lost in the cleanup. That concern was fair, and it shaped how carefully we approached it. + +The initial results answered it. They showed there was real insight sitting in the system that nobody could reach, and that the cleanup path was the right one. The question that had been nearly impossible, budget against end-of-project financials including work orders, change orders, and supply markup, became answerable. CASim is now in UAT and beta testing, so the adoption story is still being written. + +## Reflections + +Now that the project is in beta and proceeding through UAT, I am able to reflect on what I'd do differently and, potentially, what I would change moving forward in how I approach AI products. + +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. + +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. diff --git a/src/pages/case-studies/color-picker.md b/src/pages/portfolio/color-picker.md similarity index 74% rename from src/pages/case-studies/color-picker.md rename to src/pages/portfolio/color-picker.md index d4904c09..60fa5c1c 100644 --- a/src/pages/case-studies/color-picker.md +++ b/src/pages/portfolio/color-picker.md @@ -1,6 +1,13 @@ --- layout: markdown.njk title: 'Color Picker' +portfolioOrder: 7 +card: + title: "Color Picker" + summary: "As one of the most up-voted feature requests, the goal was to create an accessible option that combined colors with patterns." + badges: ["A11y", "Components"] + group: "Professional" + featured: false date: git Last Modified abbreviation: 'colorpicker' description: 'Accessible color picker combining WCAG compliance with patterns.' @@ -15,7 +22,7 @@ containers: true ## Project Overview -> A native iOS app, built by a coach, who needed fast and reliable game tracking without surrendering data to a third-party platform — designed for the sideline, built in Swift. +> An accessible color picker for the design system that pairs WCAG-compliant colors with patterns and icons, so color is never the only way to tell labels apart. :::card @@ -31,7 +38,7 @@ containers: true ## Introduction -A color picker, but nature, is not accessible - the goal of this component design was to provide a solution that not only allowed users to select colors for labels, but also provide alternatives such as patterns and icons. +A color picker is not accessible by nature, so the goal of this component design was to provide a solution that not only allowed users to select colors for labels, but also provide alternatives such as patterns and icons.
@@ -93,6 +100,6 @@ Once the basic levels had been configured, I needed to compare the current label Once the prototype was up and running, I was able to test out the interactions, visuals, and test the new component with users. -After reviewing the findings, it was determined that another round of design and testing was needed before we could release the color picker to production. +The color picker launched to production. The findings from this round also fed follow-up work: another round of design and testing. :::: diff --git a/src/pages/designs/component-library.md b/src/pages/portfolio/component-library.md similarity index 91% rename from src/pages/designs/component-library.md rename to src/pages/portfolio/component-library.md index 999eb31c..26a6f2e9 100644 --- a/src/pages/designs/component-library.md +++ b/src/pages/portfolio/component-library.md @@ -1,5 +1,14 @@ --- title: 'Component Library' +portfolioOrder: 5 +card: + title: "Component Library" + summary: "Built comprehensive design system for construction management software spanning web and iOS applications. Created design tokens, component documentation, and prototypes that accelerated development cycles by 25%." + image: "/assets/img/Storybook-GettingStarted.webp" + imageAlt: "Getting Started screen on Storybook" + badges: ["Library", "Design Tokens"] + group: "Professional" + featured: true date: git Last Modified abbreviation: 'componentlibrary' description: 'Design System for Construction Management Software' @@ -143,9 +152,3 @@ eleventyNavigation:
-
-
- Previous Case Study - Next Case Study -
-
diff --git a/src/pages/designs/customer-engagement.md b/src/pages/portfolio/customer-engagement.md similarity index 98% rename from src/pages/designs/customer-engagement.md rename to src/pages/portfolio/customer-engagement.md index b41e4e87..78aea2f4 100644 --- a/src/pages/designs/customer-engagement.md +++ b/src/pages/portfolio/customer-engagement.md @@ -27,7 +27,7 @@ eleventyNavigation:

THE CHALLENGE: - Saylent Technologies' Customer Engagement App (CEA) was a critical platform for credit unions and regional banks to track customer engagement and manage marketing campaigns. However, the existing interface was outdated, cluttered, and difficult to use—resulting in frustrated users and inefficient workflows. + Saylent Technologies' Customer Engagement App (CEA) was a critical platform for credit unions and regional banks to track customer engagement and manage marketing campaigns. However, the existing interface was outdated, cluttered, and difficult to use, resulting in frustrated users and inefficient workflows.

The company needed a complete UX overhaul that would: