221 lines
17 KiB
Markdown
221 lines
17 KiB
Markdown
# Implementation Plan: Website Information Architecture / Core Pages
|
|
|
|
**Branch**: `215-website-core-pages` | **Date**: 2026-04-19 | **Spec**: `specs/215-website-core-pages/spec.md`
|
|
**Input**: Feature specification from `specs/215-website-core-pages/spec.md`
|
|
|
|
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.
|
|
|
|
## Summary
|
|
|
|
- Keep `apps/website` fully local to the website track and preserve `@tenantatlas/website`, `WEBSITE_PORT`, and the root `dev:website` / `build:website` workflows.
|
|
- Re-anchor the public-site IA in the existing Astro route and metadata layer (`src/lib/site.ts`, `src/types/site.ts`, `src/content/pages`, and published Astro pages) instead of introducing a CMS, router framework, or any `apps/platform` coupling.
|
|
- Canonicalize the initial public core around Home, Product, Trust, Changelog, Contact, Privacy, and Imprint; keep one primary conversion path; standardize optional content discoverability on `Resources`; leave the editorial `articles` collection unpublished; and keep Pricing/Docs/Solutions-hub style expansion deferred.
|
|
- Reconcile the current v0 topology with compatibility-safe changes by introducing `/trust`, `/changelog`, and `/imprint`, shrinking primary navigation to the Spec 215 core, and extending smoke coverage for the new IA contract.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: Astro 6.0.0 templates + TypeScript 5.9 strict
|
|
**Primary Dependencies**: Astro 6, Tailwind CSS v4 via `@tailwindcss/vite`, Astro content collections, local Astro layout/primitive/content helpers, Playwright smoke tests
|
|
**Storage**: Static filesystem pages, content modules, and Astro content collections under `apps/website/src` and `apps/website/public`; no database
|
|
**Testing**: Root build proof via `corepack pnpm build:website` plus Playwright smoke coverage in `apps/website/tests/smoke`
|
|
**Validation Lanes**: fast-feedback
|
|
**Target Platform**: Static public website for modern desktop and mobile browsers
|
|
**Project Type**: Web (standalone Astro app inside the monorepo)
|
|
**Performance Goals**: Preserve static HTML output for canonical public routes, keep browsing flows zero-hydration by default, and avoid introducing JS-heavy navigation or runtime platform coupling
|
|
**Constraints**: Preserve `@tenantatlas/website`, `WEBSITE_PORT`, and Astro static output mode; keep all IA changes local to `apps/website`; do not publish placeholder routes; keep one clear primary conversion path; keep Trust top-level visible; avoid premature promotion of `Resources`, later editorial surfaces, Docs, or Pricing
|
|
**Scale/Scope**: Current public site ships 9 routes, 3 future content collections (`articles` as unpublished editorial inventory, `changelog`, `resources`), one route-definition source in `src/lib/site.ts`, and a small Playwright smoke suite that must expand to cover the Spec 215 IA contract
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: no operator-facing surface change
|
|
- **Native vs custom classification summary**: N/A - public Astro website only
|
|
- **Shared-family relevance**: none
|
|
- **State layers in scope**: none
|
|
- **Handling modes by drift class or surface**: N/A
|
|
- **Repository-signal treatment**: report-only
|
|
- **Special surface test profiles**: N/A
|
|
- **Required tests or manual smoke**: manual-smoke plus browser smoke for public routes
|
|
- **Exception path and spread control**: none
|
|
- **Active feature PR close-out entry**: Smoke Coverage
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
- Inventory-first / Graph contract / deterministic capabilities / RBAC-UX / Filament surface rules: N/A for this feature because all work stays inside `apps/website` and introduces no `/admin`, `/admin/t/{tenant}/...`, or `/system` runtime behavior.
|
|
- Read/write separation: Pass. The feature changes public route structure, navigation, and content discoverability only; Contact remains a public conversion surface, not a website-side backend workflow.
|
|
- Workspace isolation: Pass. The website remains runtime-independent from `apps/platform`, and the plan preserves the explicit website working contract.
|
|
- Data minimization: Pass. The feature only reorganizes public pages, content sources, and navigation metadata; it introduces no tenant data, secrets, auth state, or operational records.
|
|
- Test governance (TEST-GOV-001): Pass. Validation stays in `fast-feedback` with build proof plus the local Playwright smoke suite, with no database, auth, provider, or heavy-suite defaults.
|
|
- Proportionality / no premature abstraction: Pass. The plan reuses the existing `site.ts`, `types/site.ts`, Astro page routes, and content collections instead of introducing a CMS, server route layer, or generic routing framework.
|
|
- Persisted truth / new state: Pass. No database schema, queued work, new domain state family, or persisted artifact is introduced.
|
|
- UI semantics / few layers: Pass. The added semantics stay limited to website-local route roles, navigation groups, publication rules, and journey flow rather than becoming a cross-app framework.
|
|
- Website working contract: Pass. The plan keeps all implementation local to `apps/website` and preserves `@tenantatlas/website`, `WEBSITE_PORT`, and root workflow compatibility.
|
|
|
|
Status: ✅ No constitution violations for this feature. The plan remains website-only, static-first, and scoped to the existing Astro website track.
|
|
|
|
## Test Governance Check
|
|
|
|
> **Fill for any runtime-changing or test-affecting feature. Docs-only or template-only work may state concise `N/A` or `none`.**
|
|
|
|
- **Test purpose / classification by changed surface**: Browser smoke coverage for required public routes, navigation/footer topology, compatibility routing, and optional-surface suppression plus static build proof
|
|
- **Affected validation lanes**: fast-feedback
|
|
- **Why this lane mix is the narrowest sufficient proof**: The feature changes the runtime route topology and public-shell behavior of a static Astro site. Build proof catches route and artifact generation regressions; focused Playwright smoke coverage is the smallest realistic browser-level proof for link reachability, canonical paths, and the absence of placeholder navigation without adding backend or heavy end-to-end cost.
|
|
- **Narrowest proving command(s)**: `corepack pnpm build:website` and `cd apps/website && corepack pnpm exec playwright test`
|
|
- **Fixture / helper / factory / seed / context cost risks**: none; public website pages require no database, auth, tenant, or provider setup
|
|
- **Expensive defaults or shared helper growth introduced?**: no; any smoke-helper changes remain local to `apps/website/tests/smoke`
|
|
- **Heavy-family additions, promotions, or visibility changes**: none
|
|
- **Surface-class relief / special coverage rule**: N/A
|
|
- **Closing validation and reviewer handoff**: Re-run the website build and smoke suite after route, shell, or navigation changes. Reviewers should verify that `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint` load; `/trust` and `/changelog` can still route visitors to `/contact` within the intended action flow; Trust is top-level visible; the brand links home; one primary CTA remains obvious; unpublished optional content hubs stay hidden; and any legacy route compatibility is explicit rather than silently duplicated.
|
|
- **Budget / baseline / trend follow-up**: none beyond small website smoke-suite growth
|
|
- **Review-stop questions**: Did any route rename break sitemap/canonical output? Did optional surfaces leak into primary nav without content? Did a compatibility path become permanent instead of transitional? Did any change introduce platform coupling or hidden runtime cost?
|
|
- **Escalation path**: document-in-feature
|
|
- **Active feature PR close-out entry**: Smoke Coverage
|
|
- **Why no dedicated follow-up spec is needed**: The change is bounded to a small public-route contract and website shell behavior. The later page-structure specs handle content/detail work, so route and navigation proof can remain inside this feature.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/215-website-core-pages/
|
|
├── plan.md
|
|
├── research.md
|
|
├── data-model.md
|
|
├── quickstart.md
|
|
├── contracts/
|
|
│ └── public-site-ia.openapi.yaml
|
|
└── tasks.md
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
|
|
```text
|
|
apps/website/
|
|
├── astro.config.mjs
|
|
├── package.json
|
|
├── playwright.config.ts
|
|
├── public/
|
|
├── src/
|
|
│ ├── components/
|
|
│ │ ├── layout/ # Navbar, Footer, PageShell
|
|
│ │ ├── primitives/ # Container, Section, Button, Card, Input, Textarea, Grid, Stack
|
|
│ │ ├── sections/ # PageHero, FeatureGrid, TrustGrid, CTASection, LogoStrip
|
|
│ │ └── content/ # CTA wrappers, callouts, text blocks
|
|
│ ├── content/
|
|
│ │ ├── changelog/ # Existing future collection for dated updates
|
|
│ │ ├── pages/ # Route-level content definitions
|
|
│ │ └── resources/ # Existing optional future collection
|
|
│ ├── content.config.ts
|
|
│ ├── layouts/
|
|
│ │ └── BaseLayout.astro
|
|
│ ├── lib/
|
|
│ │ ├── seo.ts
|
|
│ │ └── site.ts # Current route, shell, and navigation truth
|
|
│ ├── pages/
|
|
│ │ ├── index.astro
|
|
│ │ ├── product.astro
|
|
│ │ ├── contact.astro
|
|
│ │ ├── privacy.astro
|
|
│ │ ├── solutions.astro
|
|
│ │ ├── integrations.astro
|
|
│ │ ├── security-trust.astro
|
|
│ │ ├── legal.astro
|
|
│ │ ├── terms.astro
|
|
│ │ └── sitemap.xml.ts
|
|
│ ├── styles/
|
|
│ └── types/
|
|
└── tests/
|
|
└── smoke/
|
|
```
|
|
|
|
**Structure Decision**: Keep the existing website structure and implement the IA in the current Astro route stack. The core truth should live in `src/lib/site.ts`, `src/types/site.ts`, `src/content/pages`, and published page files. Add canonical route files for `/trust`, `/changelog`, and `/imprint`, and use compatibility-only routes only when a rename is necessary to avoid avoidable breakage.
|
|
|
|
## Complexity Tracking
|
|
|
|
None.
|
|
|
|
## Proportionality Review
|
|
|
|
- **Current operator problem**: The current website still reflects the broader v0 route inventory, with `Solutions` and `Integrations` acting as primary-nav peers, `Security & Trust` using a non-canonical path, and no `/changelog` or `/imprint` routes even though Spec 215 treats those as part of the small credible core.
|
|
- **Existing structure is insufficient because**: `src/lib/site.ts` and `src/types/site.ts` currently encode one flat route inventory but do not distinguish between required core surfaces, optional content surfaces, deferred surfaces, and compatibility paths. That makes it too easy for template-era routes to keep occupying top-level attention.
|
|
- **Narrowest correct implementation**: Reuse the existing route-definition layer and content collections to encode the new IA contract, publish only the required core routes, and tighten smoke coverage around route topology and navigation behavior. Do not introduce a CMS, API contract, or platform/shared routing abstraction.
|
|
- **Ownership cost created**: Ongoing maintenance of the explicit public IA contract, a small set of compatibility decisions for renamed routes, and lightweight smoke assertions that protect navigation and route truth.
|
|
- **Alternative intentionally rejected**: Keeping the current v0 topology and trying to solve the IA only through page copy was rejected because it leaves the route and navigation contract incoherent; adding a richer content/router system was rejected because the website does not need that extra ownership cost.
|
|
- **Release truth**: Current-release truth for `apps/website`
|
|
|
|
## Phase 0 — Outline & Research (complete)
|
|
|
|
- Output: `specs/215-website-core-pages/research.md`
|
|
- Key decisions captured:
|
|
- Keep the IA fully local to `apps/website` and preserve the website working contract.
|
|
- Use the existing `src/lib/site.ts` + `src/types/site.ts` route-definition layer as the canonical public IA source of truth.
|
|
- Canonicalize the required public core around `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint`, with compatibility handling only where renames are necessary.
|
|
- Gate optional `Resources` discoverability through the existing Astro content collections, and keep the editorial `articles` collection unpublished until a later spec activates it.
|
|
- Reclassify current `Solutions`, `Integrations`, `Legal`, and `Terms` surfaces as secondary supporting routes so primary navigation stays buyer-first and intentionally small.
|
|
- Validate with build proof plus route- and navigation-focused Playwright smoke coverage.
|
|
|
|
## Phase 1 — Design & Contracts (complete)
|
|
|
|
### Data model
|
|
|
|
- Output: `specs/215-website-core-pages/data-model.md`
|
|
- No database schema changes are required; the model is a website-local route, navigation, publication, and compatibility contract.
|
|
|
|
### Public IA contract
|
|
|
|
- Output: `specs/215-website-core-pages/contracts/public-site-ia.openapi.yaml`
|
|
- The contract captures required public HTML routes, navigation invariants, optional-surface gating, and compatibility-path expectations for the initial website IA.
|
|
|
|
### Quickstart
|
|
|
|
- Output: `specs/215-website-core-pages/quickstart.md`
|
|
- Quickstart covers the local development flow, implementation order, compatibility expectations, and required validation commands.
|
|
|
|
### Agent context update
|
|
|
|
- Completed via `.specify/scripts/bash/update-agent-context.sh copilot` so the Copilot context reflects the current planning artifacts.
|
|
|
|
### Constitution re-check (post-design)
|
|
|
|
- ✅ The design remains fully local to `apps/website` and preserves the website working contract.
|
|
- ✅ No database truth, backend form handling, queueing, auth, or platform-side runtime concern is introduced.
|
|
- ✅ The IA layer remains narrow: route roles, navigation groups, publication rules, and compatibility handling only.
|
|
- ✅ Validation remains cheap, representative, and website-specific.
|
|
|
|
## Phase 2 — Implementation Plan (next)
|
|
|
|
### Story 1 (P1): Canonical core-route contract
|
|
|
|
- Update `src/types/site.ts`, `src/lib/site.ts`, `src/content/pages`, and the published Astro route files so the canonical public core is `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint`.
|
|
- Add the missing `/changelog` and `/imprint` surfaces and replace `/security-trust` as the canonical trust path with `/trust`.
|
|
- Keep compatibility routes narrow and explicit; any legacy route retained during migration must stay out of primary navigation and must not become a second canonical truth.
|
|
- Tests / validation:
|
|
- Update smoke helpers and assertions to reflect the new canonical navigation labels and route set.
|
|
- Verify sitemap/canonical behavior and route reachability through build proof plus browser smoke tests.
|
|
|
|
### Story 2 (P1): Navigation and footer reduction to the Spec 215 core
|
|
|
|
- Shrink primary navigation to Product, Trust, Changelog, Contact, and optional `Resources` only when content is substantive.
|
|
- Move buyer-outcome explanation responsibility into Home and Product so `Solutions` is no longer required as a top-level peer; treat `Solutions` and `Integrations` as retained secondary supporting pages instead of core IA pillars.
|
|
- Rebuild footer groups around Product, Trust/Legal, Contact, and optional Content, with direct links to `/privacy`, `/imprint`, and the retained secondary `/terms` legal disclosure.
|
|
- Tests / validation:
|
|
- Assert brand-to-home behavior, Trust top-level visibility, `/trust -> /contact` reachability, one clear primary CTA, and the new footer grouping.
|
|
- Add negative assertions that placeholder or deferred routes do not appear in primary navigation.
|
|
|
|
### Story 3 (P2): Content-backed updates and optional-surface gating
|
|
|
|
- Use the existing `src/content/changelog` collection or equivalent dated entries to make `/changelog` a real progress surface rather than a placeholder.
|
|
- Keep `/resources` unpublished or unlinked until content exists, keep the editorial `articles` collection unpublished until a later blog/editorial spec, and keep Docs and Pricing out of primary navigation until later specs explicitly activate them.
|
|
- Rationalize current `/legal` and `/terms` behavior as retained secondary legal surfaces, and current `/solutions` and `/integrations` behavior as retained secondary supporting pages, without letting them inflate the initial IA.
|
|
- Tests / validation:
|
|
- Extend smoke coverage for `/changelog`, `/imprint`, and `/changelog -> /contact` reachability.
|
|
- Verify unpublished optional surfaces stay hidden, the editorial `articles` collection remains undiscoverable, and any compatibility or retained secondary paths stay out of primary navigation.
|
|
|
|
## Validation Evidence
|
|
|
|
- **Lane**: `fast-feedback`
|
|
- **Build proof**: `corepack pnpm build:website` completed successfully on 2026-04-19 after the final IA/content changes.
|
|
- **Browser smoke proof**: `cd apps/website && corepack pnpm exec playwright test` completed successfully on 2026-04-19 with 13 passing smoke tests.
|
|
- **Reviewer note**: If an Astro dev server is already running on `WEBSITE_PORT`, stop it before rerunning Playwright so the suite does not reuse stale content state.
|