17 KiB
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/websitefully local to the website track and preserve@tenantatlas/website,WEBSITE_PORT, and the rootdev:website/build:websiteworkflows. - 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 anyapps/platformcoupling. - 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 editorialarticlescollection 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/websiteand introduces no/admin,/admin/t/{tenant}/..., or/systemruntime 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-feedbackwith 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/websiteand 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/Aornone.
- 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:websiteandcd 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/imprintload;/trustand/changelogcan still route visitors to/contactwithin 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)
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)
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
SolutionsandIntegrationsacting as primary-nav peers,Security & Trustusing a non-canonical path, and no/changelogor/imprintroutes even though Spec 215 treats those as part of the small credible core. - Existing structure is insufficient because:
src/lib/site.tsandsrc/types/site.tscurrently 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/websiteand preserve the website working contract. - Use the existing
src/lib/site.ts+src/types/site.tsroute-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
Resourcesdiscoverability through the existing Astro content collections, and keep the editorialarticlescollection unpublished until a later spec activates it. - Reclassify current
Solutions,Integrations,Legal, andTermssurfaces 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.
- Keep the IA fully local to
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 copilotso the Copilot context reflects the current planning artifacts.
Constitution re-check (post-design)
- ✅ The design remains fully local to
apps/websiteand 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
/changelogand/imprintsurfaces and replace/security-trustas 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
Resourcesonly when content is substantive. - Move buyer-outcome explanation responsibility into Home and Product so
Solutionsis no longer required as a top-level peer; treatSolutionsandIntegrationsas 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/termslegal disclosure. - Tests / validation:
- Assert brand-to-home behavior, Trust top-level visibility,
/trust -> /contactreachability, one clear primary CTA, and the new footer grouping. - Add negative assertions that placeholder or deferred routes do not appear in primary navigation.
- Assert brand-to-home behavior, Trust top-level visibility,
Story 3 (P2): Content-backed updates and optional-surface gating
- Use the existing
src/content/changelogcollection or equivalent dated entries to make/changeloga real progress surface rather than a placeholder. - Keep
/resourcesunpublished or unlinked until content exists, keep the editorialarticlescollection unpublished until a later blog/editorial spec, and keep Docs and Pricing out of primary navigation until later specs explicitly activate them. - Rationalize current
/legaland/termsbehavior as retained secondary legal surfaces, and current/solutionsand/integrationsbehavior as retained secondary supporting pages, without letting them inflate the initial IA. - Tests / validation:
- Extend smoke coverage for
/changelog,/imprint, and/changelog -> /contactreachability. - Verify unpublished optional surfaces stay hidden, the editorial
articlescollection remains undiscoverable, and any compatibility or retained secondary paths stay out of primary navigation.
- Extend smoke coverage for
Validation Evidence
- Lane:
fast-feedback - Build proof:
corepack pnpm build:websitecompleted successfully on 2026-04-19 after the final IA/content changes. - Browser smoke proof:
cd apps/website && corepack pnpm exec playwright testcompleted 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.