Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
The lukemcdonald.com project is a personal website built with the Astro framework. It operates as a static site that integrates markdown and YAML content collections into structured layouts using vanilla TypeScript and TailwindCSS. The architecture emphasizes a domain-driven "feature" structure, strict type safety, and a robust testing suite consisting of unit and end-to-end tests.
Sources: AGENTS.md:5-10, README.md:5-15
Project Structure
The codebase follows a modular organization that separates core framework routes from domain-specific logic. The src/features/ directory houses "domain modules" such as navigation, pages, and resume, which contain their own schemas, types, and utilities.
| Directory | Purpose |
|---|---|
src/pages/ | Astro routes and page components |
src/features/ | Domain-specific logic, schemas, and helpers |
src/content/ | Content collections (Markdown for pages, YAML for resume) |
src/components/ | Shared UI components |
src/layouts/ | Page shells and structural templates |
src/utils/ | Generic utility functions |
Sources: AGENTS.md:65-75
Feature Module Pattern
Each domain within src/features/ adheres to a standard file structure to ensure consistency across the application.
The domain.schema.ts file defines content validation, while domain.server.ts handles collection loaders and queries.
Sources: AGENTS.md:79-87
Data Modeling and Content
The site manages content through Astro Content Collections. Metadata is validated using Zod schemas to ensure type safety during the build process.
Page Schema
The createPagesSchema function validates frontmatter for markdown pages. It handles SEO metadata, draft status, and publication dates.
| Field | Type | Description |
|---|---|---|
title | string | The primary heading of the page |
draft | boolean | Flag to hide content from production builds (default: false) |
order | number | Optional sorting weight |
seo | object | Nested object for title, description, and OG image overrides |
Sources: src/features/pages/pages.schema.ts:5-24
Resume Schema
The resume system uses a complex union schema to validate diverse YAML data structures, including experience, education, and skills.
SEO and Metadata
The system generates structured JSON-LD data and social meta tags to improve search engine visibility.
JSON-LD Graph Generation
The buildGraphJsonLd function constructs a schema graph containing WebSite, WebPage, and Person nodes. It maps internal content types (article, blog, page) to corresponding Schema.org types.
Sources: src/utils/seo/schema.ts:10-74
Testing Architecture
The project employs a dual-layered testing strategy: unit tests for logic and Playwright for browser-level behavior.
Testing Frameworks
- Unit Tests: Uses
node:testandnode:assert/strict. Tests are colocated as*.test.tsnext to their respective modules. - End-to-End (E2E): Uses Playwright located in the
e2e/directory.
E2E Page Object Model
E2E tests utilize a Page Object Model (POM) to abstract UI interactions. The BasePage class provides shared functionality like navigation and theme seeding.
Accessibility Audits
Automated accessibility checks are integrated into the E2E suite using @axe-core/playwright. The system loops through all defined routes and themes to ensure WCAG A/AA compliance.
Sources: e2e/specs/accessibility.spec.ts:5-25
Development Workflow
The project uses pnpm as the package manager and implements strict CI/CD guardrails.
Build and Validation Scripts
Common tasks are managed via package.json scripts:
pnpm validate: Runs linting, formatting checks, type checking, and unit tests.pnpm audit:code: Executesfallowto audit code quality and hotspots.pnpm test:e2e: Runs the Playwright test suite.
Sources: package.json:10-35, AGENTS.md:12-20
Infrastructure
The site is hosted on Netlify, which triggers daily rebuilds for dynamic content like the "verse of the day." Analytics are provided by Cloudflare Web Analytics via a proxied beacon.
Sources: README.md:17-25
The architecture prioritizes a "no UI runtime" approach, favoring native HTML elements (<dialog>, <select>) and minimal vanilla TypeScript over libraries like React for client-side interactivity.
Sources: AGENTS.md:100-105