## Summary - add the localized evaluation-readiness route pair at `/evaluierung` and `/en/evaluation` with a shared page component - wire homepage, platform, trust, review-pack, use-case, footer, and locale-switcher discovery paths into the new evaluation surface - add smoke coverage plus full Spec Kit artifacts for the evaluation, procurement, and rollout readiness feature ## Validation - `corepack pnpm --filter @tenantatlas/website build` - `WEBSITE_PORT=4322 corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts` - `WEBSITE_PORT=4323 corepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #408
19 KiB
Implementation Plan: Evaluation, Procurement & Rollout Readiness Website Surface
Branch: 409-evaluation-procurement-rollout | Date: 2026-05-30 | Spec: spec.md
Input: Feature specification from /specs/409-evaluation-procurement-rollout/spec.md
Summary
Deliver one localized public evaluation-readiness route in apps/website that explains demo flow, pilot scope, Microsoft 365 access readiness, security/privacy review, stakeholder involvement, and controlled rollout expectations, then expose it through existing homepage, platform, trust, use-case, review-story, and footer discovery surfaces without changing apps/platform or introducing fake procurement, trial, or compliance claims.
The implementation stays inside the Astro website, reuses the current siteCopy content model plus locale-aware routing, and validates the new public route through the existing Playwright smoke suite, metadata inventory, and static claim scans.
Technical Context
Language/Version: TypeScript 6.0.3 and Astro 6.3.3 content/runtime files
Primary Dependencies: Astro, Playwright, Tailwind CSS v4 (@tailwindcss/vite), Starlight docs stack
Storage: N/A (static public website content only)
Testing: Playwright smoke tests in apps/website/tests/smoke plus astro check inside the website build script
Validation Lanes: browser, confidence
Target Platform: Static website build and browser-rendered public routes
Project Type: Web application (Astro static site)
Performance Goals: Maintain readable desktop/mobile public routes, valid metadata, no horizontal overflow, and no broken CTA or discovery links
Constraints: Preserve root workspace contracts (package.json scripts, WEBSITE_PORT, apps/*), keep apps/platform untouched, use real CTA targets only, and avoid unsupported legal, provider, automation, or self-service claims
Scale/Scope: One new German root route, one new English root route, one shared page component, centralized copy additions, lightweight discovery updates across existing public surfaces, and smoke-test inventory updates
UI / Surface Guardrail Plan
- Guardrail scope: no operator-facing surface change
- Native vs custom classification summary: N/A
- Shared-family relevance: public website copy, metadata, navigation/footer links, homepage teasers, CTA targets, and smoke route inventory only
- State layers in scope: shell and page
- Audience modes in scope: customer/read-only
- Decision/diagnostic/raw hierarchy plan: decision-first public buyer copy only; no operator diagnostics or raw evidence surface is introduced
- Raw/support gating plan: N/A
- One-primary-action / duplicate-truth control: each evaluation surface keeps one primary conversion target to
/contact; supporting CTA surfaces point only to real trust, platform, or adjacent buyer-story routes to avoid CTA sprawl - Handling modes by drift class or surface: report-only
- Repository-signal treatment: review-mandatory for public claim language, route discoverability, and CTA integrity
- Special surface test profiles: N/A
- Required tests or manual smoke: manual-smoke and browser smoke
- Exception path and spread control: none
- Active feature PR close-out entry: Smoke Coverage
Shared Pattern & System Fit
- Cross-cutting feature marker: yes
- Systems touched:
siteCopylocale dictionaries, locale helpers, homepage composition, platform page composition, trust-page handoff copy, use-case page crosslinks, review-pack page crosslinks, footer links, and public route smoke inventory - Shared abstractions reused:
apps/website/src/data_files/site-copy.ts,apps/website/src/i18n.ts,MainLayout, existing page components inapps/website/src/components/pages, andapps/website/tests/smoke/smoke-helpers.ts - New abstraction introduced? why?: none beyond one bounded
EvaluationPage.astrocomponent to avoid duplicating German and English markup - Why the existing abstraction was sufficient or insufficient: the existing Astro copy-first structure already centralizes public text, locale-aware links, metadata, and smoke coverage; this feature extends those patterns without a new content system or design framework
- Bounded deviation / spread control: none
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no
- Central contract reused: N/A
- Delegated UX behaviors: N/A
- Surface-owned behavior kept local: none
- Queued DB-notification policy: N/A
- Terminal notification path: N/A
- Exception path: none
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes
- Provider-owned seams: Microsoft 365 access-readiness wording, provider-permission discussion, and consent/admin-role public framing
- Platform-core seams: evaluation, pilot scope, security review, trust handoff, stakeholder readiness, success criteria, and controlled rollout language
- Neutral platform terms / contracts preserved: evaluation, pilot, trust documents, security review, provider permissions, stakeholder readiness, success criteria, and rollout readiness
- Retained provider-specific semantics and why: Microsoft 365, consent, and admin-role language remain explicit because they are current-release public truth and keep the buyer journey concrete
- Bounded extraction or follow-up path: document-in-feature only; any future permission-detail matrix or procurement runtime remains a later website or platform concern
Constitution Check
GATE status before Phase 0 research: Pass for website-only scope.
- Inventory-first: N/A (no inventory/runtime change)
- Read/write separation: Pass (no write behavior)
- Graph contract path: N/A (no Graph/API runtime)
- Deterministic capabilities: N/A
- RBAC-UX and tenant/workspace isolation: N/A (public unauthenticated pages)
- Run observability / OperationRun UX: N/A
- TEST-GOV-001: Pass (browser lane explicit, narrow smoke coverage, no fixture/helper cost expansion planned)
- PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001: Pass (no new persistence, abstractions, enums, or semantic frameworks)
- XCUT-001: Pass (reuse existing site copy, locale helper, CTA, footer, and smoke helper patterns)
- PROV-001: Pass (bounded provider wording, no platform-core runtime coupling)
- DECIDE-AUD-001: N/A for operator/status surfaces; public marketing hierarchy stays copy-only
Post-design re-check after Phase 1: Pass. The research, data model, route contract, and quickstart remain static public-site artifacts only, introduce no runtime truth, and keep apps/platform out of scope.
Test Governance Check
- Test purpose / classification by changed surface: Browser
- Affected validation lanes: browser, confidence
- Why this lane mix is the narrowest sufficient proof: changes are public-route, metadata, CTA, and claim-language concerns best proven by the existing route smoke suite plus build-time Astro checks
- Narrowest proving command(s):
corepack pnpm --filter @tenantatlas/website buildcorepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.tscorepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts
- Fixture / helper / factory / seed / context cost risks: none
- Expensive defaults or shared helper growth introduced?: no
- Heavy-family additions, promotions, or visibility changes: none
- Surface-class relief / special coverage rule: public website browser smoke only
- Closing validation and reviewer handoff: reviewers verify the new route renders in both locales, exposed discovery links are real, no banned claims appear, and changed files stay within
apps/websiteplus feature-spec artifacts - Budget / baseline / trend follow-up: none
- Review-stop questions: lane fit, hidden helper cost, overbroad browser assertions, claim-boundary completeness
- Escalation path: document-in-feature
- Active feature PR close-out entry: Smoke Coverage
- Why no dedicated follow-up spec is needed: this is bounded copy/routing work inside existing public-site structures; procurement runtime, legal document delivery, or trial automation remain separate product slices
Project Structure
Documentation (this feature)
specs/409-evaluation-procurement-rollout/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ └── evaluation-readiness-routes.openapi.yaml
└── spec.md
Source Code (repository root)
apps/website/
├── src/
│ ├── pages/
│ │ ├── evaluierung.astro
│ │ ├── en/
│ │ │ └── evaluation.astro
│ │ ├── platform.astro
│ │ ├── trust.astro
│ │ ├── use-cases/
│ │ │ ├── msp.astro
│ │ │ └── mittelstand.astro
│ │ └── platform/
│ │ └── review-packs.astro
│ ├── components/
│ │ └── pages/
│ │ ├── EvaluationPage.astro
│ │ ├── HomePage.astro
│ │ ├── PlatformPage.astro
│ │ ├── ReviewPacksPage.astro
│ │ └── TrustPage.astro
│ ├── data_files/
│ │ └── site-copy.ts
│ └── i18n.ts
└── tests/smoke/
├── public-routes.spec.ts
├── interaction.spec.ts
└── smoke-helpers.ts
Structure Decision: Web app/Astro structure under apps/website; route files stay thin and locale-aware, while one shared EvaluationPage.astro is the preferred implementation shape for the section-heavy page to avoid German/English markup duplication.
Route Family Decision
Selected route family: root-level buyer route
Chosen routes:
/evaluierung/en/evaluation
Reasoning:
- The website already uses root-level public buyer and commercial routes such as
/contact,/pricing, and/trustwith/en/*counterparts. /platform/review-packsis the existing nested product-story exception, but the evaluation journey is broader than one product feature and belongs to top-level buyer navigation.- The default locale is German, so
/evaluierungfits the site’s German-first public surface while/en/evaluationkeeps the English path explicit. - The route cleanly separates evaluation readiness from the product-detail path under
/platform.
Rejected alternatives:
/platform/evaluation: too feature-nested for a buyer-readiness journey that spans demo, pilot, trust, and procurement questions./procurement: too narrow relative to the broader evaluation and rollout scope./startor/demo-pilot: less explicit for SEO and weaker alignment with the existing trust/pricing/contact family.
CTA Target Decision
Selected real CTA targets:
- Primary conversion:
/contactand/en/contact - Trust handoff:
/trustand/en/trust - Product context:
/platformand/en/platform - Adjacent story context:
/platform/review-packs,/use-cases/msp, and/use-cases/mittelstandplus locale equivalents when those links are surfaced
Reasoning:
- Existing public CTA patterns already use
/contactas the real demo/contact destination. - The current site does not use
mailto:as the primary sales CTA pattern. - Trust follow-up already has a real route and is safer than inventing a security-pack or AVV download target.
Security-Unterlagen anfragenshould map to the existing contact path unless implementation discovers a different real destination.
Discovery Strategy Decision
Selected discovery surfaces:
- Homepage teaser
- Compact platform-page teaser
- Trust-page crosslink
- Review-pack page crosslink
- MSP use-case crosslink
- Mittelstand / Enterprise IT use-case crosslink
- Footer link
Decision: do not add a main-navigation item by default.
Reasoning:
- The current main nav is already dense with primary category links.
- Contextual discovery on homepage, platform, use-case, and review-pack surfaces is stronger because it carries the buyer story naturally.
- Footer exposure keeps the route globally reachable without forcing a top-level IA refactor.
Research-Driven Implementation Notes
- Localized copy should stay in
apps/website/src/data_files/site-copy.tsunder one dedicatedevaluationsection per locale. - The docs checklist route (
/guides/first-project-checklist/) already speaks to evaluation, but it is documentation, not the right public conversion surface for this feature. - Public smoke coverage already includes route metadata and forbidden public-claim checks, so the new route should join the existing inventory instead of adding a second test style.
Static Claim Scan Commands
grep -RIn -e 'href="#"' -e 'lorem ipsum' -e 'procurement readiness website surface' -e 'productization gap' -e 'repo-real foundation' -e 'workspace-first route context' -e 'capability registry' -e 'provider-neutral artifact taxonomy' -e 'instant trial' -e 'self-service onboarding available' -e 'sofort kostenlos starten' -e 'DSGVO-konform' -e 'ISO-zertifiziert' -e 'NIS2-konform' -e 'garantiert auditbereit' -e 'automatic remediation' -e 'automatic restore' -e 'one-click restore' -e 'Google supported' -e 'AWS supported' -e 'no customer data stored' -e 'in Deutschland gehostet' apps/website/src apps/website/public 2>/dev/null || truegrep -RIn -e 'href="#"' -e 'lorem ipsum' -e 'procurement readiness website surface' -e 'productization gap' -e 'repo-real foundation' -e 'workspace-first route context' -e 'capability registry' -e 'provider-neutral artifact taxonomy' -e 'instant trial' -e 'self-service onboarding available' -e 'sofort kostenlos starten' -e 'DSGVO-konform' -e 'ISO-zertifiziert' -e 'NIS2-konform' -e 'garantiert auditbereit' -e 'automatic remediation' -e 'automatic restore' -e 'one-click restore' -e 'Google supported' -e 'AWS supported' -e 'no customer data stored' -e 'in Deutschland gehostet' apps/website/dist 2>/dev/null || true
Planned Validation Results Capture
Implementation must record:
- exact website commands run from current
package.json/apps/website/package.json - route-metadata additions in public smoke coverage
- static claim scan outcomes
- timed comprehension-review notes for buyer (60 seconds), security/procurement (90 seconds), and technical-owner (60 seconds) personas mapped to SC-001 through SC-003
- browser smoke pass/fail notes for desktop and mobile readability
- which optional discovery surfaces were shipped or intentionally omitted
- confirmation that
apps/platform/**remained untouched
Validation Results (Implementation)
Commands run (from apps/website/package.json)
corepack pnpm --filter @tenantatlas/website format:check— Prettier reported pre-existing style warnings outside this feature; the feature-owned files were formatted withprettier --writeand are clean.corepack pnpm --filter @tenantatlas/website build— Pass (astro check+astro build+process-html.mjs); both/evaluierungand/en/evaluationare generated, plus all discovery-surface pages.corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts— Pass (362 passed).corepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts— Pass (82 passed, 6 project-scoped skips).
Static claim scan outcomes
- Plan scan command over
apps/website/srcandapps/website/public— no matches (clean). - Plan scan command over
apps/website/dist— no matches (clean). - During smoke runs the EN negations "automatic remediation" / "automatic restore" tripped the substring-based forbidden-claim assertions even though they were negated, so the copy was reworded to "No unattended remediation" and "Nothing is remediated or restored without your review and approval." No banned substrings remain in source or
dist.
Smoke coverage close-out
- New route metadata, content, discovery-link, click-through, viewport, reduced-motion, and no-JS assertions for
/evaluierungand/en/evaluationwere added to the existing public-website smoke family only (public-routes.spec.ts,interaction.spec.ts,smoke-helpers.ts). No new test style, heavy helper, or fixture layer was introduced.
Locale slug-alias fix
- DE
/evaluierungand EN/evaluationuse different slugs, which broke the sharedLanguagePickerandMeta.astrohreflang/x-default alternates (they naively prefixed/en). A centralizedlocalizeRoutePath(strippedPath, fromLocale, toLocale)helper with aslugAliasGroupsmap was added inapps/website/src/i18n.tsand adopted byLanguagePicker.astroandMeta.astroso cross-locale links resolve to real routes.
Timed comprehension review (SC-001 through SC-006)
Structural review against the rendered sections on desktop and mobile:
- SC-001 (buyer, 60s): Pass — hero + "evaluation path" numbered steps + example timeline convey the demo-to-pilot-to-decision sequence above the fold and in the first scroll.
- SC-002 (buyer, 60s): Pass — primary/final CTAs route to
/contactwith "request a demo / start a conversation" language; no instant self-service onboarding implied. - SC-003 (security/procurement, 90s): Pass — preparation cards, stakeholder cards, security/procurement checklist, and buyer FAQ identify who to involve and what to review without fake legal/compliance promises.
- SC-004 (technical owner, 60s): Pass — pilot scenarios, Microsoft 365 access principles, and non-requirement cards explain scope-dependent access and controlled rollout without an unverified permission matrix.
- SC-005 (discovery): Pass — homepage, platform, review-pack, trust, both use-case surfaces, and footer expose real links validated by the discovery-link and click-through smoke tests.
- SC-006 (readability): Pass — desktop/mobile readability, reduced-motion, and no-JS assertions pass for both routes.
Omitted discovery surfaces
- Main-navigation item intentionally omitted (per Discovery Strategy Decision above); all other planned surfaces shipped.
Scope confirmation
git diff --name-onlyshows changes confined toapps/website/**andspecs/409-evaluation-procurement-rollout/**(plus the standard auto-updated.github/agents/copilot-instructions.mdagent-context file).apps/platform/**remained untouched.
Quickstart validation
specs/409-evaluation-procurement-rollout/quickstart.mdsteps (build + both smoke suites + claim scans) were executed as above with passing results; no documentation drift identified.
Complexity Tracking
No constitutional violations and no bloat-triggering additions are planned for this feature.
Proportionality Review
N/A for this implementation plan. The feature introduces no new enum/status family, DTO/presenter/envelope layer, persisted entity/table/artifact, interface/contract/registry/resolver, taxonomy system, or cross-domain UI framework. The only new structure is one bounded public page component plus copy entries inside existing website patterns.