diff --git a/.documentation/specs/001-github-repo-showcase/checklists/requirements.md b/.documentation/specs/001-github-repo-showcase/checklists/requirements.md new file mode 100644 index 0000000..adb7a8e --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/checklists/requirements.md @@ -0,0 +1,48 @@ +# Specification Quality Checklist: GitHub Repository Showcase App + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-04-16 +**Feature**: [spec.md](../spec.md) + +## Shared Validation Contract + +- [x] Frontmatter includes all required route metadata fields +- [x] Route metadata is internally consistent for a full-spec workflow +- [x] Status line is present and uses a valid lifecycle state +- [x] Required top-level sections are present exactly once and in canonical order +- [x] No more than 3 clarification markers are present +- [x] Required full-spec content exists for user stories, edge cases, requirements, and success criteria +- [x] Scope boundaries, assumptions, or constraints are documented in route-appropriate sections + +## Content Quality + +- [x] Frontmatter matches the shared validation contract +- [x] Required headings for the selected route are present in canonical order +- [x] Status line uses a valid lifecycle state +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Validation completed on 2026-04-16 against `.devspark/spec-validation-contract.md`. +- No clarification round is required before proceeding to `/devspark.plan`. diff --git a/.documentation/specs/001-github-repo-showcase/contracts/repository-showcase-contract.md b/.documentation/specs/001-github-repo-showcase/contracts/repository-showcase-contract.md new file mode 100644 index 0000000..e11ca79 --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/contracts/repository-showcase-contract.md @@ -0,0 +1,101 @@ +# Contract: Repository Showcase Data Flow + +## Purpose + +Define the expected interface between BootstrapSpark and the Mark Hazleton repository dataset for the GitHub Repository Showcase app. + +## Endpoints + +### Development Fetch Contract + +- Route: `/api/repositories` +- Transport: Vite development proxy +- Upstream source: raw or hosted repository dataset for `markhazleton` +- Method: `GET` +- Expected content type: `application/json` + +### Production Fetch Contract + +- Route: `/api/proxy-repositories` +- Transport: Azure Function HTTP endpoint +- Upstream source: hosted repository dataset for `markhazleton` +- Method: `GET` +- Expected content type: `application/json` + +### Embedded Fallback Contract + +- Path: `src/data/repositories.json` +- Purpose: last-resort bundled fallback when remote and cached data are unavailable + +## Response Shape + +The application expects a JSON object with this top-level structure: + +```json +{ + "profile": {}, + "repositories": [], + "metadata": {} +} +``` + +## Required Top-Level Fields + +| Field | Type | Required | Description | +| ------ | ------ | ------ | ------ | +| `profile.username` | string | Yes | GitHub account identifier | +| `profile.total_repositories` | number | Yes | Repository count for hero summary | +| `profile.total_stars` | number | Yes | Aggregate stars metric | +| `profile.total_forks` | number | Yes | Aggregate forks metric | +| `profile.total_commits` | number | Yes | Aggregate commit metric | +| `repositories` | array | Yes | Repository collection | +| `metadata.generated_at` | string | Yes | Feed generation timestamp | +| `metadata.schema_version` | string | Yes | Feed schema identifier | + +## Minimum Repository Record + +Each rendered repository must provide at least: + +```json +{ + "name": "BootstrapSpark", + "url": "https://github.com/markhazleton/BootstrapSpark", + "description": "...", + "stars": 0, + "forks": 0, + "language": "TypeScript", + "updated_at": "2026-04-14T00:25:37+00:00", + "pushed_at": "2026-04-14T03:25:09+00:00" +} +``` + +Additional fields such as `summary`, `recent_commits_90d`, `commit_history`, `attention_score`, `rank`, `composite_score`, `has_pages`, `has_tests`, and `screenshot` may be used to enrich the experience and support automatic featured fallback. + +## Behavioral Rules + +- The service must validate the full payload with Zod before caching or UI mapping. +- If remote fetch fails, the service may serve cached data if available and still structurally valid. +- If both remote and cache are unavailable or invalid, the service must fall back to the embedded JSON snapshot. +- Private repositories must not be rendered even if they appear unexpectedly in the source payload. +- Archived and forked repositories may be rendered but must be visually labeled. +- Featured status must prefer explicit curated designation if the feed exposes one; otherwise the service may derive featured records from ranking, score, recency, and quality cues. + +## Cache Contract + +Suggested cache metadata keys: + +- `cachedRepositoriesData` +- `repositoriesLastUpdated` +- `repositoriesCount` +- `repositoriesSource` +- `repositoriesCacheVersion` + +## Error Contract + +If no valid source is available, the UI must show: + +- A non-breaking error state +- A clear user-facing recovery message +- A retry affordance when practical + +The UI must never render a blank route caused by an unhandled repository feed failure. diff --git a/.documentation/specs/001-github-repo-showcase/data-model.md b/.documentation/specs/001-github-repo-showcase/data-model.md new file mode 100644 index 0000000..40836d8 --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/data-model.md @@ -0,0 +1,188 @@ +# Data Model: GitHub Repository Showcase App + +## Source Feed + +### RepositoryFeed + +Represents the full upstream JSON document fetched from the generated repository dataset. + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `profile` | `ProfileSummary` | Yes | Top-level statistics and activity summaries for `markhazleton` | +| `repositories` | `RepositoryRecord[]` | Yes | Repository collection used to populate highlights and list views | +| `metadata` | `FeedMetadata` | Yes | Generator and schema metadata for freshness and compatibility messaging | + +### FeedMetadata + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `generated_at` | string | Yes | Feed generation timestamp used for freshness messaging | +| `schema_version` | string | Yes | Schema identifier used for compatibility checks | +| `source` | string | Optional | Upstream generator/source identifier when provided | + +## Profile and Activity + +### ProfileSummary + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `username` | string | Yes | Expected to identify the GitHub account being showcased | +| `total_repositories` | number | Yes | Used in hero metrics | +| `total_stars` | number | Yes | Used in hero metrics | +| `total_forks` | number | Yes | Used in hero metrics | +| `total_commits` | number | Yes | Used in hero metrics | +| `activity_calendar` | record of date to number | Optional | Supports compact freshness or activity storytelling | +| `weekly_activity` | `WeeklyActivity[]` | Optional | Supports recent activity summaries | + +### WeeklyActivity + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `week` | string | Yes | ISO-like week identifier | +| `label` | string | Yes | Human-readable label | +| `commits` | number | Yes | Weekly commit count | +| `active_repos` | number | Yes | Repositories active during the week | + +## Repository Domain + +### RepositoryRecord + +Represents a single repository entry from the upstream feed after validation. + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `name` | string | Yes | Primary repository identifier | +| `description` | string or null | Optional | Short GitHub description | +| `summary` | `RepositorySummary` | Optional | Curated or generated summary text | +| `url` | string | Yes | Canonical repository URL | +| `homepage` | string or null | Optional | External homepage if available | +| `has_pages` | boolean | Optional | Indicates GitHub Pages presence | +| `pages_url` | string or null | Optional | Public pages URL | +| `website_url` | string or null | Optional | Website destination used by the dataset | +| `stars` | number | Yes | Used in ranking and badges | +| `forks` | number | Yes | Used in ranking and badges | +| `watchers` | number | Optional | Secondary interest signal | +| `language` | string or null | Optional | Primary language label | +| `created_at` | string | Yes | ISO timestamp | +| `updated_at` | string | Yes | ISO timestamp | +| `pushed_at` | string | Yes | ISO timestamp | +| `total_commits` | number | Optional | Aggregate history cue | +| `recent_commits_90d` | number | Optional | Recent activity cue | +| `commit_history` | `CommitHistorySummary` | Optional | Activity and recency details | +| `tech_stack` | `TechStackSummary` or null | Optional | Dependency and ecosystem clues | +| `has_readme` | boolean | Optional | Repository maturity signal | +| `has_license` | boolean | Optional | Repository maturity signal | +| `has_ci_cd` | boolean | Optional | Repository maturity signal | +| `has_tests` | boolean | Optional | Repository maturity signal | +| `has_docs` | boolean | Optional | Repository maturity signal | +| `is_fork` | boolean | Optional | Filter/status cue | +| `is_private` | boolean | Optional | Should generally be false for displayable items | +| `is_archived` | boolean | Optional | Filter/status cue | +| `days_since_last_push` | number | Optional | Recency cue | +| `attention_score` | number | Optional | Relative importance or health input | +| `rank` | number | Optional | Upstream ranking cue | +| `composite_score` | number | Optional | Ranking cue | +| `screenshot` | `RepositoryScreenshot` or null | Optional | Hero or card media candidate | + +### RepositorySummary + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `text` | string | Yes | Best short explanation of repository value | +| `ai_generated` | boolean | Optional | Source provenance indicator | +| `generation_method` | string or null | Optional | Provenance detail | +| `confidence_score` | number or null | Optional | Optional trust cue | + +### CommitHistorySummary + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `total_commits` | number | Optional | Aggregate count | +| `recent_90d` | number | Optional | Activity measure | +| `last_commit_date` | string | Optional | Recency display | +| `patterns` | string[] | Optional | Labels like `recently_updated` or `consistent` | +| `days_since_last_commit` | number | Optional | Supports freshness labels | + +### TechStackSummary + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `dependency_file_type` | string | Optional | Context for dependency data | +| `currency_score` | number | Optional | Dependency health cue | +| `outdated_count` | number | Optional | Maintenance cue | +| `total_dependencies` | number | Optional | Complexity cue | +| `dependencies` | `DependencyRecord[]` | Optional | Badge/filter candidate | + +### DependencyRecord + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `name` | string | Yes | Dependency name | +| `ecosystem` | string | Optional | npm, pypi, nuget, etc. | +| `current_version` | string or null | Optional | Display cue | +| `status` | string or null | Optional | Currency cue | +| `source_file` | string or null | Optional | Provenance | + +### RepositoryScreenshot + +| Field | Type | Required | Notes | +| ------ | ------ | ------ | ------ | +| `url` | string | Optional | Candidate showcase media | +| `captured_at` | string | Optional | Freshness cue | +| `width` | number | Optional | Media sizing metadata | +| `height` | number | Optional | Media sizing metadata | + +## UI-Derived Models + +### RepositoryShowcaseViewModel + +A derived object prepared by the service layer for the page component. + +| Field | Type | Notes | +| ------ | ------ | ------ | +| `profile` | `ProfileHeroMetrics` | Reduced metric payload for hero and summary sections | +| `featured` | `RepositoryCardViewModel[]` | Curated-first spotlight repositories | +| `repositories` | `RepositoryCardViewModel[]` | Searchable and sortable list records | +| `filters` | `RepositoryFilterCatalog` | Distinct filter values derived from validated data | +| `sourceStatus` | `SourceStatus` | Remote, cache, or embedded fallback state | + +### RepositoryCardViewModel + +| Field | Type | Notes | +| ------ | ------ | ------ | +| `name` | string | Display title | +| `description` | string | Non-empty description or fallback summary | +| `summaryText` | string | Richer explanatory text for spotlight or tooltips | +| `primaryLanguage` | string or null | Badge/filter cue | +| `repoUrl` | string | Main outbound destination | +| `siteUrl` | string or null | Optional live-site destination | +| `stars` | number | Metric badge | +| `forks` | number | Metric badge | +| `recentCommits90d` | number | Activity badge | +| `statusTags` | string[] | Derived labels such as featured, archived, pages, tested | +| `featuredSource` | `curated` or `automatic` or `none` | Clarified featured-state provenance | +| `sortMetrics` | object | Precomputed sort values for activity, score, recency | + +### SourceStatus + +| Field | Type | Notes | +| ------ | ------ | ------ | +| `source` | `remote` or `cache` or `local` | Current content source | +| `lastUpdated` | string or null | Cache/fetch timestamp | +| `count` | number | Repository count presented to the user | +| `message` | string | User-facing freshness or fallback message | + +## Relationships + +- One `RepositoryFeed` contains one `ProfileSummary` and many `RepositoryRecord` items. +- One `RepositoryRecord` may contribute to zero or more `RepositoryInsightGroup` buckets in the UI, such as featured, recent, or language-based groups. +- `RepositoryShowcaseViewModel` is derived from the validated feed and should never bypass schema parsing. +- Featured repositories are selected from `RepositoryRecord` items using curated designation first, then automatic ranking fallback if curated designation is absent. + +## Validation Rules + +- Reject feeds that omit the top-level `profile`, `repositories`, or `metadata` objects. +- Reject repository entries without a `name` or canonical `url`. +- Normalize null or empty descriptive fields into safe fallback strings before display. +- Exclude private repositories from rendered results if they ever appear in the source feed. +- Preserve archived and forked repositories, but label them so they do not overpower active featured work. diff --git a/.documentation/specs/001-github-repo-showcase/plan.md b/.documentation/specs/001-github-repo-showcase/plan.md new file mode 100644 index 0000000..37c9ff6 --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/plan.md @@ -0,0 +1,126 @@ +# Implementation Plan: GitHub Repository Showcase App + +**Branch**: `001-github-repo-showcase` | **Date**: 2026-04-17 | **Spec**: [.documentation/specs/001-github-repo-showcase/spec.md](./spec.md) +**Input**: Feature specification from `.documentation/specs/001-github-repo-showcase/spec.md` + +## Summary + +Build a new repository showcase app inside BootstrapSpark that presents Mark Hazleton's GitHub repository portfolio with a dedicated route, curated-first featured highlights, recent activity context, client-side discovery controls, and resilient data loading. The implementation will follow the existing Projects and Articles pattern: typed model + Zod validation, development proxy + Azure Function proxy, local embedded fallback data, generated sitemap/SEO route integration, polished Bootstrap-first UI, and layered test coverage across service, contract, and component flows. + +## Technical Context + +**Language/Version**: TypeScript 5.9.x, React 19, Node.js-based Vite toolchain +**Primary Dependencies**: React Router, React Bootstrap, Bootstrap 5, React Bootstrap Icons, Zod, Vitest, Testing Library +**Storage**: Browser localStorage cache for fetched dataset metadata and payload; embedded JSON fallback in `src/data/` +**Testing**: Vitest, @testing-library/react, @testing-library/user-event, jsdom, existing contract/integration/unit test layout +**Target Platform**: Static React web app deployed to Azure Static Web Apps and GitHub Pages, with Azure Function proxy endpoints for production data access +**Project Type**: Single web application +**Performance Goals**: Repository route renders meaningful above-the-fold content quickly, keeps client-side filtering and sorting instantaneous for the expected repository set, and preserves responsive interaction on phone and desktop layouts +**Constraints**: Must preserve BootstrapSpark architecture and Bootstrap 5 styling, must validate external data with Zod, must provide graceful fallback when remote data is unavailable, must maintain keyboard accessibility, must keep CSP and proxy configuration aligned across Vite and Azure deployment +**Scale/Scope**: One new app route plus supporting service/model/data/proxy/SEO/test updates; current dataset size is roughly dozens of repositories with profile metrics and weekly activity, but the design should remain workable as the dataset grows modestly over time + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- **Type Safety**: PASS. New repository models, service responses, and derived view models will be fully typed in TypeScript with strict-mode-safe parsing. +- **Code Quality & Linting**: PASS. The feature fits existing linted React + TypeScript patterns and should not require rule exceptions. +- **Testing**: PASS WITH REQUIRED WORK. Implementation must add automated coverage for schema parsing, fallback behavior, and repository UI flows before merge. +- **Documentation**: PASS. Feature artifacts remain under `.documentation/specs/001-github-repo-showcase/` and should stay synchronized with the delivered behavior. +- **Component Architecture**: PASS. Work cleanly maps to `src/components`, `src/services`, `src/models`, `src/data`, and `tests/`. +- **Error Handling & Resilience**: PASS WITH REQUIRED WORK. The data service must mirror the existing multi-layer fallback pattern used by Projects and RSS. +- **Logging & Observability**: PASS. Existing development-time logging is acceptable, but production behavior must continue to rely on the configured strip step. +- **Input Validation & Security**: PASS WITH REQUIRED WORK. Remote repository data must be validated with Zod, and any new proxy endpoint must respect current CORS and CSP expectations. +- **Styling Standards**: PASS. The feature is explicitly Bootstrap-first and should integrate with current theme support and SCSS structure. +- **Code Quality Gates**: PASS. The plan remains compatible with existing lint, type-check, test, and build commands. + +**Post-Design Re-check**: No constitutional conflicts were introduced by the chosen design. The main enforcement items for implementation are Zod runtime validation, resilient fallback behavior, Bootstrap/theming consistency, and new automated tests. + +## Project Structure + +### Documentation (this feature) + +```text +.documentation/specs/001-github-repo-showcase/ +├── plan.md +├── research.md +├── data-model.md +├── quickstart.md +├── contracts/ +│ └── repository-showcase-contract.md +├── checklists/ +│ └── requirements.md +└── tasks.md +``` + +### Source Code (repository root) + +```text +src/ +├── components/ +│ ├── Header.tsx +│ └── Repositories.tsx +├── config/ +│ └── AppConfig.ts +├── data/ +│ └── repositories.json +├── models/ +│ └── Repository.ts +├── services/ +│ └── RepositoryService.ts +├── utils/ +│ └── generateSitemap.ts +├── App.tsx +└── test/ + +api/ +└── proxy-repositories/ + ├── function.json + ├── index.js + └── package.json + +tests/ +├── contract/ +│ └── repositories/ +├── integration/ +│ └── repositories/ +└── unit/ + ├── components/ + ├── models/ + └── services/ +``` + +**Structure Decision**: Keep the feature inside the existing single-app React frontend with a matching Azure Function proxy, following the same service/model/component separation already used by Projects and Articles. + +## Implementation Strategy + +### Phase 0: Research Completion + +- Confirm the remote repository dataset shape and select the subset of fields the UI will depend on directly. +- Lock the ingestion pattern to the existing remote → cache → embedded fallback model already used in BootstrapSpark. +- Define the featured-repository rule as curated-first with automatic fallback when curated metadata is absent. +- Choose a UI composition that showcases profile metrics, featured repositories, activity context, and a searchable/sortable repository collection without introducing new design systems. + +### Phase 1: Design Artifacts + +- Define a typed repository domain model covering top-level profile metrics, weekly activity summaries, explicit feed metadata, and individual repository records. +- Document the repository data contract for development proxy, production proxy, and embedded fallback expectations. +- Document a quickstart flow that validates route wiring, remote data loading, fallback behavior, and test execution. +- Update agent context from the completed plan so downstream task generation sees the selected stack and feature shape. + +### Phase 2: Implementation Slices + +- **Slice 1: Data foundation** + Add repository model schemas, service fetch logic, curated-first featured selection, private-repository exclusion, explicit feed metadata handling, embedded fallback data, and production/development proxy support. +- **Slice 2: Route and navigation** + Register the repository route, lazy-load the page, expose it through the Apps navigation structure, and include the route in generated sitemap/SEO output. +- **Slice 3: Showcase experience** + Build the page layout with hero metrics, recent activity summaries, featured spotlight treatment, repository cards, retry-capable error states, and strong Bootstrap-forward presentation. +- **Slice 4: Discovery controls** + Add search, filtering, sorting, paging/grouping, empty states, and freshness messaging. +- **Slice 5: Validation and resilience** + Add tests for schemas, service fallback behavior, private-repository exclusion, generated sitemap coverage, retry behavior, and critical UI flows; then run lint, type-check, tests, and build verification. + +## Complexity Tracking + +No constitution exceptions or unusual complexity justifications are required at planning time. The feature extends existing site patterns rather than introducing a new subsystem or architecture tier. diff --git a/.documentation/specs/001-github-repo-showcase/quickstart.md b/.documentation/specs/001-github-repo-showcase/quickstart.md new file mode 100644 index 0000000..ae9e7aa --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/quickstart.md @@ -0,0 +1,62 @@ +# Quickstart: GitHub Repository Showcase App + +## Goal + +Validate the repository showcase feature end to end inside BootstrapSpark during implementation. + +## Prerequisites + +- Node.js version compatible with the existing Vite and Vitest toolchain +- npm dependencies installed in the repository root +- Active feature branch: `001-github-repo-showcase` + +## Build and Run + +1. Install dependencies if needed. + +```powershell +npm install +``` + +2. Start the local development experience. + +```powershell +npm run dev +``` + +3. Open the app at the local Vite URL and navigate to the new repository showcase route from the Apps menu. + +## Implementation Validation Checklist + +1. Confirm the header exposes a repository showcase entry and the route loads without errors. +2. Confirm the page displays a distinct repository-focused hero area rather than reusing Projects wording. +3. Confirm repository data loads through the development proxy and exposes profile metrics plus repository cards. +4. Confirm featured repositories appear using curated-first logic, with automatic fallback when curated metadata is not available. +5. Confirm search, filter, and sort controls update the visible list and handle zero-match states gracefully. +6. Confirm the page reports freshness or fallback source information in a user-friendly way. +7. Confirm phone-width and desktop-width layouts both preserve the main interactions. +8. Confirm keyboard navigation reaches search, filters, sort controls, and outbound links. + +## Automated Verification + +Run the project quality gates after implementation changes. + +```powershell +npm run lint +npm run type-check +npm run test:coverage +npm run build +``` + +## Expected Test Coverage Additions + +- Unit tests for repository schema parsing and view-model mapping +- Unit tests for repository service cache and fallback behavior +- Contract tests for the repository feed shape +- Integration or component tests for route rendering, empty states, and discovery controls + +## Production-Specific Checks + +1. Validate the production proxy path serves repository data through the Azure Function endpoint. +2. Confirm CSP and CORS remain compatible with the new repository data source. +3. Confirm the generated site still builds to `docs/` and the route works in preview or deployed environments. diff --git a/.documentation/specs/001-github-repo-showcase/research.md b/.documentation/specs/001-github-repo-showcase/research.md new file mode 100644 index 0000000..c0c7ffc --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/research.md @@ -0,0 +1,49 @@ +# Research: GitHub Repository Showcase App + +## Decision 1: Use the existing BootstrapSpark remote-cache-local fallback pattern + +- Decision: Implement repository ingestion with the same layered strategy used by Projects and RSS: development proxy, production Azure Function proxy, localStorage cache, and embedded JSON fallback. +- Rationale: This repository already relies on that pattern for external content and the constitution requires graceful degradation when remote services fail. +- Alternatives considered: + - Direct browser fetch from the GitHub raw URL only. Rejected because production reliability and CORS behavior would be weaker than the existing site pattern. + - Build-time-only data ingestion. Rejected because the rest of BootstrapSpark favors runtime refresh with cache fallback rather than requiring a rebuild for fresh data. + +## Decision 2: Model the source as a profile-plus-repositories feed, then adapt it to UI view models + +- Decision: Preserve the upstream dataset shape in validation and service parsing, then derive page-specific view models for spotlight cards, filters, and summary metrics. +- Rationale: The source feed contains more information than the UI needs on first render, including profile metrics, weekly activity, and rich per-repository metadata. Separating raw-source parsing from display mapping keeps validation strict and UI code simpler. +- Alternatives considered: + - Flatten the source schema directly into component props. Rejected because it would couple the UI too tightly to a large external payload. + - Ignore profile and activity metadata and render only repository cards. Rejected because the spec calls for a showcase experience, not a plain repository list. + +## Decision 3: Define featured repositories as curated-first with automatic fallback + +- Decision: If the dataset exposes an explicit featured or curated designation, honor it first. Otherwise, compute featured repositories from repository quality and activity cues already in the feed. +- Rationale: This resolves the clarified spec requirement while preserving intentional curation and still allowing the app to work if curated metadata is not present. +- Alternatives considered: + - Manual curation only. Rejected because the page could degrade to no featured content when explicit curation is absent. + - Metrics-only ranking. Rejected because it removes editorial control from the showcase experience. + +## Decision 4: Add a dedicated repository service, model, route, and proxy rather than extending Projects + +- Decision: Create `RepositoryService`, `Repository` model/schema, a dedicated `Repositories` component, a new route, and a matching Azure Function proxy. +- Rationale: The repository feed has a richer schema and different browsing goals than the simpler projects dataset. Keeping it separate preserves clean architecture and keeps the Projects feature focused. +- Alternatives considered: + - Extend the Projects page to support multiple data modes. Rejected because it would blend two unrelated information architectures into one component. + - Render repository data inside an existing demo/showcase page. Rejected because the feature is part of the Apps information architecture and should remain discoverable there. + +## Decision 5: Treat the external JSON feed as a runtime contract and validate it with Zod + +- Decision: Create Zod schemas for the top-level profile object, weekly activity items, and repository records before any caching or UI mapping occurs. +- Rationale: The constitution explicitly requires runtime validation for external data. Early validation also gives predictable fallback behavior and cleaner tests. +- Alternatives considered: + - Trust the remote JSON and validate only selected fields late in the UI. Rejected because it increases risk of runtime breakage and contradicts the repo's validation standard. + - Validate only the repository array. Rejected because profile metrics and activity summaries are also central to the planned showcase. + +## Decision 6: Keep the UI contract centered on Bootstrap-first presentation with existing route and test patterns + +- Decision: Build the new page with the same route wiring, lazy loading, theme compatibility, and test layout already used in BootstrapSpark, while pushing the visuals further through stronger metric panels, spotlight sections, and richer card treatment. +- Rationale: The feature should look more theatrical than Projects and Articles, but still feel native to the site and fit existing maintenance patterns. +- Alternatives considered: + - Introduce a new charting or motion library. Rejected at planning time because the feature can achieve the required polish using the current stack and should minimize new dependencies. + - Reuse the Projects layout almost unchanged. Rejected because the spec explicitly calls for a more world-class showcase feel. diff --git a/.documentation/specs/001-github-repo-showcase/spec.md b/.documentation/specs/001-github-repo-showcase/spec.md new file mode 100644 index 0000000..112bf8d --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/spec.md @@ -0,0 +1,164 @@ +--- +classification: full-spec +risk_level: medium +target_workflow: specify-full +required_artifacts: spec, plan, tasks +recommended_next_step: plan +required_gates: checklist, analyze, critic +--- + +# Feature Specification: GitHub Repository Showcase App + +**Feature Branch**: `001-github-repo-showcase` +**Created**: 2026-04-16 +**Status**: Draft +**Input**: User description: "Create a MarkHazleton GitHub Repository app that showcases data from the generated repositories dataset in github-stats-spark, with strong Bootstrap flair and a world-class presentation similar in spirit to the existing Projects and Articles experiences." + +## Rationale Summary + +### Core Problem + +BootstrapSpark currently highlights portfolio projects and articles, but it does not provide a dedicated experience for exploring Mark Hazleton's public GitHub repositories as a living body of work. Visitors who want to evaluate repository breadth, current activity, and open-source focus must leave the site or rely on a less curated GitHub profile view. + +### Decision Summary + +Create a dedicated GitHub Repository Showcase app within BootstrapSpark that transforms the generated repository dataset into a high-impact browsing experience. The app should feel consistent with the site's existing showcase pages while raising the visual ambition through stronger storytelling, richer highlights, and more expressive Bootstrap presentation. + +### Key Drivers + +- Provide a stronger on-site portfolio narrative around Mark Hazleton's public GitHub work. +- Reuse the existing pattern of curated, data-driven showcase pages already established by Projects and Articles. +- Present repository data in a way that is immediately useful for recruiters, collaborators, and technically curious visitors. + +### Source Inputs + +- User request for a new MarkHazleton GitHub Repository app with substantial Bootstrap showmanship. +- Existing BootstrapSpark showcase patterns represented by the Projects and Articles sections. +- Repository data published from the github-stats-spark project for the `markhazleton` account. + +### Tradeoffs Considered + +- Option A: Link users directly to GitHub profile pages without an in-site experience. This was not chosen because it does not demonstrate BootstrapSpark's design and data storytelling capabilities. +- Option B: Fold repository records into the existing Projects page. This was not chosen because repositories have different discovery needs, metadata, and browsing behavior than curated project entries. +- Selected: Create a dedicated repository showcase app that complements, rather than replaces, the existing Projects and Articles experiences. + +### Architectural Impact + +- Adds a new user-facing app or route to the existing BootstrapSpark navigation model. +- Introduces a dedicated repository browsing experience driven by an external generated dataset. +- Preserves backward compatibility for existing pages while expanding the site's portfolio coverage. + +### Assumptions + +- The repository dataset will continue to represent public repository information for the `markhazleton` GitHub account. +- The page should support the same resilience expectations as existing data-driven pages, including meaningful fallback behavior when the freshest remote data is unavailable. +- The showcase is intended for discovery and exploration, not repository management or authenticated GitHub operations. + +### Scope Boundaries + +- In scope: browsing, filtering, sorting, highlighting, and linking out to public repositories. +- In scope: visually rich summary sections that help visitors understand repository themes, activity, and value. +- Out of scope: editing repositories, starring repositories from within the site, or exposing private repository data. + +### Reviewer Guidance + +Reviewers should focus on whether the spec keeps the feature centered on visitor value, clearly distinguishes it from the existing Projects page, and preserves graceful behavior when data is incomplete or temporarily unavailable. + +## Clarifications + +### Session 2026-04-16 + +- Q: How should featured repositories be determined? → A: Use manual curation when available, with automatic fallback when no curated flag exists. + +## User Scenarios & Testing + +### User Story 1 - Browse Repository Portfolio (Priority: P1) + +As a visitor evaluating Mark Hazleton's work, I want a dedicated repository showcase page so that I can quickly understand the breadth and quality of his public GitHub portfolio without leaving the site immediately. + +**Why this priority**: This is the core value of the feature. Without a browsable portfolio view, the app does not meet its purpose. + +**Independent Test**: Can be fully tested by opening the repository showcase page and confirming that a visitor can review repository highlights, summary metrics, and a browsable list of repositories without relying on any other new feature slice. + +**Acceptance Scenarios**: + +1. **Given** a visitor opens the repository showcase page, **When** repository data is available, **Then** the page presents a visually prominent overview and a browsable collection of Mark Hazleton repositories. +2. **Given** a visitor lands on the page for the first time, **When** they scan the opening content, **Then** they can immediately tell that the page is about GitHub repositories rather than general projects or articles. + +--- + +### User Story 2 - Narrow to Relevant Repositories (Priority: P2) + +As a visitor with specific interests, I want to search, filter, and sort repositories so that I can quickly find the repositories most relevant to a topic, language, or level of activity. + +**Why this priority**: Repository counts can grow over time, so discovery controls are necessary for the experience to remain useful. + +**Independent Test**: Can be fully tested by interacting with the repository list controls and verifying that the visible results update to match the selected search and browsing criteria. + +**Acceptance Scenarios**: + +1. **Given** a visitor enters a search term or selects browsing filters, **When** matching repositories exist, **Then** the page reduces the visible results to repositories that match the chosen criteria. +2. **Given** a visitor applies search or filters that produce no matches, **When** the list updates, **Then** the page shows an intentional empty state with a clear recovery path. + +--- + +### User Story 3 - Decide What to Open Next (Priority: P3) + +As a visitor deciding which repository to inspect further, I want each repository entry to explain why it matters so that I can choose whether to open the repository on GitHub. + +**Why this priority**: The showcase should not function as a raw dump of repository records; it needs enough context to support informed exploration. + +**Independent Test**: Can be fully tested by reviewing repository entries and confirming that a visitor can understand purpose, relative importance, and next actions directly from the page. + +**Acceptance Scenarios**: + +1. **Given** a visitor reviews a repository card or spotlight view, **When** they compare repositories, **Then** they can see enough summary information to distinguish active, featured, or especially relevant repositories. +2. **Given** a visitor chooses a repository of interest, **When** they activate the primary call to action, **Then** they are taken to the corresponding public GitHub destination. + +### Edge Cases + +- The primary repository dataset is unreachable or stale when the page loads. +- Some repositories are missing descriptions, topics, language indicators, or other summary metadata. +- The dataset contains a large number of repositories, creating pressure on mobile layout and browsing controls. +- Search and filter combinations return zero matches. +- Archived, forked, or experimental repositories need to remain visible without overshadowing featured work. + +## Requirements + +### Functional Requirements + +- **FR-001**: The system MUST provide a dedicated GitHub Repository Showcase app for Mark Hazleton's public repositories rather than merging this experience into the existing Projects or Articles pages. +- **FR-002**: The system MUST source repository content from the generated repository dataset associated with the `markhazleton` GitHub account. +- **FR-003**: The system MUST present an opening overview that clearly communicates repository portfolio scale and helps visitors understand the purpose of the page at a glance. +- **FR-004**: The system MUST display repository entries with enough summary information for visitors to understand what each repository is about before leaving the site. +- **FR-005**: Users MUST be able to search the repository collection by repository name and descriptive text. +- **FR-006**: Users MUST be able to refine the visible repository set using available dataset attributes that support browsing, such as technology focus, repository status, or activity-related indicators. +- **FR-007**: Users MUST be able to reorder or sort the visible repository set using meaningful repository attributes exposed by the dataset. +- **FR-008**: The system MUST visually distinguish featured repositories by honoring any explicit curated designation in the dataset and falling back to automatic selection only when no curated designation is available. +- **FR-009**: The system MUST provide direct calls to action that open the selected repository in its public GitHub destination. +- **FR-010**: The system MUST communicate data freshness or source status in a visitor-friendly way so users understand whether they are seeing current or fallback content. +- **FR-011**: The system MUST fail gracefully when the freshest remote dataset cannot be loaded, showing either fallback content or a clear recovery message with a retry path instead of an empty or broken page. +- **FR-012**: The system MUST provide intentional empty, loading, and error states that remain visually polished and consistent with the rest of the site. +- **FR-013**: The system MUST feel visually aligned with BootstrapSpark while providing a more theatrical, showcase-oriented presentation than the existing Projects and Articles pages. +- **FR-014**: The system MUST be usable on phone and desktop viewports without losing access to primary discovery actions. +- **FR-015**: The system MUST preserve keyboard-accessible navigation for primary interactive controls and outbound repository actions. +- **FR-016**: The system MUST expose the repository showcase as a first-class public route in site navigation and generated SEO route metadata, including sitemap output. +- **FR-017**: The system MUST present recent activity context alongside portfolio metrics so visitors can quickly understand current repository momentum. +- **FR-018**: The system MUST exclude private repositories from rendered results even if they appear unexpectedly in an upstream payload. + +### Key Entities + +- **Repository Showcase Record**: A public GitHub repository entry used by the page, including identifying details, summary text, status indicators, repository destination, and any available activity or popularity cues. +- **Repository Insight Group**: A visitor-facing grouping or highlight lens that organizes repositories into meaningful sets such as featured work, recent activity, technology themes, or notable categories, with featured status preferring curated designation over automatic fallback. +- **Repository Feed Metadata**: Generator and schema metadata used to describe feed freshness, compatibility, and whether the page is using remote, cached, or embedded fallback content. +- **Showcase State Message**: A visitor-visible state descriptor that explains whether the page is loading, using current data, showing fallback content, or encountering an issue. + +## Success Criteria + +### Measurable Outcomes + +- **SC-001**: In acceptance testing, a first-time visitor can identify the purpose of the page and open at least one relevant repository within 60 seconds of landing on it. +- **SC-002**: In acceptance testing, 90% or more of sampled repository entries provide enough on-page context for reviewers to distinguish repository purpose before opening GitHub. +- **SC-003**: In acceptance testing, users can narrow the repository list to a targeted subset within three interactions or fewer using search, filter, or sort controls. +- **SC-004**: When the freshest remote dataset is unavailable, the page still presents a usable visitor experience with a clear state message in 100% of tested failure scenarios. +- **SC-005**: In responsive acceptance testing, all primary browse, filter, sort, and outbound navigation actions remain usable on both phone-sized and desktop-sized viewports. diff --git a/.documentation/specs/001-github-repo-showcase/tasks.md b/.documentation/specs/001-github-repo-showcase/tasks.md new file mode 100644 index 0000000..b4fe7b7 --- /dev/null +++ b/.documentation/specs/001-github-repo-showcase/tasks.md @@ -0,0 +1,216 @@ +--- + +description: "Executable task list for the GitHub Repository Showcase feature" +--- + +# Tasks: GitHub Repository Showcase App + +**Input**: Design documents from `.documentation/specs/001-github-repo-showcase/` +**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/repository-showcase-contract.md, quickstart.md + +**Tests**: Included. The plan, quickstart, and constitution require automated coverage for schema parsing, fallback behavior, and primary UI flows. + +**Organization**: Tasks are grouped by user story to enable independent implementation and validation. + +## Format: `[ID] [P?] [Story] Description` + +- **[P]**: Can run in parallel when dependencies are satisfied +- **[Story]**: User story label for story-specific tasks only +- Each task includes exact file paths + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: Prepare the repository showcase file structure and feature-specific test surfaces. + +- [ ] T001 Create repository model and service scaffolds in `src/models/Repository.ts` and `src/services/RepositoryService.ts` +- [ ] T002 [P] Create repository page and route test scaffolds in `src/components/Repositories.tsx` and `tests/integration/repositories/RepositoriesPage.test.tsx` +- [ ] T003 [P] Create repository proxy scaffolds in `api/proxy-repositories/function.json`, `api/proxy-repositories/index.js`, and `api/proxy-repositories/package.json` +- [ ] T004 [P] Create repository data and test scaffolds in `src/data/repositories.json`, `tests/unit/models/Repository.test.ts`, `tests/unit/services/RepositoryService.test.ts`, and `tests/contract/repositories/repositoryFeed.contract.test.ts` + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Build the validated data pipeline and runtime plumbing required by all user stories. + +**⚠️ CRITICAL**: No user story work should start until this phase is complete. + +- [ ] T005 Implement Zod schemas and typed repository feed exports in `src/models/Repository.ts` +- [ ] T005 Implement Zod schemas and typed repository feed exports, including explicit `FeedMetadata` fields for freshness and schema compatibility, in `src/models/Repository.ts` +- [ ] T006 [P] Add the embedded repository fallback snapshot in `src/data/repositories.json` +- [ ] T007 Implement repository fetch, validation, cache metadata, private-repository exclusion, curated-first featured selection with automatic fallback ranking, and fallback mapping in `src/services/RepositoryService.ts` +- [ ] T008 [P] Add the development proxy route for `/api/repositories` in `vite.config.ts` +- [ ] T009 Implement the production repository proxy in `api/proxy-repositories/index.js` +- [ ] T010 [P] Configure the repository proxy function metadata and dependencies in `api/proxy-repositories/function.json` and `api/proxy-repositories/package.json` +- [ ] T011 Add contract coverage for the feed shape, explicit metadata fields, and minimum required repository fields in `tests/contract/repositories/repositoryFeed.contract.test.ts` +- [ ] T012 Add unit coverage for schema parsing, view-model derivation, and invalid feed rejection in `tests/unit/models/Repository.test.ts` +- [ ] T013 Add unit coverage for remote, cache, and local fallback behavior, private-repository exclusion, and retry-ready failure handling in `tests/unit/services/RepositoryService.test.ts` + +**Checkpoint**: Repository data can be loaded, validated, cached, and served through both development and production integration paths. + +--- + +## Phase 3: User Story 1 - Browse Repository Portfolio (Priority: P1) 🎯 MVP + +**Goal**: Deliver a dedicated repository showcase route with a strong opening narrative, featured highlights, and a browsable list of repositories. + +**Independent Test**: Navigate to the repository showcase route from the app navigation and verify that the page renders profile metrics, recent activity context, featured repositories, and a repository collection from validated data without relying on search or filter interactions. + +### Tests for User Story 1 + +- [ ] T014 [P] [US1] Add route and first-render integration coverage for hero metrics, recent activity context, and featured spotlight rendering in `tests/integration/repositories/RepositoriesPage.test.tsx` + +### Implementation for User Story 1 + +- [ ] T015 [US1] Register the lazy-loaded repository route in `src/App.tsx` +- [ ] T016 [US1] Add the repository showcase entry to the Apps navigation and generated sitemap route list in `src/components/Header.tsx` and `src/utils/generateSitemap.ts` +- [ ] T017 [US1] Implement the repository page shell, hero metrics, recent activity summary, source-status messaging, retry-capable error state, and featured spotlight section in `src/components/Repositories.tsx` +- [ ] T018 [US1] Connect the repository page to `RepositoryService` and render the base repository collection in `src/components/Repositories.tsx` +- [ ] T019 [US1] Add page-level SEO copy and accessible section structure in `src/components/Repositories.tsx` + +**Checkpoint**: User Story 1 is independently functional and demoable as the MVP. + +--- + +## Phase 4: User Story 2 - Narrow to Relevant Repositories (Priority: P2) + +**Goal**: Let visitors search, filter, sort, and refine the repository collection to find relevant work quickly. + +**Independent Test**: Enter a search term, apply at least one filter or sort option, and verify that the visible repository results update correctly and recover cleanly from zero-result combinations. + +### Tests for User Story 2 + +- [ ] T020 [P] [US2] Add integration coverage for search, filter, sort, and zero-state behavior in `tests/integration/repositories/RepositoriesPage.test.tsx` + +### Implementation for User Story 2 + +- [ ] T021 [P] [US2] Create repository discovery helpers for filtering, sorting, and derived filter catalogs in `src/utils/repositoryFilters.ts` +- [ ] T022 [US2] Add searchable and sortable repository view state to `src/components/Repositories.tsx` +- [ ] T023 [US2] Implement filter controls, result counts, and zero-match recovery messaging in `src/components/Repositories.tsx` +- [ ] T024 [US2] Add responsive list management for larger result sets, including paging or grouped presentation, in `src/components/Repositories.tsx` + +**Checkpoint**: User Stories 1 and 2 both work independently, with discovery controls usable on phone and desktop layouts. + +--- + +## Phase 5: User Story 3 - Decide What to Open Next (Priority: P3) + +**Goal**: Help visitors understand repository value quickly and choose the right outbound GitHub destination. + +**Independent Test**: Compare multiple repositories on the page and confirm that each entry exposes enough context, status, and outbound actions for a user to decide what to open next without leaving the site blindly. + +### Tests for User Story 3 + +- [ ] T025 [P] [US3] Add integration coverage for repository CTA links, badges, and featured/fallback distinction in `tests/integration/repositories/RepositoriesPage.test.tsx` + +### Implementation for User Story 3 + +- [ ] T026 [US3] Enrich repository cards with summary text, activity badges, and status tags in `src/components/Repositories.tsx` +- [ ] T027 [US3] Add outbound GitHub and live-site call-to-action handling with accessible labels in `src/components/Repositories.tsx` + +**Checkpoint**: All user stories are independently functional, and repository entries provide clear decision support before outbound navigation. + +--- + +## Phase 6: Polish & Cross-Cutting Concerns + +**Purpose**: Finish theme fit, resilience, and full verification across the feature. + +- [ ] T029 [P] Refine Bootstrap styling, theme compatibility, and responsive polish for the repository showcase in `src/components/Repositories.tsx` and `src/css/styles.css` +- [ ] T030 [P] Add any missing accessibility, error-state, and retry-affordance assertions to `tests/integration/repositories/RepositoriesPage.test.tsx` +- [ ] T031 Run full quality verification with `npm run lint`, `npm run type-check`, `npm run test:coverage`, and `npm run build` +- [ ] T032 Run the quickstart validation scenarios from `.documentation/specs/001-github-repo-showcase/quickstart.md` and update feature docs if behavior drift is discovered + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Phase 1: Setup** has no dependencies and can start immediately. +- **Phase 2: Foundational** depends on setup and blocks all user story work. +- **Phase 3: User Story 1** depends on foundational completion and defines the MVP. +- **Phase 4: User Story 2** depends on foundational completion and builds on the repository page surface from User Story 1. +- **Phase 5: User Story 3** depends on foundational completion and can overlap with later User Story 2 work once the page shell exists. +- **Phase 6: Polish** depends on the desired user stories being complete. + +### User Story Dependencies + +- **US1**: Starts after foundational work and has no dependency on other stories. +- **US2**: Starts after foundational work but benefits from the route and page shell delivered in US1. +- **US3**: Starts after foundational work but benefits from the card and spotlight structure delivered in US1. + +### Within Each User Story + +- Write or update the story tests before finalizing the implementation. +- Route and navigation changes should land before user-facing page validation. +- Shared data logic belongs in the foundational phase or service layer, not duplicated in UI tasks. +- Curated-first featured selection is part of the foundational service behavior and must land before US1 is declared MVP-complete. + +### Parallel Opportunities + +- T002, T003, and T004 can run in parallel after T001 begins the feature scaffolding. +- T006, T008, T009, and T010 can run in parallel after the model and service shapes are known. +- T011, T012, and T013 can run in parallel once the foundational implementation stabilizes. +- T021 can run in parallel with early US3 card-detail work after the base page exists. +- T029 and T030 can run in parallel during polish. + +--- + +## Parallel Example: User Story 1 + +```text +Task: "T014 [US1] Add route and first-render integration coverage in tests/integration/repositories/RepositoriesPage.test.tsx" +Task: "T016 [US1] Add the repository showcase entry to the Apps navigation in src/components/Header.tsx" + +Task: "T017 [US1] Implement the repository page shell, hero metrics, source-status messaging, and featured spotlight section in src/components/Repositories.tsx" +Task: "T015 [US1] Register the lazy-loaded repository route in src/App.tsx" +``` + +## Parallel Example: User Story 2 + +```text +Task: "T020 [US2] Add integration coverage for search, filter, sort, and zero-state behavior in tests/integration/repositories/RepositoriesPage.test.tsx" +Task: "T021 [US2] Create repository discovery helpers for filtering, sorting, and derived filter catalogs in src/utils/repositoryFilters.ts" +``` + +## Parallel Example: User Story 3 + +```text +Task: "T025 [US3] Add integration coverage for repository CTA links, badges, and featured/fallback distinction in tests/integration/repositories/RepositoriesPage.test.tsx" +Task: "T026 [US3] Enrich repository cards with summary text, activity badges, and status tags in src/components/Repositories.tsx" +``` + +--- + +## Implementation Strategy + +### MVP First + +1. Complete Phase 1: Setup. +2. Complete Phase 2: Foundational. +3. Complete Phase 3: User Story 1. +4. Stop and validate the repository route as the MVP before expanding discovery and decision-support behavior. + +### Incremental Delivery + +1. Ship the validated data pipeline and base repository showcase route. +2. Add discovery controls for narrowing the collection. +3. Add richer repository decision support, CTA behavior, and featured fallback refinement. +4. Finish with polish and full verification. + +### Gate Notes + +- The feature metadata requires `checklist`, `analyze`, and `critic` gates. +- The requirements checklist exists and is complete. +- No existing `analyze.md`, `critic.md`, or other gate findings were present when tasks were generated. + +--- + +## Notes + +- All tasks follow the required checklist format. +- Exact file paths are included for every task. +- Suggested MVP scope: complete through T019 (User Story 1). +- Total tasks: 31. +- Task count by story: US1 = 6, US2 = 5, US3 = 3. \ No newline at end of file diff --git a/.github/agents/copilot-instructions.md b/.github/agents/copilot-instructions.md index dc93a24..9a4cf1e 100644 --- a/.github/agents/copilot-instructions.md +++ b/.github/agents/copilot-instructions.md @@ -5,6 +5,8 @@ Auto-generated from all feature plans. Last updated: 2026-03-01 ## Active Technologies - TypeScript 5.9, React 19, Vite 7 + React Router 7, Bootstrap 5.3, React-Bootstrap 2.10, Sass 1.99, Zod 4, Vitest 4, Testing Library, Bootswatch 5.3 package assets (001-robust-theme-switcher) - Browser `localStorage` for theme preference, static JSON/catalog files for supported theme definitions, static CSS assets for curated themes (001-robust-theme-switcher) +- TypeScript 5.9.x, React 19, Node.js-based Vite toolchain + React Router, React Bootstrap, Bootstrap 5, React Bootstrap Icons, Zod, Vitest, Testing Library (001-github-repo-showcase) +- Browser localStorage cache for fetched dataset metadata and payload; embedded JSON fallback in `src/data/` (001-github-repo-showcase) - TypeScript 5.9.3, React 19.2.5, Node.js (ESNext module system) + Vite 7.3.2 (build tool), React Router DOM 7.14.1, Bootstrap 5.3.8, Axios 1.15.0 (001-constitution-compliance) @@ -25,6 +27,7 @@ npm test; npm run lint TypeScript 5.9.3, React 19.2.5, Node.js (ESNext module system): Follow standard conventions ## Recent Changes +- 001-github-repo-showcase: Added TypeScript 5.9.x, React 19, Node.js-based Vite toolchain + React Router, React Bootstrap, Bootstrap 5, React Bootstrap Icons, Zod, Vitest, Testing Library - 001-robust-theme-switcher: Added TypeScript 5.9, React 19, Vite 7 + React Router 7, Bootstrap 5.3, React-Bootstrap 2.10, Sass 1.99, Zod 4, Vitest 4, Testing Library, Bootswatch 5.3 package assets - 001-constitution-compliance: Added TypeScript 5.9.3, React 19.2.5, Node.js (ESNext module system) + Vite 7.3.2 (build tool), React Router DOM 7.14.1, Bootstrap 5.3.8, Axios 1.15.0