feat(website): add evaluation procurement rollout surface
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 52s
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 52s
This commit is contained in:
parent
acdea41d92
commit
8645938a5c
2
.github/agents/copilot-instructions.md
vendored
2
.github/agents/copilot-instructions.md
vendored
@ -304,9 +304,9 @@ ## Code Style
|
||||
PHP 8.4.15: Follow standard conventions
|
||||
|
||||
## Recent Changes
|
||||
- 409-evaluation-procurement-rollout: Added TypeScript 6.0.3 and Astro 6.3.3 content/runtime files + Astro, Playwright, Tailwind CSS v4 (`@tailwindcss/vite`), Starlight docs stack
|
||||
- 408-review-evidence-decision: Added TypeScript 6.0.3 and Astro 6.3.3 content/runtime files + Astro, Playwright, Tailwind CSS v4 (`@tailwindcss/vite`), Starlight docs stack
|
||||
- 404-public-content-messaging: Added TypeScript 6.0.3, Astro 6.3.3, Node.js >=20.0.0, pnpm 10.33.0 + Astro, `@astrojs/starlight`, `@astrojs/sitemap`, `@astrojs/mdx`, Tailwind CSS v4, `@tailwindcss/vite`, Preline 4, Lenis, GSAP, Sharp, Playwrigh
|
||||
- 253-remove-findings-backfill-runtime-surfaces: Added PHP 8.4 (Laravel 12) + Laravel 12 + Filament v5 + Livewire v4 + Pest; existing `UiEnforcement`, `OperationUxPresenter`, `OperationRunService`, `OperationCatalog`, `SystemOperationRunLinks`, `OperationRunLinks`, `AuditRecorder`, `WorkspaceAuditLogger`, and `PlatformCapabilities`
|
||||
<!-- MANUAL ADDITIONS START -->
|
||||
|
||||
### Pre-production compatibility check
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
isLocale,
|
||||
localeOg,
|
||||
localizedPath,
|
||||
localizeRoutePath,
|
||||
stripLocalePrefix,
|
||||
type Locale,
|
||||
} from '@/i18n';
|
||||
@ -96,7 +97,7 @@ const appleTouchIcon = await getImage({
|
||||
{
|
||||
alternateLocales.map(lang => {
|
||||
const href = new URL(
|
||||
localizedPath(cleanPath, lang),
|
||||
localizeRoutePath(cleanPath, locale, lang),
|
||||
Astro.site || Astro.url.origin
|
||||
).href;
|
||||
return <link rel="alternate" hreflang={lang} href={href} />;
|
||||
@ -105,8 +106,10 @@ const appleTouchIcon = await getImage({
|
||||
<link
|
||||
rel="alternate"
|
||||
hreflang="x-default"
|
||||
href={new URL(localizedPath(cleanPath, 'de'), Astro.site || Astro.url.origin)
|
||||
.href}
|
||||
href={new URL(
|
||||
localizeRoutePath(cleanPath, locale, 'de'),
|
||||
Astro.site || Astro.url.origin
|
||||
).href}
|
||||
/>
|
||||
|
||||
{/* Facebook Meta Tags */}
|
||||
|
||||
530
apps/website/src/components/pages/EvaluationPage.astro
Normal file
530
apps/website/src/components/pages/EvaluationPage.astro
Normal file
@ -0,0 +1,530 @@
|
||||
---
|
||||
import MainLayout from '@/layouts/MainLayout.astro';
|
||||
import HeroSection from '@components/sections/landing/HeroSection.astro';
|
||||
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro';
|
||||
import SecondaryCTA from '@components/ui/buttons/SecondaryCTA.astro';
|
||||
import Icon from '@components/ui/icons/Icon.astro';
|
||||
import AccordionItem from '@components/ui/blocks/AccordionItem.astro';
|
||||
import heroImage from '@images/tenantial-rollout-plan.avif';
|
||||
import { SITE } from '@data/constants';
|
||||
import { siteCopy } from '@data/site-copy';
|
||||
import {
|
||||
localeHtmlLang,
|
||||
localizeHref,
|
||||
localizedPath,
|
||||
type Locale,
|
||||
} from '@/i18n';
|
||||
|
||||
const { locale } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
locale: Locale;
|
||||
}
|
||||
|
||||
const copy = siteCopy[locale].evaluation;
|
||||
const siteDescription = siteCopy[locale].site.description;
|
||||
const canonicalPath = localizedPath(copy.routePath, locale);
|
||||
---
|
||||
|
||||
<MainLayout
|
||||
lang={locale}
|
||||
title={copy.pageTitle}
|
||||
customDescription={copy.metaDescription}
|
||||
customOgTitle={copy.pageTitle}
|
||||
structuredData={{
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebPage',
|
||||
'@id': `${SITE.url}${canonicalPath}`,
|
||||
url: `${SITE.url}${canonicalPath}`,
|
||||
name: copy.pageTitle,
|
||||
description: copy.metaDescription,
|
||||
isPartOf: {
|
||||
'@type': 'WebSite',
|
||||
url: SITE.url,
|
||||
name: SITE.title,
|
||||
description: siteDescription,
|
||||
},
|
||||
inLanguage: localeHtmlLang[locale],
|
||||
}}
|
||||
>
|
||||
<HeroSection
|
||||
title={copy.heroTitle}
|
||||
subTitle={copy.heroSubtitle}
|
||||
primaryBtn={copy.primaryCta.label}
|
||||
primaryBtnURL={localizeHref(copy.primaryCta.href, locale)}
|
||||
secondaryBtn={copy.secondaryCta.label}
|
||||
secondaryBtnURL={localizeHref(copy.secondaryCta.href, locale)}
|
||||
withReview={false}
|
||||
supportingLine={copy.supportingLine}
|
||||
src={heroImage}
|
||||
alt={copy.heroTitle}
|
||||
/>
|
||||
|
||||
{/* Evaluation path */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-neutral-100/80 p-6 md:p-10 dark:border-neutral-700 dark:bg-white/[0.05]"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionRoute" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.pathTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.pathIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ol class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.evaluationSteps.map((step: any, index: number) => (
|
||||
<li class="rounded-3xl border border-neutral-300 bg-white p-6 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<span class="inline-flex rounded-full bg-yellow-400 px-3 py-1 text-xs font-semibold tracking-[0.18em] text-neutral-900 uppercase">
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
<h3 class="mt-4 text-lg font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{step.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-pretty text-neutral-700 dark:text-neutral-300">
|
||||
{step.content}
|
||||
</p>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Preparation */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-neutral-100/80 p-6 md:p-10 dark:border-neutral-700 dark:bg-white/[0.05]"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionPrep" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.preparationTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.preparationIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.preparationCards.map((card: any) => (
|
||||
<article class="rounded-2xl bg-white p-5 shadow-xs dark:bg-neutral-900/70">
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{card.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Pilot scenarios */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-neutral-100/80 p-6 md:p-10 dark:border-neutral-700 dark:bg-white/[0.05]"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionPilot" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.pilotTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.pilotIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.pilotScenarios.map((scenario: any) => (
|
||||
<article class="rounded-3xl border border-neutral-300 bg-white p-6 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{scenario.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-pretty text-neutral-700 dark:text-neutral-300">
|
||||
{scenario.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Stakeholders */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionStakeholders" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.stakeholderTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.stakeholderIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.stakeholderCards.map((card: any) => (
|
||||
<article class="rounded-2xl border border-neutral-300 bg-white p-5 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{card.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Security & procurement */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/20 text-yellow-600 ring-1 ring-yellow-400/40 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionSecurity" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.securityTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.securityIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.securityChecklist.map((item: any) => (
|
||||
<article class="rounded-2xl bg-white p-5 shadow-xs dark:bg-neutral-900/70">
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{item.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mt-8 border-t border-neutral-300 pt-6 dark:border-neutral-700"
|
||||
>
|
||||
<h3
|
||||
class="text-lg font-semibold text-neutral-900 dark:text-neutral-100"
|
||||
>
|
||||
{copy.securityHandoffTitle}
|
||||
</h3>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 dark:text-neutral-300"
|
||||
>
|
||||
{copy.securityHandoffText}
|
||||
</p>
|
||||
<div class="mt-5">
|
||||
<PrimaryCTA
|
||||
title={copy.securityHandoffCta.label}
|
||||
url={localizeHref(copy.securityHandoffCta.href, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Microsoft 365 access principles */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionAccess" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.accessTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.accessIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-2">
|
||||
{
|
||||
copy.accessPrinciples.map((principle: any) => (
|
||||
<article class="rounded-3xl border border-neutral-300 bg-white p-6 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{principle.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-pretty text-neutral-700 dark:text-neutral-300">
|
||||
{principle.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Non-requirements */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-neutral-100/80 p-6 md:p-10 dark:border-neutral-700 dark:bg-white/[0.05]"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionLimits" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.nonRequirementTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.nonRequirementIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{
|
||||
copy.nonRequirementCards.map((card: any) => (
|
||||
<article class="rounded-2xl border border-neutral-300 bg-white p-5 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{card.content}
|
||||
</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Example timeline */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionTimeline" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.timelineTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.timelineIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ol class="mt-8 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
{
|
||||
copy.timelineEntries.map((entry: any, index: number) => (
|
||||
<li class="rounded-3xl border border-neutral-300 bg-white p-5 shadow-xs dark:border-neutral-700 dark:bg-white/[0.04]">
|
||||
<span class="inline-flex rounded-full bg-yellow-400 px-3 py-1 text-xs font-semibold tracking-[0.18em] text-neutral-900 uppercase">
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
<h3 class="mt-4 text-base font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
{entry.title}
|
||||
</h3>
|
||||
<p class="mt-2 text-sm leading-6 text-neutral-700 dark:text-neutral-300">
|
||||
{entry.content}
|
||||
</p>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Buyer FAQ */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-neutral-100/80 p-6 md:p-10 dark:border-neutral-700 dark:bg-white/[0.05]"
|
||||
>
|
||||
<div class="flex max-w-(--breakpoint-md) items-start gap-x-4">
|
||||
<span
|
||||
class="inline-flex size-12 shrink-0 items-center justify-center rounded-2xl bg-yellow-400/15 text-yellow-600 ring-1 ring-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:ring-yellow-400/20"
|
||||
>
|
||||
<Icon name="sectionFaq" />
|
||||
</span>
|
||||
<div>
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.faqTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.faqIntro}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid gap-x-12 md:grid-cols-2">
|
||||
{
|
||||
[0, 1].map((column: number) => (
|
||||
<div class="hs-accordion-group divide-y divide-neutral-300 dark:divide-neutral-700">
|
||||
{copy.faqItems
|
||||
.filter((_item: any, index: number) => index % 2 === column)
|
||||
.map((item: any, index: number) => {
|
||||
const itemIndex = index * 2 + column;
|
||||
return (
|
||||
<AccordionItem
|
||||
id={`evaluation-faq-heading-${itemIndex}`}
|
||||
collapseId={`evaluation-faq-collapse-${itemIndex}`}
|
||||
question={item.question}
|
||||
answer={item.answer}
|
||||
first={index === 0}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* Final CTA */}
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-900 md:text-3xl dark:text-neutral-100"
|
||||
>
|
||||
{copy.finalCtaTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-700 md:text-lg dark:text-neutral-300"
|
||||
>
|
||||
{copy.finalCtaSubtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
{
|
||||
copy.finalCtas.map((cta: any, index: number) =>
|
||||
index === 0 ? (
|
||||
<PrimaryCTA
|
||||
title={cta.label}
|
||||
url={localizeHref(cta.href, locale)}
|
||||
/>
|
||||
) : (
|
||||
<SecondaryCTA
|
||||
title={cta.label}
|
||||
url={localizeHref(cta.href, locale)}
|
||||
/>
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</MainLayout>
|
||||
@ -195,6 +195,38 @@ const copy = siteCopy[locale].home;
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<span
|
||||
class="text-xs font-semibold tracking-[0.18em] text-yellow-600 uppercase dark:text-yellow-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.homepageEyebrow}
|
||||
</span>
|
||||
<h2
|
||||
class="mt-3 text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.homepageTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.homepageContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.homepageCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
@ -170,4 +170,31 @@ const canonicalPath = localizedPath('/platform', locale);
|
||||
mainStatSubTitle={copy.mainStatSubTitle}
|
||||
stats={copy.stats}
|
||||
/>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.platformTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.platformContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.platformCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</MainLayout>
|
||||
|
||||
@ -516,6 +516,33 @@ const canonicalPath = localizedPath('/platform/review-packs', locale);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.reviewPackTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.reviewPackContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.reviewPackCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
@ -326,4 +326,31 @@ const statusLabel = (key: string) => statusByKey.get(key)?.label ?? key;
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.trustTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.trustContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.trustCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</MainLayout>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import {
|
||||
getLocaleFromPath,
|
||||
localeLabels,
|
||||
localizedPath,
|
||||
localizeRoutePath,
|
||||
stripLocalePrefix,
|
||||
} from '@/i18n';
|
||||
import Icon from './icons/Icon.astro';
|
||||
@ -47,7 +47,11 @@ const currentPath = stripLocalePrefix(Astro.url.pathname);
|
||||
? 'font-semibold text-orange-500 dark:text-orange-300'
|
||||
: 'text-neutral-800 dark:text-neutral-400',
|
||||
]}
|
||||
href={localizedPath(currentPath, locale as 'de' | 'en')}
|
||||
href={localizeRoutePath(
|
||||
currentPath,
|
||||
currentLocale,
|
||||
locale as 'de' | 'en'
|
||||
)}
|
||||
aria-current={locale === currentLocale ? 'true' : undefined}
|
||||
>
|
||||
{label}
|
||||
|
||||
@ -518,4 +518,130 @@ export const Icons = {
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionRoute: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionPrep: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionPilot: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionStakeholders: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionSecurity: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionAccess: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionLimits: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionTimeline: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
sectionFaq: {
|
||||
paths: [
|
||||
{
|
||||
d: 'M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z',
|
||||
},
|
||||
],
|
||||
class: 'size-6 shrink-0',
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
strokeWidth: '1.5',
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
stroke: 'currentColor',
|
||||
},
|
||||
};
|
||||
|
||||
@ -62,6 +62,7 @@ export const siteCopy: Record<Locale, any> = {
|
||||
{ name: 'Interne IT', url: '/use-cases/mittelstand' },
|
||||
{ name: 'Preise', url: '/pricing' },
|
||||
{ name: 'Vertrauen', url: '/trust' },
|
||||
{ name: 'Evaluierung', url: '/evaluierung' },
|
||||
{ name: 'Docs', url: '/welcome-to-docs/' },
|
||||
],
|
||||
},
|
||||
@ -1231,6 +1232,404 @@ export const siteCopy: Record<Locale, any> = {
|
||||
hardClaimNote:
|
||||
'Retained hard trust claims: none. Alle sensiblen Aussagen sind bewusst als dokumentiert, auf Anfrage, in Vorbereitung, geplant, nicht beansprucht oder nicht anwendbar formuliert.',
|
||||
},
|
||||
evaluation: {
|
||||
routePath: '/evaluierung',
|
||||
pageTitle: 'Evaluierung & Rollout | Tenantial',
|
||||
metaDescription:
|
||||
'Erleben Sie in einer Demo, wie Tenantial Microsoft-365-Governance sichtbarer macht, Reviews beschleunigt und einen fokussierten Pilot sauber vorbereitet.',
|
||||
heroEyebrow: 'Evaluierung, Procurement & Rollout',
|
||||
heroTitle: 'Tenantial sicher evaluieren und schneller zum Pilot kommen',
|
||||
heroSubtitle:
|
||||
'Erleben Sie in einer Demo, wie Tenantial Drift sichtbar macht, Reviews verständlicher aufbereitet und Ihren Weg zu einem fokussierten Pilot verkürzt. Trust-, Berechtigungs- und Rollout-Fragen bleiben dabei früh sichtbar statt ein spätes Risiko zu werden.',
|
||||
supportingLine:
|
||||
'Für MSPs und interne IT: schnell verstehen, ob Tenantial zu Ihrem Governance-Setup, Ihren Kundenreviews und Ihrem Rollout-Prozess passt.',
|
||||
primaryCta: { label: 'Demo buchen', href: '/contact' },
|
||||
secondaryCta: { label: 'Trust-Grenzen ansehen', href: '/trust' },
|
||||
tertiaryCta: { label: 'Plattform ansehen', href: '/platform' },
|
||||
pathTitle: 'So wird aus der Demo ein belastbarer Pilot',
|
||||
pathIntro:
|
||||
'Der Weg ist bewusst kurz und klar: Sie sehen den Produktnutzen früh, klären die kritischen Fragen rechtzeitig und landen mit einem kleinen, belastbaren Pilot statt in einem langen Vorprojekt.',
|
||||
evaluationSteps: [
|
||||
{
|
||||
key: 'discovery-call',
|
||||
title: 'Discovery Call',
|
||||
content:
|
||||
'Im ersten Gespräch schärfen wir Ihren Use Case, damit die Demo direkt zeigt, wo Tenantial für Sie operativen Mehrwert liefert.',
|
||||
},
|
||||
{
|
||||
key: 'product-walkthrough',
|
||||
title: 'Produkt-Walkthrough',
|
||||
content:
|
||||
'Eine geführte Demo zeigt, wie Tenantial Policy-Zustand, Evidence und Drift-Sichtbarkeit in eine verständliche Review-Story übersetzt.',
|
||||
},
|
||||
{
|
||||
key: 'security-privacy-review',
|
||||
title: 'Security- & Datenschutz-Review',
|
||||
content:
|
||||
'Trust-, Datenschutz- und Berechtigungsfragen werden früh geklärt, damit Security und Einkauf den Pilot nicht erst kurz vor dem Start ausbremsen.',
|
||||
},
|
||||
{
|
||||
key: 'technical-readiness-check',
|
||||
title: 'Technischer Readiness-Check',
|
||||
content:
|
||||
'Gemeinsam schneiden wir Scope und Berechtigungen so zu, dass der Pilot klein startet und trotzdem die entscheidenden Fragen beantwortet.',
|
||||
},
|
||||
{
|
||||
key: 'focused-pilot',
|
||||
title: 'Fokussierter Pilot',
|
||||
content:
|
||||
'Ein bewusst kleiner Pilot zeigt Tenantial in einem klar abgegrenzten Szenario mit echtem Alltagsbezug statt in einer abstrakten Laborsituation.',
|
||||
},
|
||||
{
|
||||
key: 'review-next-step',
|
||||
title: 'Review & nächster Schritt',
|
||||
content:
|
||||
'Am Ende haben Sie eine lesbare Entscheidungsgrundlage: erkannter Nutzen, offene Punkte und ein sinnvoller nächster Schritt Richtung Rollout.',
|
||||
},
|
||||
],
|
||||
preparationTitle: 'Was Sie für einen starken Start mitbringen sollten',
|
||||
preparationIntro:
|
||||
'Sie brauchen kein Großprojekt, um sinnvoll zu starten. Mit diesen wenigen Punkten wird aus der ersten Demo schnell ein belastbarer nächster Schritt.',
|
||||
preparationCards: [
|
||||
{
|
||||
key: 'use-case',
|
||||
title: 'Use-Case',
|
||||
content:
|
||||
'Eine kurze Beschreibung des konkreten Problems, das Sie lösen wollen, etwa Kundenreviews, interne Kontrolle oder Audit-Vorbereitung.',
|
||||
},
|
||||
{
|
||||
key: 'microsoft-365-scope',
|
||||
title: 'Microsoft-365-Scope',
|
||||
content:
|
||||
'Eine grobe Vorstellung davon, welche Umgebungen und Policy-Bereiche zuerst betrachtet werden sollen.',
|
||||
},
|
||||
{
|
||||
key: 'technical-owner',
|
||||
title: 'Technischer Owner',
|
||||
content:
|
||||
'Eine Person, die den technischen Kontext kennt und den Readiness-Check sowie den Pilot begleiten kann.',
|
||||
},
|
||||
{
|
||||
key: 'security-privacy-contact',
|
||||
title: 'Security-/Datenschutz-Kontakt',
|
||||
content:
|
||||
'Eine Ansprechperson für Trust-, Datenschutz- und Berechtigungsfragen, damit diese Punkte früh statt spät auftauchen.',
|
||||
},
|
||||
{
|
||||
key: 'review-objective',
|
||||
title: 'Review-Ziel',
|
||||
content:
|
||||
'Eine klare Vorstellung davon, was die Evaluierung beantworten soll, damit der Pilot ein messbares Ziel hat.',
|
||||
},
|
||||
{
|
||||
key: 'success-criteria',
|
||||
title: 'Erfolgskriterien',
|
||||
content:
|
||||
'Ein paar einfache Kriterien, an denen Sie festmachen, ob der Pilot für Sie erfolgreich war.',
|
||||
},
|
||||
],
|
||||
pilotTitle: 'Welche Ergebnisse Sie im Pilot sichtbar machen können',
|
||||
pilotIntro:
|
||||
'Diese Szenarien zeigen, wo Tenantial früh Nutzen stiften kann. Sie sind bewusst fokussiert und helfen Ihnen, den Pilot auf ein klares Ergebnis statt auf maximale Breite auszurichten.',
|
||||
pilotScenarios: [
|
||||
{
|
||||
key: 'msp-customer-review',
|
||||
title: 'MSP-Kundenreview',
|
||||
content:
|
||||
'Ein MSP nutzt einen begrenzten Pilot, um einen wiederholbaren Kundenreview mit Evidence und sichtbarem Follow-up zu erproben.',
|
||||
},
|
||||
{
|
||||
key: 'internal-it-governance',
|
||||
title: 'Interne IT-Governance',
|
||||
content:
|
||||
'Eine interne IT prüft Tenantial für nachvollziehbare Changes, Audit-Kontext und defensive Recovery-Vorbereitung.',
|
||||
},
|
||||
{
|
||||
key: 'policy-backup-versioning',
|
||||
title: 'Policy-Backup & Versionierung',
|
||||
content:
|
||||
'Der Pilot konzentriert sich auf versionierte Konfigurationsstände und reproduzierbare Evidence über die Zeit.',
|
||||
},
|
||||
{
|
||||
key: 'evidence-audit-preparation',
|
||||
title: 'Evidence- & Audit-Vorbereitung',
|
||||
content:
|
||||
'Der Fokus liegt darauf, Evidence so aufzubereiten, dass sie eine Review-Entscheidung statt nur Screenshots erklärt.',
|
||||
},
|
||||
{
|
||||
key: 'provider-permission-readiness',
|
||||
title: 'Provider-Berechtigungen',
|
||||
content:
|
||||
'Der Pilot klärt, welche Microsoft-365-Berechtigungen je nach Pilot-Scope nötig sind, bevor breiter ausgerollt wird.',
|
||||
},
|
||||
],
|
||||
stakeholderTitle:
|
||||
'Wer Sie schnell zu einer tragfähigen Entscheidung bringt',
|
||||
stakeholderIntro:
|
||||
'Tenantial verkauft sich nicht nur über Features. Die Entscheidung wird schneller und sauberer, wenn Betrieb, Governance, Security und Einkauf früh dasselbe Bild sehen.',
|
||||
stakeholderCards: [
|
||||
{
|
||||
key: 'msp-service-owner',
|
||||
title: 'MSP Service-Owner',
|
||||
content:
|
||||
'Bewertet, ob Tenantial den Kundenservice wiederholbar und überzeugend macht.',
|
||||
},
|
||||
{
|
||||
key: 'msp-operator',
|
||||
title: 'MSP-Operator',
|
||||
content:
|
||||
'Prüft den täglichen Ablauf: Reviews, Evidence und Follow-up über mehrere Umgebungen.',
|
||||
},
|
||||
{
|
||||
key: 'it-leadership',
|
||||
title: 'IT-Leitung',
|
||||
content:
|
||||
'Bewertet Kontrolle, Nachvollziehbarkeit und den Wert für interne Governance.',
|
||||
},
|
||||
{
|
||||
key: 'microsoft-365-admin',
|
||||
title: 'Microsoft-365-Admin',
|
||||
content:
|
||||
'Klärt den technischen Scope, Berechtigungen und die Einbindung in die bestehende Umgebung.',
|
||||
},
|
||||
{
|
||||
key: 'security',
|
||||
title: 'Security',
|
||||
content:
|
||||
'Prüft Zugriffsmodell, Grenzen und das Versprechen, dass nichts blind ausgeführt wird.',
|
||||
},
|
||||
{
|
||||
key: 'datenschutz-dpo',
|
||||
title: 'Datenschutz / DPO',
|
||||
content:
|
||||
'Adressiert AVV/DPA, TOM und Datenschutzfragen über den realen Kontaktweg.',
|
||||
},
|
||||
{
|
||||
key: 'procurement-vendor-management',
|
||||
title: 'Einkauf / Lieferantenmanagement',
|
||||
content:
|
||||
'Bewertet kommerzielle Passung, Vertragsfragen und den weiteren Beschaffungsprozess.',
|
||||
},
|
||||
],
|
||||
securityTitle: 'Security- & Procurement-Fragen vorab klären',
|
||||
securityIntro:
|
||||
'Diese Punkte sind oft der Unterschied zwischen Interesse und echtem Pilot-Start. Wir halten sie bewusst konkret, ohne erfundene Freigaben oder Downloads vorzutäuschen.',
|
||||
securityChecklist: [
|
||||
{
|
||||
key: 'trust-privacy',
|
||||
title: 'Trust & Datenschutz',
|
||||
content:
|
||||
'Wie Tenantial mit Vertrauen und Datenschutz umgeht, lässt sich auf der Trust-Seite einordnen und im Gespräch vertiefen.',
|
||||
},
|
||||
{
|
||||
key: 'avv-dpa-tom',
|
||||
title: 'AVV / DPA / TOM',
|
||||
content:
|
||||
'AVV/DPA und TOM werden über den realen Kontaktweg geklärt; der jeweilige Status wird offen benannt statt vorzeitig als fertig dargestellt.',
|
||||
},
|
||||
{
|
||||
key: 'provider-permissions',
|
||||
title: 'Provider-Berechtigungen',
|
||||
content:
|
||||
'Welche Microsoft-365-Berechtigungen nötig sind, hängt vom Pilot-Scope ab und wird gemeinsam abgestimmt.',
|
||||
},
|
||||
{
|
||||
key: 'hosting-subprocessors',
|
||||
title: 'Hosting & Subprozessoren',
|
||||
content:
|
||||
'Fragen zu Hosting und Subprozessoren werden direkt beantwortet, ohne pauschale Garantien auf der öffentlichen Website.',
|
||||
},
|
||||
{
|
||||
key: 'audit-retention',
|
||||
title: 'Audit & Aufbewahrung',
|
||||
content:
|
||||
'Audit-Trail und Aufbewahrung werden im Kontext der konkreten Anforderungen besprochen.',
|
||||
},
|
||||
{
|
||||
key: 'commercial-fit',
|
||||
title: 'Kommerzielle Passung',
|
||||
content:
|
||||
'Preis- und Vertragsfragen werden im Beschaffungsprozess geklärt; kommerzielle Bedingungen erfordern eine schriftliche Vereinbarung.',
|
||||
},
|
||||
],
|
||||
securityHandoffTitle: 'Trust-Unterlagen direkt anfordern',
|
||||
securityHandoffText:
|
||||
'Wenn Sie AVV/DPA, TOM, Security-Fragen oder Berechtigungsdetails prüfen wollen, geht das über den realen Kontaktweg. So bekommen Sie belastbare Aussagen statt Marketing-Abkürzungen.',
|
||||
securityHandoffCta: {
|
||||
label: 'Security-Unterlagen anfragen',
|
||||
href: '/contact',
|
||||
},
|
||||
accessTitle: 'Microsoft-365-Zugriff ohne unnötige Reibung planen',
|
||||
accessIntro:
|
||||
'Tenantial soll Ihnen schneller Klarheit geben, nicht mit unnötig breiten Rechteforderungen starten. Deshalb orientiert sich der Einstieg am Pilot-Scope und an einem nachvollziehbaren Readiness-Modell.',
|
||||
accessPrinciples: [
|
||||
{
|
||||
key: 'read-oriented-access',
|
||||
title: 'Lesender Zugriff zuerst',
|
||||
content:
|
||||
'Der Einstieg ist lesend orientiert: beobachten, vergleichen und Evidence aufbauen, bevor verändernde Schritte überhaupt Thema werden.',
|
||||
},
|
||||
{
|
||||
key: 'write-recovery-adjacent-access',
|
||||
title: 'Schreib- und recovery-naher Zugriff',
|
||||
content:
|
||||
'Verändernde oder recovery-nahe Aktionen werden nur scope-abhängig und bewusst eingeordnet, nicht pauschal vorausgesetzt.',
|
||||
},
|
||||
{
|
||||
key: 'consent-admin-roles',
|
||||
title: 'Consent & Admin-Rollen',
|
||||
content:
|
||||
'Notwendiger Consent und Admin-Rollen werden je nach Pilot-Scope abgestimmt, statt undifferenziert maximale Rechte zu verlangen.',
|
||||
},
|
||||
{
|
||||
key: 'no-blind-execution',
|
||||
title: 'Keine blinde Ausführung',
|
||||
content:
|
||||
'Sensible Aktionen bleiben preview-first mit Validierung, Konfliktbewusstsein und expliziter Bestätigung. Nichts wird blind ausgeführt.',
|
||||
},
|
||||
],
|
||||
nonRequirementTitle: 'Was Sie für den Start nicht umstellen müssen',
|
||||
nonRequirementIntro:
|
||||
'Ein guter Einstieg fühlt sich nicht wie ein Plattformwechsel an. Diese Grenzen halten die Einstiegshürde niedrig, ohne die Trust-Grenze weichzuzeichnen.',
|
||||
nonRequirementCards: [
|
||||
{
|
||||
key: 'no-big-bang-rollout',
|
||||
title: 'Kein Big-Bang-Rollout',
|
||||
content:
|
||||
'Die Evaluierung verlangt keinen sofortigen flächendeckenden Rollout. Ein kontrollierter Rollout folgt erst nach der Review-Entscheidung.',
|
||||
},
|
||||
{
|
||||
key: 'no-admin-center-replacement',
|
||||
title: 'Kein Ersatz für das Admin Center',
|
||||
content:
|
||||
'Tenantial ersetzt das Microsoft Admin Center nicht, sondern ergänzt es um Versionierung, Evidence und Review-Kontext.',
|
||||
},
|
||||
{
|
||||
key: 'no-helpdesk-switch',
|
||||
title: 'Kein Helpdesk-/PSA-Wechsel',
|
||||
content:
|
||||
'Sie müssen für die Evaluierung weder Helpdesk noch PSA wechseln.',
|
||||
},
|
||||
{
|
||||
key: 'no-automatic-remediation',
|
||||
title: 'Keine automatische Remediation',
|
||||
content:
|
||||
'Es gibt keine im Hintergrund laufende automatische Korrektur. Veränderungen bleiben bewusst und bestätigt.',
|
||||
},
|
||||
{
|
||||
key: 'no-fake-compliance',
|
||||
title: 'Keine vorgetäuschte Compliance',
|
||||
content:
|
||||
'Tenantial behauptet keine Zertifizierung oder fertige rechtliche Freigabe. Status wird offen geklärt statt versprochen.',
|
||||
},
|
||||
],
|
||||
timelineTitle: 'Ein typischer Weg von Demo zu Entscheidung',
|
||||
timelineIntro:
|
||||
'Keine starre Zusage, aber ein realistischer Takt: schnell genug für Momentum, sauber genug für Security, Procurement und technische Freigaben.',
|
||||
timelineEntries: [
|
||||
{
|
||||
key: 'orientation',
|
||||
title: 'Orientierung',
|
||||
content:
|
||||
'Discovery Call und Walkthrough, um Use-Case und Ziel der Evaluierung zu klären.',
|
||||
},
|
||||
{
|
||||
key: 'technical-review',
|
||||
title: 'Technischer Review',
|
||||
content:
|
||||
'Readiness-Check und Security-/Datenschutz-Fragen, um den Pilot-Scope abzustecken.',
|
||||
},
|
||||
{
|
||||
key: 'pilot',
|
||||
title: 'Pilot',
|
||||
content:
|
||||
'Fokussierter Pilot an einem klar abgegrenzten Szenario mit nachvollziehbarer Evidence.',
|
||||
},
|
||||
{
|
||||
key: 'wrap-up-review',
|
||||
title: 'Abschluss-Review',
|
||||
content:
|
||||
'Lesbare Review-Entscheidung und Skizze eines kontrollierten Rollouts als nächster Schritt.',
|
||||
},
|
||||
],
|
||||
faqTitle: 'Häufige Fragen vor Demo und Pilot',
|
||||
faqIntro:
|
||||
'Direkte Antworten auf die Fragen, die vor einer Demo, vor einem Pilot und vor der internen Freigabe fast immer auftauchen.',
|
||||
faqItems: [
|
||||
{
|
||||
question: 'Brauchen wir dafür einen produktiven Tenant?',
|
||||
answer:
|
||||
'Für die erste Demo nicht. Ein produktiver Microsoft-365-Tenant wird erst relevant, wenn Sie einen fokussierten Pilot je nach Scope vereinbaren.',
|
||||
},
|
||||
{
|
||||
question: 'Welche Berechtigungen sind nötig?',
|
||||
answer:
|
||||
'Das hängt vom Pilot-Scope ab. Der Einstieg ist lesend orientiert; verändernde oder recovery-nahe Rechte werden nur scope-abhängig abgestimmt.',
|
||||
},
|
||||
{
|
||||
question: 'Wie ist der Status von AVV und TOM?',
|
||||
answer:
|
||||
'AVV/DPA und TOM werden über den realen Kontaktweg geklärt. Der jeweilige Status wird offen benannt statt vorzeitig als abgeschlossen dargestellt.',
|
||||
},
|
||||
{
|
||||
question: 'Ersetzt Tenantial das Admin Center?',
|
||||
answer:
|
||||
'Nein. Tenantial ergänzt das Microsoft Admin Center um Versionierung, Evidence, Drift-Sichtbarkeit und Review-Kontext.',
|
||||
},
|
||||
{
|
||||
question: 'Müssen wir Helpdesk oder PSA wechseln?',
|
||||
answer:
|
||||
'Nein. Für die Evaluierung ist kein Wechsel von Helpdesk oder PSA nötig.',
|
||||
},
|
||||
{
|
||||
question: 'Verändert Tenantial automatisch etwas?',
|
||||
answer:
|
||||
'Nein. Sensible Aktionen bleiben preview-first, mit Validierung und expliziter Bestätigung. Es gibt keine automatische Remediation oder automatische Wiederherstellung.',
|
||||
},
|
||||
{
|
||||
question: 'Welche Provider werden unterstützt?',
|
||||
answer:
|
||||
'Der heutige Fokus ist Microsoft 365. Weitere Policy-Domänen sind als Richtung eingeordnet, nicht als live unterstützte Integrationen.',
|
||||
},
|
||||
{
|
||||
question: 'Wo liegt die Compliance-Grenze?',
|
||||
answer:
|
||||
'Tenantial unterstützt Ihre Governance- und Audit-Arbeit, ersetzt aber keine rechtliche oder Compliance-Bewertung. Tenantial behauptet keine Zertifizierung.',
|
||||
},
|
||||
],
|
||||
finalCtaTitle: 'Prüfen Sie jetzt, ob Tenantial zu Ihrem Setup passt',
|
||||
finalCtaSubtitle:
|
||||
'Starten Sie mit einer Demo, stecken Sie einen fokussierten Pilot ab oder klären Sie zuerst Trust- und Security-Fragen. So kommen Sie schnell zu einer belastbaren Entscheidung statt zu einem langen Vorprojekt.',
|
||||
finalCtas: [
|
||||
{ label: 'Demo buchen', href: '/contact' },
|
||||
{ label: 'Trust-Grenzen ansehen', href: '/trust' },
|
||||
{ label: 'Plattform ansehen', href: '/platform' },
|
||||
],
|
||||
discovery: {
|
||||
homepageEyebrow: 'Evaluierung & Pilot',
|
||||
homepageTitle:
|
||||
'Tenantial sicher evaluieren und schneller zum Pilot kommen',
|
||||
homepageContent:
|
||||
'Erleben Sie in einer Demo, wie Tenantial Reviews verständlicher macht, Drift sichtbar hält und einen fokussierten Pilot sauber vorbereitet.',
|
||||
homepageCta: 'Evaluierung & Pilot ansehen',
|
||||
platformTitle: 'Evaluierung & kontrollierter Rollout',
|
||||
platformContent:
|
||||
'Sehen Sie, wie Tenantial von der Demo bis zur Rollout-Entscheidung Mehrwert, Security-Fragen und Pilot-Scope in einen klaren Prozess bringt.',
|
||||
platformCta: 'Evaluierung & Rollout ansehen',
|
||||
reviewPackTitle: 'Vom Review zur Evaluierung',
|
||||
reviewPackContent:
|
||||
'Wenn die Review-Story überzeugt, zeigt der Evaluierungspfad den schnellsten Weg von echtem Mehrwert zur Pilot-Entscheidung.',
|
||||
reviewPackCta: 'Evaluierungspfad ansehen',
|
||||
trustTitle: 'Evaluierung & Procurement',
|
||||
trustContent:
|
||||
'Kritische Trust-, Datenschutz- und Procurement-Fragen werden früh geklärt, damit ein Pilot nicht am Ende hängen bleibt.',
|
||||
trustCta: 'Evaluierung & Procurement ansehen',
|
||||
useCaseTitle: 'Evaluierung & Pilot planen',
|
||||
useCaseContent:
|
||||
'Planen Sie einen fokussierten Einstieg, der Ihren Use Case zeigt, Security mitnimmt und schnell zu einer klaren Pilot-Entscheidung führt.',
|
||||
useCaseCta: 'Evaluierung & Pilot planen',
|
||||
},
|
||||
},
|
||||
legal: {
|
||||
pageTitle: 'Rechtliches | Tenantial',
|
||||
metaDescription:
|
||||
@ -1294,6 +1693,7 @@ export const siteCopy: Record<Locale, any> = {
|
||||
{ name: 'Internal IT', url: '/use-cases/mittelstand' },
|
||||
{ name: 'Pricing', url: '/pricing' },
|
||||
{ name: 'Trust', url: '/trust' },
|
||||
{ name: 'Evaluation', url: '/evaluation' },
|
||||
{ name: 'Docs', url: '/welcome-to-docs/' },
|
||||
],
|
||||
},
|
||||
@ -2454,6 +2854,402 @@ export const siteCopy: Record<Locale, any> = {
|
||||
hardClaimNote:
|
||||
'Retained hard trust claims: none. Sensitive statements are intentionally phrased as documented, on request, in preparation, planned, not claimed, or not applicable.',
|
||||
},
|
||||
evaluation: {
|
||||
routePath: '/evaluation',
|
||||
pageTitle: 'Evaluation & Rollout | Tenantial',
|
||||
metaDescription:
|
||||
'See in one demo how Tenantial makes Microsoft 365 governance clearer, speeds up reviews, and prepares a focused pilot without hand-wavy rollout promises.',
|
||||
heroEyebrow: 'Evaluation, procurement & rollout',
|
||||
heroTitle: 'Evaluate Tenantial and get to a focused pilot faster',
|
||||
heroSubtitle:
|
||||
'See in a live demo how Tenantial makes drift visible, turns reviews into something teams can actually act on, and shortens the path to a focused pilot. Trust, permission, and rollout questions stay visible early instead of becoming late-stage blockers.',
|
||||
supportingLine:
|
||||
'For MSPs and internal IT: quickly understand whether Tenantial fits your governance setup, customer review motion, and rollout process.',
|
||||
primaryCta: { label: 'Book a demo', href: '/contact' },
|
||||
secondaryCta: { label: 'See trust boundaries', href: '/trust' },
|
||||
tertiaryCta: { label: 'View platform', href: '/platform' },
|
||||
pathTitle: 'How a demo turns into a credible pilot',
|
||||
pathIntro:
|
||||
'The path is intentionally short and clear: see product value early, answer the risky questions on time, and end with a bounded pilot instead of a long pre-project.',
|
||||
evaluationSteps: [
|
||||
{
|
||||
key: 'discovery-call',
|
||||
title: 'Discovery call',
|
||||
content:
|
||||
'The first conversation sharpens your use case so the demo shows where Tenantial creates operational value for your team.',
|
||||
},
|
||||
{
|
||||
key: 'product-walkthrough',
|
||||
title: 'Product walkthrough',
|
||||
content:
|
||||
'A guided demo shows how Tenantial turns policy state, evidence, and drift visibility into a review story people can actually work with.',
|
||||
},
|
||||
{
|
||||
key: 'security-privacy-review',
|
||||
title: 'Security & privacy review',
|
||||
content:
|
||||
'Trust, privacy, and permission questions are handled early so security and procurement do not become last-minute blockers to the pilot.',
|
||||
},
|
||||
{
|
||||
key: 'technical-readiness-check',
|
||||
title: 'Technical readiness check',
|
||||
content:
|
||||
'Together we right-size scope and permissions so the pilot starts small while still answering the questions that matter.',
|
||||
},
|
||||
{
|
||||
key: 'focused-pilot',
|
||||
title: 'Focused pilot',
|
||||
content:
|
||||
'A deliberately small pilot proves Tenantial in a real operating scenario instead of throwing everything into production at once.',
|
||||
},
|
||||
{
|
||||
key: 'review-next-step',
|
||||
title: 'Review & next step',
|
||||
content:
|
||||
'The result is a readable decision: observed value, open questions, and the next sensible step toward rollout.',
|
||||
},
|
||||
],
|
||||
preparationTitle: 'What helps you start strong',
|
||||
preparationIntro:
|
||||
'You do not need a major project to start well. With these few inputs, the first demo can turn quickly into a meaningful next step.',
|
||||
preparationCards: [
|
||||
{
|
||||
key: 'use-case',
|
||||
title: 'Use case',
|
||||
content:
|
||||
'A short description of the concrete problem you want to solve, such as customer reviews, internal control, or audit preparation.',
|
||||
},
|
||||
{
|
||||
key: 'microsoft-365-scope',
|
||||
title: 'Microsoft 365 scope',
|
||||
content:
|
||||
'A rough idea of which environments and policy areas should be looked at first.',
|
||||
},
|
||||
{
|
||||
key: 'technical-owner',
|
||||
title: 'Technical owner',
|
||||
content:
|
||||
'A person who knows the technical context and can support the readiness check and the pilot.',
|
||||
},
|
||||
{
|
||||
key: 'security-privacy-contact',
|
||||
title: 'Security/privacy contact',
|
||||
content:
|
||||
'A contact for trust, privacy, and permission questions so these points surface early rather than late.',
|
||||
},
|
||||
{
|
||||
key: 'review-objective',
|
||||
title: 'Review objective',
|
||||
content:
|
||||
'A clear idea of what the evaluation should answer so the pilot has a measurable goal.',
|
||||
},
|
||||
{
|
||||
key: 'success-criteria',
|
||||
title: 'Success criteria',
|
||||
content:
|
||||
'A few simple criteria you use to decide whether the pilot was successful for you.',
|
||||
},
|
||||
],
|
||||
pilotTitle: 'What you can make visible in the pilot',
|
||||
pilotIntro:
|
||||
'These scenarios show where Tenantial can create early value. They are intentionally focused so the pilot is aimed at a clear result, not maximum breadth.',
|
||||
pilotScenarios: [
|
||||
{
|
||||
key: 'msp-customer-review',
|
||||
title: 'MSP customer review',
|
||||
content:
|
||||
'An MSP uses a bounded pilot to try a repeatable customer review with evidence and visible follow-up.',
|
||||
},
|
||||
{
|
||||
key: 'internal-it-governance',
|
||||
title: 'Internal IT governance',
|
||||
content:
|
||||
'An internal IT team evaluates Tenantial for traceable changes, audit context, and defensive recovery preparation.',
|
||||
},
|
||||
{
|
||||
key: 'policy-backup-versioning',
|
||||
title: 'Policy backup & versioning',
|
||||
content:
|
||||
'The pilot focuses on versioned configuration states and reproducible evidence over time.',
|
||||
},
|
||||
{
|
||||
key: 'evidence-audit-preparation',
|
||||
title: 'Evidence & audit preparation',
|
||||
content:
|
||||
'The focus is on shaping evidence so it explains a review decision rather than just screenshots.',
|
||||
},
|
||||
{
|
||||
key: 'provider-permission-readiness',
|
||||
title: 'Provider permission readiness',
|
||||
content:
|
||||
'The pilot clarifies which Microsoft 365 permissions are needed depending on pilot scope before rolling out more broadly.',
|
||||
},
|
||||
],
|
||||
stakeholderTitle: 'Who helps you reach a credible decision faster',
|
||||
stakeholderIntro:
|
||||
'Tenantial is not won on feature lists alone. Decisions move faster when operations, governance, security, and procurement see the same picture early.',
|
||||
stakeholderCards: [
|
||||
{
|
||||
key: 'msp-service-owner',
|
||||
title: 'MSP service owner',
|
||||
content:
|
||||
'Evaluates whether Tenantial makes the customer service repeatable and convincing.',
|
||||
},
|
||||
{
|
||||
key: 'msp-operator',
|
||||
title: 'MSP operator',
|
||||
content:
|
||||
'Checks the day-to-day flow: reviews, evidence, and follow-up across multiple environments.',
|
||||
},
|
||||
{
|
||||
key: 'it-leadership',
|
||||
title: 'IT leadership',
|
||||
content:
|
||||
'Evaluates control, traceability, and the value for internal governance.',
|
||||
},
|
||||
{
|
||||
key: 'microsoft-365-admin',
|
||||
title: 'Microsoft 365 admin',
|
||||
content:
|
||||
'Clarifies the technical scope, permissions, and fit into the existing environment.',
|
||||
},
|
||||
{
|
||||
key: 'security',
|
||||
title: 'Security',
|
||||
content:
|
||||
'Reviews the access model, boundaries, and the promise that nothing is executed blindly.',
|
||||
},
|
||||
{
|
||||
key: 'datenschutz-dpo',
|
||||
title: 'Privacy / DPO',
|
||||
content:
|
||||
'Addresses DPA, TOM, and privacy questions through the real contact path.',
|
||||
},
|
||||
{
|
||||
key: 'procurement-vendor-management',
|
||||
title: 'Procurement / vendor management',
|
||||
content:
|
||||
'Evaluates commercial fit, contract questions, and the wider procurement process.',
|
||||
},
|
||||
],
|
||||
securityTitle: 'Security & procurement questions to clear early',
|
||||
securityIntro:
|
||||
'These are often the points that decide whether interest becomes a real pilot. We keep them concrete without pretending approvals or downloadable proof packs already exist.',
|
||||
securityChecklist: [
|
||||
{
|
||||
key: 'trust-privacy',
|
||||
title: 'Trust & privacy',
|
||||
content:
|
||||
'How Tenantial handles trust and privacy can be understood on the trust page and explored further in conversation.',
|
||||
},
|
||||
{
|
||||
key: 'avv-dpa-tom',
|
||||
title: 'DPA / TOM',
|
||||
content:
|
||||
'DPA and TOM are clarified through the real contact path; the respective status is named openly instead of presented as finished prematurely.',
|
||||
},
|
||||
{
|
||||
key: 'provider-permissions',
|
||||
title: 'Provider permissions',
|
||||
content:
|
||||
'Which Microsoft 365 permissions are needed depends on pilot scope and is agreed together.',
|
||||
},
|
||||
{
|
||||
key: 'hosting-subprocessors',
|
||||
title: 'Hosting & subprocessors',
|
||||
content:
|
||||
'Questions about hosting and subprocessors are answered directly, without blanket guarantees on the public website.',
|
||||
},
|
||||
{
|
||||
key: 'audit-retention',
|
||||
title: 'Audit & retention',
|
||||
content:
|
||||
'Audit trail and retention are discussed in the context of your concrete requirements.',
|
||||
},
|
||||
{
|
||||
key: 'commercial-fit',
|
||||
title: 'Commercial fit',
|
||||
content:
|
||||
'Pricing and contract questions are clarified in the procurement process; commercial terms require a written agreement.',
|
||||
},
|
||||
],
|
||||
securityHandoffTitle: 'Request trust documents directly',
|
||||
securityHandoffText:
|
||||
'If you need DPA, TOM, security answers, or permission details, use the real contact path. That keeps the conversation reliable instead of hiding behind marketing shortcuts.',
|
||||
securityHandoffCta: {
|
||||
label: 'Request security documents',
|
||||
href: '/contact',
|
||||
},
|
||||
accessTitle: 'Plan Microsoft 365 access without unnecessary friction',
|
||||
accessIntro:
|
||||
'Tenantial should give you clarity faster, not start with unnecessarily broad rights requests. The entry point follows pilot scope and a readable readiness model.',
|
||||
accessPrinciples: [
|
||||
{
|
||||
key: 'read-oriented-access',
|
||||
title: 'Read-oriented access first',
|
||||
content:
|
||||
'The entry point is read-oriented: observe, compare, and build evidence before any changing steps become a topic at all.',
|
||||
},
|
||||
{
|
||||
key: 'write-recovery-adjacent-access',
|
||||
title: 'Write and recovery-adjacent access',
|
||||
content:
|
||||
'Changing or recovery-adjacent actions are only framed depending on scope, not assumed across the board.',
|
||||
},
|
||||
{
|
||||
key: 'consent-admin-roles',
|
||||
title: 'Consent & admin roles',
|
||||
content:
|
||||
'Required consent and admin roles are agreed depending on pilot scope, instead of demanding maximum rights indiscriminately.',
|
||||
},
|
||||
{
|
||||
key: 'no-blind-execution',
|
||||
title: 'No blind execution',
|
||||
content:
|
||||
'Sensitive actions stay preview-first with validation, conflict awareness, and explicit confirmation. Nothing is executed blindly.',
|
||||
},
|
||||
],
|
||||
nonRequirementTitle: 'What you do not have to change to get started',
|
||||
nonRequirementIntro:
|
||||
'A good evaluation should not feel like a platform migration. These boundaries keep the entry hurdle low without softening the trust line.',
|
||||
nonRequirementCards: [
|
||||
{
|
||||
key: 'no-big-bang-rollout',
|
||||
title: 'No big-bang rollout',
|
||||
content:
|
||||
'The evaluation does not require an immediate organization-wide rollout. A controlled rollout follows only after the review decision.',
|
||||
},
|
||||
{
|
||||
key: 'no-admin-center-replacement',
|
||||
title: 'No admin center replacement',
|
||||
content:
|
||||
'Tenantial does not replace the Microsoft admin center; it complements it with versioning, evidence, and review context.',
|
||||
},
|
||||
{
|
||||
key: 'no-helpdesk-switch',
|
||||
title: 'No helpdesk/PSA switch',
|
||||
content:
|
||||
'You do not have to switch helpdesk or PSA for the evaluation.',
|
||||
},
|
||||
{
|
||||
key: 'no-automatic-remediation',
|
||||
title: 'No unattended remediation',
|
||||
content:
|
||||
'Nothing corrects your tenant in the background. Changes stay deliberate and confirmed.',
|
||||
},
|
||||
{
|
||||
key: 'no-fake-compliance',
|
||||
title: 'No pretended compliance',
|
||||
content:
|
||||
'Tenantial does not claim certification or finished legal approval. Status is clarified openly instead of promised.',
|
||||
},
|
||||
],
|
||||
timelineTitle: 'A typical path from demo to decision',
|
||||
timelineIntro:
|
||||
'Not a fixed commitment, but a realistic pace: fast enough for momentum, structured enough for security, procurement, and technical sign-off.',
|
||||
timelineEntries: [
|
||||
{
|
||||
key: 'orientation',
|
||||
title: 'Orientation',
|
||||
content:
|
||||
'Discovery call and walkthrough to clarify the use case and the goal of the evaluation.',
|
||||
},
|
||||
{
|
||||
key: 'technical-review',
|
||||
title: 'Technical review',
|
||||
content:
|
||||
'Readiness check and security/privacy questions to scope the pilot.',
|
||||
},
|
||||
{
|
||||
key: 'pilot',
|
||||
title: 'Pilot',
|
||||
content:
|
||||
'Focused pilot against a clearly bounded scenario with traceable evidence.',
|
||||
},
|
||||
{
|
||||
key: 'wrap-up-review',
|
||||
title: 'Wrap-up review',
|
||||
content:
|
||||
'Readable review decision and an outline of a controlled rollout as the next step.',
|
||||
},
|
||||
],
|
||||
faqTitle: 'Questions that come up before demo and pilot',
|
||||
faqIntro:
|
||||
'Straight answers to the questions that usually come up before a demo, before a pilot, and before internal sign-off.',
|
||||
faqItems: [
|
||||
{
|
||||
question: 'Do we need a productive tenant for this?',
|
||||
answer:
|
||||
'Not for the first demo. A productive Microsoft 365 tenant only becomes relevant when you agree a focused pilot depending on scope.',
|
||||
},
|
||||
{
|
||||
question: 'Which permissions are required?',
|
||||
answer:
|
||||
'It depends on pilot scope. The entry point is read-oriented; changing or recovery-adjacent rights are only agreed depending on scope.',
|
||||
},
|
||||
{
|
||||
question: 'What is the status of DPA and TOM?',
|
||||
answer:
|
||||
'DPA and TOM are clarified through the real contact path. The respective status is named openly instead of presented as completed prematurely.',
|
||||
},
|
||||
{
|
||||
question: 'Does Tenantial replace the admin center?',
|
||||
answer:
|
||||
'No. Tenantial complements the Microsoft admin center with versioning, evidence, drift visibility, and review context.',
|
||||
},
|
||||
{
|
||||
question: 'Do we have to switch helpdesk or PSA?',
|
||||
answer:
|
||||
'No. The evaluation does not require switching helpdesk or PSA.',
|
||||
},
|
||||
{
|
||||
question: 'Does Tenantial change anything automatically?',
|
||||
answer:
|
||||
'No. Sensitive actions stay preview-first, with validation and explicit confirmation. Nothing is remediated or restored without your review and approval.',
|
||||
},
|
||||
{
|
||||
question: 'Which providers are supported?',
|
||||
answer:
|
||||
'Today the focus is Microsoft 365. Further policy domains are framed as direction, not as live supported integrations.',
|
||||
},
|
||||
{
|
||||
question: 'Where is the compliance boundary?',
|
||||
answer:
|
||||
'Tenantial supports your governance and audit work but does not replace a legal or compliance assessment. Tenantial does not claim certification.',
|
||||
},
|
||||
],
|
||||
finalCtaTitle: 'Check whether Tenantial fits your setup',
|
||||
finalCtaSubtitle:
|
||||
'Start with a demo, shape a focused pilot, or clear trust and security questions first. The goal is a credible decision quickly, not a drawn-out pre-project.',
|
||||
finalCtas: [
|
||||
{ label: 'Book a demo', href: '/contact' },
|
||||
{ label: 'See trust boundaries', href: '/trust' },
|
||||
{ label: 'View platform', href: '/platform' },
|
||||
],
|
||||
discovery: {
|
||||
homepageEyebrow: 'Evaluation & pilot',
|
||||
homepageTitle: 'Evaluate Tenantial and get to a focused pilot faster',
|
||||
homepageContent:
|
||||
'See in one demo how Tenantial makes reviews clearer, keeps drift visible, and prepares a focused pilot without hand-wavy rollout promises.',
|
||||
homepageCta: 'See evaluation and pilot',
|
||||
platformTitle: 'Evaluation & controlled rollout',
|
||||
platformContent:
|
||||
'See how Tenantial brings product value, security questions, and pilot scope into one clear path from demo to rollout decision.',
|
||||
platformCta: 'See evaluation and rollout',
|
||||
reviewPackTitle: 'From review to evaluation',
|
||||
reviewPackContent:
|
||||
'If the review story resonates, the evaluation path shows the fastest route from visible value to a focused pilot decision.',
|
||||
reviewPackCta: 'See the evaluation path',
|
||||
trustTitle: 'Evaluation & procurement',
|
||||
trustContent:
|
||||
'Trust, privacy, and procurement questions are handled early so a pilot does not stall at the end.',
|
||||
trustCta: 'See evaluation and procurement',
|
||||
useCaseTitle: 'Plan evaluation and pilot',
|
||||
useCaseContent:
|
||||
'Plan a focused start that proves your use case, brings security along, and gets you to a clear pilot decision fast.',
|
||||
useCaseCta: 'Plan evaluation and pilot',
|
||||
},
|
||||
},
|
||||
legal: {
|
||||
pageTitle: 'Legal | Tenantial',
|
||||
metaDescription: 'Tenantial public website legal information.',
|
||||
|
||||
@ -73,3 +73,31 @@ export function localizeHref(href: string, locale: Locale): string {
|
||||
|
||||
return hash ? `${localized}#${hash}` : localized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Routes whose URL slug differs per locale. Each group maps a locale to its
|
||||
* locale-specific base path (without the locale prefix). Used to translate a
|
||||
* route between locales for the language switcher and hreflang alternates.
|
||||
*
|
||||
* @type {ReadonlyArray<Record<Locale, string>>}
|
||||
*/
|
||||
const slugAliasGroups: ReadonlyArray<Record<Locale, string>> = [
|
||||
{ de: '/evaluierung', en: '/evaluation' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Translate a locale-stripped route path from one locale to another, honoring
|
||||
* per-locale slug aliases. Falls back to the same slug when no alias exists.
|
||||
*/
|
||||
export function localizeRoutePath(
|
||||
strippedPath: string,
|
||||
fromLocale: Locale,
|
||||
toLocale: Locale
|
||||
): string {
|
||||
const group = slugAliasGroups.find(
|
||||
aliasGroup => aliasGroup[fromLocale] === strippedPath
|
||||
);
|
||||
const targetBase = group ? group[toLocale] : strippedPath;
|
||||
|
||||
return localizedPath(targetBase, toLocale);
|
||||
}
|
||||
|
||||
5
apps/website/src/pages/en/evaluation.astro
Normal file
5
apps/website/src/pages/en/evaluation.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import EvaluationPage from '@components/pages/EvaluationPage.astro';
|
||||
---
|
||||
|
||||
<EvaluationPage locale="en" />
|
||||
@ -250,6 +250,33 @@ const canonicalPath = localizedPath('/use-cases/mittelstand', locale);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.useCaseCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
@ -250,6 +250,33 @@ const canonicalPath = localizedPath('/use-cases/msp', locale);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.useCaseCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
5
apps/website/src/pages/evaluierung.astro
Normal file
5
apps/website/src/pages/evaluierung.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import EvaluationPage from '@components/pages/EvaluationPage.astro';
|
||||
---
|
||||
|
||||
<EvaluationPage locale="de" />
|
||||
@ -250,6 +250,33 @@ const canonicalPath = localizedPath('/use-cases/mittelstand', locale);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.useCaseCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
@ -250,6 +250,33 @@ const canonicalPath = localizedPath('/use-cases/msp', locale);
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div
|
||||
class="rounded-[2rem] border border-neutral-300 bg-linear-to-br from-neutral-100 to-yellow-100/60 p-6 md:p-10 dark:border-neutral-700 dark:from-neutral-900 dark:to-neutral-800"
|
||||
>
|
||||
<div class="max-w-(--breakpoint-md)">
|
||||
<h2
|
||||
class="text-2xl font-bold text-balance text-neutral-800 md:text-3xl dark:text-neutral-200"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseTitle}
|
||||
</h2>
|
||||
<p
|
||||
class="mt-3 max-w-prose text-pretty text-neutral-600 md:text-lg dark:text-neutral-400"
|
||||
>
|
||||
{siteCopy[locale].evaluation.discovery.useCaseContent}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<SecondaryCTA
|
||||
title={siteCopy[locale].evaluation.discovery.useCaseCta}
|
||||
url={localizeHref(siteCopy[locale].evaluation.routePath, locale)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
|
||||
@ -458,6 +458,89 @@ for (const { route, linkName, href, targetHeading } of [
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, linkName, href, targetHeading } of [
|
||||
{
|
||||
route: '/',
|
||||
linkName: 'Evaluierung & Pilot ansehen',
|
||||
href: '/evaluierung',
|
||||
targetHeading:
|
||||
/Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
},
|
||||
{
|
||||
route: '/platform',
|
||||
linkName: 'Evaluierung & Rollout ansehen',
|
||||
href: '/evaluierung',
|
||||
targetHeading:
|
||||
/Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
},
|
||||
{
|
||||
route: '/platform/review-packs',
|
||||
linkName: 'Evaluierungspfad ansehen',
|
||||
href: '/evaluierung',
|
||||
targetHeading:
|
||||
/Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
},
|
||||
{
|
||||
route: '/trust',
|
||||
linkName: 'Evaluierung & Procurement ansehen',
|
||||
href: '/evaluierung',
|
||||
targetHeading:
|
||||
/Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
},
|
||||
{
|
||||
route: '/use-cases/msp',
|
||||
linkName: 'Evaluierung & Pilot planen',
|
||||
href: '/evaluierung',
|
||||
targetHeading:
|
||||
/Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
},
|
||||
{
|
||||
route: '/en/',
|
||||
linkName: 'See evaluation and pilot',
|
||||
href: '/en/evaluation',
|
||||
targetHeading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
},
|
||||
{
|
||||
route: '/en/platform',
|
||||
linkName: 'See evaluation and rollout',
|
||||
href: '/en/evaluation',
|
||||
targetHeading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
},
|
||||
{
|
||||
route: '/en/platform/review-packs',
|
||||
linkName: 'See the evaluation path',
|
||||
href: '/en/evaluation',
|
||||
targetHeading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
},
|
||||
{
|
||||
route: '/en/trust',
|
||||
linkName: 'See evaluation and procurement',
|
||||
href: '/en/evaluation',
|
||||
targetHeading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
},
|
||||
{
|
||||
route: '/en/use-cases/msp',
|
||||
linkName: 'Plan evaluation and pilot',
|
||||
href: '/en/evaluation',
|
||||
targetHeading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
},
|
||||
] as const) {
|
||||
test(`${route} clicks through to the evaluation page`, async ({ page }) => {
|
||||
await page.goto(route);
|
||||
|
||||
await page
|
||||
.getByRole('link', { name: linkName, exact: true })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await expect(page).toHaveURL(new RegExp(`${href}/?$`));
|
||||
await expect(
|
||||
page.getByRole('heading', { name: targetHeading })
|
||||
).toBeVisible();
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, heading, contactHref } of [
|
||||
{
|
||||
route: '/platform/review-packs',
|
||||
@ -483,6 +566,34 @@ for (const { route, heading, contactHref } of [
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, heading, contactHref } of [
|
||||
{
|
||||
route: '/evaluierung',
|
||||
heading: /Tenantial sicher evaluieren und schneller zum Pilot kommen/i,
|
||||
contactHref: '/contact',
|
||||
},
|
||||
{
|
||||
route: '/en/evaluation',
|
||||
heading: /Evaluate Tenantial and get to a focused pilot faster/i,
|
||||
contactHref: '/en/contact',
|
||||
},
|
||||
] as const) {
|
||||
test(`${route} keeps the evaluation page actionable and readable`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(route);
|
||||
|
||||
await expect(page.getByRole('heading', { name: heading })).toBeVisible();
|
||||
await expect(
|
||||
page.locator(`main a[href="${contactHref}"]`).first()
|
||||
).toBeVisible();
|
||||
|
||||
await page.locator(`main a[href="${contactHref}"]`).first().click();
|
||||
await expect(page).toHaveURL(new RegExp(`${contactHref}/?$`));
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
}
|
||||
|
||||
test('reduced motion keeps preview pages understandable', async ({ page }) => {
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' });
|
||||
|
||||
@ -490,10 +601,12 @@ test('reduced motion keeps preview pages understandable', async ({ page }) => {
|
||||
'/',
|
||||
'/platform',
|
||||
'/platform/review-packs',
|
||||
'/evaluierung',
|
||||
'/pricing',
|
||||
'/use-cases/msp',
|
||||
'/use-cases/mittelstand',
|
||||
'/en/platform/review-packs',
|
||||
'/en/evaluation',
|
||||
] as const) {
|
||||
await page.goto(route);
|
||||
|
||||
@ -511,11 +624,13 @@ test.describe('without JavaScript', () => {
|
||||
'/',
|
||||
'/platform',
|
||||
'/platform/review-packs',
|
||||
'/evaluierung',
|
||||
'/contact',
|
||||
'/trust',
|
||||
'/use-cases/msp',
|
||||
'/use-cases/mittelstand',
|
||||
'/en/platform/review-packs',
|
||||
'/en/evaluation',
|
||||
'/en/trust',
|
||||
'/en/use-cases/msp',
|
||||
'/en/use-cases/mittelstand',
|
||||
|
||||
@ -47,6 +47,11 @@ const routeMetadata = {
|
||||
description:
|
||||
/(?=.*Review Packs)(?=.*Evidence)(?=.*Accepted Risks)(?=.*Decision Summaries)(?=.*Service-Reviews)(?=.*Audit-Vorbereitung)/i,
|
||||
},
|
||||
'/evaluierung': {
|
||||
title: /Evaluierung & Rollout \| Tenantial/i,
|
||||
description:
|
||||
/Microsoft-365-Governance sichtbarer|Reviews beschleunigt|fokussierten Pilot/i,
|
||||
},
|
||||
'/pricing': {
|
||||
title: /Preise \| Tenantial/i,
|
||||
description: /Policy-Governance-Evaluierung|Rollout-Planung/i,
|
||||
@ -119,6 +124,11 @@ const routeMetadata = {
|
||||
description:
|
||||
/(?=.*Review Packs)(?=.*evidence)(?=.*accepted risks)(?=.*decision summaries)(?=.*service reviews)(?=.*audit preparation)/i,
|
||||
},
|
||||
'/en/evaluation': {
|
||||
title: /Evaluation & Rollout \| Tenantial/i,
|
||||
description:
|
||||
/Microsoft 365 governance clearer|speeds up reviews|focused pilot/i,
|
||||
},
|
||||
'/en/pricing': {
|
||||
title: /Pricing \| Tenantial/i,
|
||||
description: /policy-governance evaluation|rollout planning/i,
|
||||
@ -423,6 +433,151 @@ for (const { route, linkName, href, footerHref } of [
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, linkName, href, footerName, footerHref } of [
|
||||
{
|
||||
route: '/',
|
||||
linkName: 'Evaluierung & Pilot ansehen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/platform',
|
||||
linkName: 'Evaluierung & Rollout ansehen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/platform/review-packs',
|
||||
linkName: 'Evaluierungspfad ansehen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/trust',
|
||||
linkName: 'Evaluierung & Procurement ansehen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/use-cases/msp',
|
||||
linkName: 'Evaluierung & Pilot planen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/use-cases/mittelstand',
|
||||
linkName: 'Evaluierung & Pilot planen',
|
||||
href: '/evaluierung',
|
||||
footerName: 'Evaluierung',
|
||||
footerHref: '/evaluierung',
|
||||
},
|
||||
{
|
||||
route: '/en/',
|
||||
linkName: 'See evaluation and pilot',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
{
|
||||
route: '/en/platform',
|
||||
linkName: 'See evaluation and rollout',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
{
|
||||
route: '/en/platform/review-packs',
|
||||
linkName: 'See the evaluation path',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
{
|
||||
route: '/en/trust',
|
||||
linkName: 'See evaluation and procurement',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
{
|
||||
route: '/en/use-cases/msp',
|
||||
linkName: 'Plan evaluation and pilot',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
{
|
||||
route: '/en/use-cases/mittelstand',
|
||||
linkName: 'Plan evaluation and pilot',
|
||||
href: '/en/evaluation',
|
||||
footerName: 'Evaluation',
|
||||
footerHref: '/en/evaluation',
|
||||
},
|
||||
] as const) {
|
||||
test(`${route} exposes evaluation discovery through contextual and footer links`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(route);
|
||||
|
||||
await expect(
|
||||
page.getByRole('link', { name: linkName, exact: true }).first()
|
||||
).toHaveAttribute('href', href);
|
||||
await expect(
|
||||
page.getByRole('link', { name: footerName, exact: true }).last()
|
||||
).toHaveAttribute('href', footerHref);
|
||||
await expect(page.locator(`footer a[href="${footerHref}"]`)).toBeVisible();
|
||||
await expectNoPlaceholderLinks(page);
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, locale } of [
|
||||
{ route: '/evaluierung', locale: 'de' },
|
||||
{ route: '/en/evaluation', locale: 'en' },
|
||||
] as const) {
|
||||
test(`${route} renders the evaluation path conservatively`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(route);
|
||||
|
||||
const headingPattern =
|
||||
locale === 'de'
|
||||
? /(Evaluierungspfad|evaluieren|pilotieren)/i
|
||||
: /(evaluation path|Evaluate Tenantial|controlled demo)/i;
|
||||
await expect(page.locator('main')).toContainText(headingPattern);
|
||||
|
||||
const securityPattern =
|
||||
locale === 'de'
|
||||
? /(Security & Procurement|Procurement|Checkliste)/i
|
||||
: /(Security & procurement|procurement|checklist)/i;
|
||||
await expect(page.locator('main')).toContainText(securityPattern);
|
||||
|
||||
const accessPattern =
|
||||
locale === 'de'
|
||||
? /(Microsoft-365-Zugriff|Bereitschafts|Berechtigung)/i
|
||||
: /(Microsoft 365 access|readiness|permission)/i;
|
||||
await expect(page.locator('main')).toContainText(accessPattern);
|
||||
|
||||
const faqPattern = locale === 'de' ? /FAQ|Fragen/i : /FAQ|questions/i;
|
||||
await expect(page.locator('main')).toContainText(faqPattern);
|
||||
|
||||
const contactPath = locale === 'de' ? '/contact' : '/en/contact';
|
||||
await expect(
|
||||
page.locator(`main a[href="${contactPath}"]`).first()
|
||||
).toBeVisible();
|
||||
|
||||
await expectNoForbiddenPublicClaims(page);
|
||||
await expectNoProviderOrDataOverclaims(page);
|
||||
await expectNoFakeTrustDownloads(page);
|
||||
await expectNoPlaceholderLinks(page);
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
}
|
||||
|
||||
for (const { route, locale } of [
|
||||
{ route: '/trust', locale: 'de' },
|
||||
{ route: '/en/trust', locale: 'en' },
|
||||
|
||||
@ -6,6 +6,7 @@ export const renderedRoutes = [
|
||||
'/use-cases/mittelstand',
|
||||
'/platform',
|
||||
'/platform/review-packs',
|
||||
'/evaluierung',
|
||||
'/pricing',
|
||||
'/contact',
|
||||
'/trust',
|
||||
@ -23,6 +24,7 @@ export const renderedRoutes = [
|
||||
'/en/use-cases/mittelstand',
|
||||
'/en/platform',
|
||||
'/en/platform/review-packs',
|
||||
'/en/evaluation',
|
||||
'/en/pricing',
|
||||
'/en/contact',
|
||||
'/en/trust',
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
# Specification Quality Checklist: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
**Purpose**: Validate specification completeness and quality before proceeding to planning
|
||||
**Created**: 2026-05-30
|
||||
**Feature**: [spec.md](../spec.md)
|
||||
|
||||
## Content Quality
|
||||
|
||||
- [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
|
||||
|
||||
- Initial validation passed with no remaining clarification markers.
|
||||
- The spec stays bounded to the public website and keeps `apps/platform` explicitly out of scope.
|
||||
- Route selection remains intentionally flexible inside current IA, with `/evaluierung` or `/evaluation` recorded as the preferred destination depending on the active site language strategy.
|
||||
- CTA behavior is explicitly limited to real routes, real forms, or real mailto/contact destinations.
|
||||
- The spec is ready for `/speckit.plan`.
|
||||
|
||||
## Implementation Close-Out
|
||||
|
||||
- Routes shipped: `/evaluierung` (de) and `/en/evaluation` (en) via a shared `EvaluationPage.astro` component and centralized locale copy.
|
||||
- Validation: `build` Pass; `public-routes.spec.ts` Pass (362); `interaction.spec.ts` Pass (82, 6 project-scoped skips); static claim scans over `src`, `public`, and `dist` clean. Full results in [plan.md](../plan.md#validation-results-implementation).
|
||||
- Discovery: homepage, platform, review-pack, trust, both use-case surfaces, and footer link to the route; main-nav item intentionally omitted.
|
||||
- Scope: changes confined to `apps/website/**` and this feature's spec artifacts; `apps/platform/**` untouched.
|
||||
@ -0,0 +1,254 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: Tenantial Public Evaluation Readiness Routes
|
||||
version: 0.1.0
|
||||
description: >
|
||||
Static public website route contract for Spec 409. These routes return
|
||||
HTML pages only and do not expose platform runtime APIs, tenant data,
|
||||
onboarding state, procurement workflows, legal-document downloads, or
|
||||
trial-provisioning behavior.
|
||||
servers:
|
||||
- url: http://127.0.0.1:4321
|
||||
description: Local website preview using WEBSITE_PORT default
|
||||
paths:
|
||||
/evaluierung:
|
||||
get:
|
||||
summary: German public evaluation, procurement, and rollout-readiness page
|
||||
operationId: getGermanEvaluationReadinessPage
|
||||
tags:
|
||||
- Public Website
|
||||
responses:
|
||||
"200":
|
||||
description: Static HTML evaluation-readiness page
|
||||
content:
|
||||
text/html:
|
||||
schema:
|
||||
type: string
|
||||
examples:
|
||||
page:
|
||||
summary: Required visible content
|
||||
value: "Tenantial sicher evaluieren und kontrolliert pilotieren. Demo, Pilot-Scope, Provider-Berechtigungen und Trust-Fragen in einem belastbaren Ablauf."
|
||||
"404":
|
||||
description: Route not configured
|
||||
x-content-requirements:
|
||||
locale: de
|
||||
mustInclude:
|
||||
- Hero framing for safe evaluation and controlled pilot readiness
|
||||
- Evaluation path from discovery call to review and next step
|
||||
- Preparation section covering use case, scope, owner, security/privacy contact, review objective, and success criteria
|
||||
- Typical pilot scenarios for MSP, internal IT, backup/versioning, evidence/audit, and provider-permission readiness
|
||||
- Stakeholder section covering MSP, IT, Microsoft 365 admin, security, Datenschutz, and procurement roles
|
||||
- Security and procurement checklist with trust, AVV/DPA/TOM status, provider permissions, hosting/subprocessors, audit/retention, and commercial fit
|
||||
- Microsoft 365 access section describing read-oriented access, write or recovery-adjacent access, consent/admin-role readiness, and no blind execution
|
||||
- Boundary section explaining what the first evaluation does not require
|
||||
- Example timeline framed as non-guaranteed guidance
|
||||
- Buyer FAQ with direct, cautious answers
|
||||
- Final CTA with real destinations only
|
||||
- Real CTA destinations only
|
||||
mustNotInclude:
|
||||
- href="#"
|
||||
- procurement readiness website surface
|
||||
- productization gap
|
||||
- repo-real foundation
|
||||
- workspace-first route context
|
||||
- capability registry
|
||||
- provider-neutral artifact taxonomy
|
||||
- instant trial
|
||||
- self-service onboarding available
|
||||
- sofort kostenlos starten
|
||||
- DSGVO-konform
|
||||
- ISO-zertifiziert
|
||||
- NIS2-konform
|
||||
- garantiert auditbereit
|
||||
- automatic remediation
|
||||
- automatic restore
|
||||
- one-click restore
|
||||
- Google supported
|
||||
- AWS supported
|
||||
- no customer data stored
|
||||
- in Deutschland gehostet
|
||||
/en/evaluation:
|
||||
get:
|
||||
summary: English public evaluation, procurement, and rollout-readiness page
|
||||
operationId: getEnglishEvaluationReadinessPage
|
||||
tags:
|
||||
- Public Website
|
||||
responses:
|
||||
"200":
|
||||
description: Static HTML evaluation-readiness page
|
||||
content:
|
||||
text/html:
|
||||
schema:
|
||||
type: string
|
||||
examples:
|
||||
page:
|
||||
summary: Required visible content
|
||||
value: "Evaluate Tenantial through a controlled demo, focused pilot, and clear trust review path for Microsoft 365 governance."
|
||||
"404":
|
||||
description: Route not configured
|
||||
x-content-requirements:
|
||||
locale: en
|
||||
mustInclude:
|
||||
- Hero framing for safe evaluation and controlled pilot readiness
|
||||
- Evaluation path from discovery call to review and next step
|
||||
- Preparation section covering use case, scope, owner, security/privacy contact, review objective, and success criteria
|
||||
- Typical pilot scenarios for MSP, internal IT, backup/versioning, evidence/audit, and provider-permission readiness
|
||||
- Stakeholder section covering MSP, IT, Microsoft 365 admin, security, privacy, and procurement roles
|
||||
- Security and procurement checklist with trust, AVV/DPA/TOM status, provider permissions, hosting/subprocessors, audit/retention, and commercial fit
|
||||
- Microsoft 365 access section describing read-oriented access, write or recovery-adjacent access, consent/admin-role readiness, and no blind execution
|
||||
- Boundary section explaining what the first evaluation does not require
|
||||
- Example timeline framed as non-guaranteed guidance
|
||||
- Buyer FAQ with direct, cautious answers
|
||||
- Final CTA with real destinations only
|
||||
- Real CTA destinations only
|
||||
mustNotInclude:
|
||||
- href="#"
|
||||
- procurement readiness website surface
|
||||
- productization gap
|
||||
- repo-real foundation
|
||||
- workspace-first route context
|
||||
- capability registry
|
||||
- provider-neutral artifact taxonomy
|
||||
- instant trial
|
||||
- self-service onboarding available
|
||||
- DSGVO-konform
|
||||
- ISO-zertifiziert
|
||||
- NIS2-konform
|
||||
- guaranteed audit readiness
|
||||
- automatic remediation
|
||||
- automatic restore
|
||||
- one-click restore
|
||||
- Google supported
|
||||
- AWS supported
|
||||
- no customer data stored
|
||||
- hosted in Germany
|
||||
components:
|
||||
schemas:
|
||||
EvaluationPathStep:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- discovery-call
|
||||
- product-walkthrough
|
||||
- security-privacy-review
|
||||
- technical-readiness-check
|
||||
- focused-pilot
|
||||
- review-next-step
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
PreparationCard:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- use-case
|
||||
- microsoft-365-scope
|
||||
- technical-owner
|
||||
- security-privacy-contact
|
||||
- review-objective
|
||||
- success-criteria
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
PilotScenarioCard:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- msp-customer-review
|
||||
- internal-it-governance
|
||||
- policy-backup-versioning
|
||||
- evidence-audit-preparation
|
||||
- provider-permission-readiness
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
StakeholderCard:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- msp-service-owner
|
||||
- msp-operator
|
||||
- it-leadership
|
||||
- microsoft-365-admin
|
||||
- security
|
||||
- datenschutz-dpo
|
||||
- procurement-vendor-management
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
SecurityChecklistItem:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- trust-privacy
|
||||
- avv-dpa-tom
|
||||
- provider-permissions
|
||||
- hosting-subprocessors
|
||||
- audit-retention
|
||||
- commercial-fit
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
AccessPrinciple:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- title
|
||||
- content
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
enum:
|
||||
- read-oriented-access
|
||||
- write-recovery-adjacent-access
|
||||
- consent-admin-roles
|
||||
- no-blind-execution
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
BuyerFaqItem:
|
||||
type: object
|
||||
required:
|
||||
- question
|
||||
- answer
|
||||
properties:
|
||||
question:
|
||||
type: string
|
||||
answer:
|
||||
type: string
|
||||
278
specs/409-evaluation-procurement-rollout/data-model.md
Normal file
278
specs/409-evaluation-procurement-rollout/data-model.md
Normal file
@ -0,0 +1,278 @@
|
||||
# Data Model: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
This feature has no persisted data model. The entities below are static website content structures used to render a public evaluation-readiness route. They must remain content-only unless a later spec introduces runtime onboarding, procurement workflow, or legal/security document delivery truth.
|
||||
|
||||
## Evaluation Readiness Page
|
||||
|
||||
**Represents**: The localized public page explaining how Tenantial is evaluated, piloted, reviewed, and prepared for controlled rollout.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `locale`: `de` or `en`
|
||||
- `pageTitle`: localized metadata title
|
||||
- `metaDescription`: localized metadata description
|
||||
- `heroTitle`: main H1
|
||||
- `heroSubtitle`: primary supporting paragraph
|
||||
- `supportingLine`: short context line for demo, pilot, and trust readiness
|
||||
- `primaryCta`: primary CTA label and route
|
||||
- `secondaryCta`: supporting CTA label and route
|
||||
- `tertiaryCta`: optional trust CTA label and route
|
||||
- `evaluationSteps`: ordered evaluation-path steps
|
||||
- `preparationCards`: checklist-style preparation cards
|
||||
- `pilotScenarios`: typical pilot-scope cards
|
||||
- `stakeholderCards`: buyer and reviewer roles
|
||||
- `securityChecklist`: security/procurement review points
|
||||
- `accessPrinciples`: Microsoft 365 access-readiness principles
|
||||
- `nonRequirementCards`: what the first evaluation does not require
|
||||
- `timelineEntries`: example evaluation timeline
|
||||
- `faqItems`: buyer FAQ entries
|
||||
- `finalCtas`: final conversion CTA set
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- `pageTitle` and `metaDescription` must not claim compliance certification, German hosting, automatic remediation, automatic restore, one-click restore, or unsupported providers.
|
||||
- Every CTA destination must be a real route or real contact destination.
|
||||
- The page must contain hero, evaluation path, preparation, pilot scenarios, stakeholders, security/procurement, Microsoft 365 access, non-requirements, timeline, FAQ, and final CTA sections.
|
||||
- The page must not contain `href="#"`.
|
||||
|
||||
## Evaluation Path Step
|
||||
|
||||
**Represents**: One visible step in the buyer journey from first conversation to next-step decision.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible step label
|
||||
- `content`: buyer-facing explanation
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- discovery-call
|
||||
- product-walkthrough
|
||||
- security-privacy-review
|
||||
- technical-readiness-check
|
||||
- focused-pilot
|
||||
- review-next-step
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Steps must explain buyer flow in public language, not internal runtime vocabulary.
|
||||
- The sequence must make clear that Tenantial is not introduced blindly into production.
|
||||
|
||||
## Preparation Card
|
||||
|
||||
**Represents**: One item a buyer should prepare before or during evaluation.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible card title
|
||||
- `content`: short preparation guidance
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- use-case
|
||||
- microsoft-365-scope
|
||||
- technical-owner
|
||||
- security-privacy-contact
|
||||
- review-objective
|
||||
- success-criteria
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Cards must stay practical and organizational, not prescriptive about unverified runtime setup.
|
||||
- Cards must reinforce that the evaluation can start small.
|
||||
|
||||
## Pilot Scenario Card
|
||||
|
||||
**Represents**: One typical bounded pilot scenario.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible card title
|
||||
- `content`: buyer-facing description
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- msp-customer-review
|
||||
- internal-it-governance
|
||||
- policy-backup-versioning
|
||||
- evidence-audit-preparation
|
||||
- provider-permission-readiness
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Cards must describe examples, not guaranteed packaged offerings.
|
||||
- Cards must not imply that every scenario is fully automated today.
|
||||
|
||||
## Stakeholder Card
|
||||
|
||||
**Represents**: One role that should be involved in the evaluation.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible role label
|
||||
- `content`: what this role evaluates
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- msp-service-owner
|
||||
- msp-operator
|
||||
- it-leadership
|
||||
- microsoft-365-admin
|
||||
- security
|
||||
- datenschutz-dpo
|
||||
- procurement-vendor-management
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Cards must explain why the evaluation is not purely technical and not purely commercial.
|
||||
- Role labels must stay buyer-facing and avoid internal architecture jargon.
|
||||
|
||||
## Security / Procurement Checklist Item
|
||||
|
||||
**Represents**: One trust, privacy, or procurement review point.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible item title
|
||||
- `content`: bounded explanation of what is reviewed
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- trust-privacy
|
||||
- avv-dpa-tom
|
||||
- provider-permissions
|
||||
- hosting-subprocessors
|
||||
- audit-retention
|
||||
- commercial-fit
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Items must describe status review or request-based handoff, not fake downloadable artifacts.
|
||||
- Items must not imply completed legal approval where current truth is unverified.
|
||||
|
||||
## Access Principle
|
||||
|
||||
**Represents**: One buyer-facing principle for Microsoft 365 access readiness.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible principle title
|
||||
- `content`: explanation of the principle
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- read-oriented-access
|
||||
- write-recovery-adjacent-access
|
||||
- consent-admin-roles
|
||||
- no-blind-execution
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Principles must stay at scope-dependent readiness level.
|
||||
- Principles must not publish an exact Microsoft Graph permission matrix unless separately verified.
|
||||
|
||||
## Non-Requirement Card
|
||||
|
||||
**Represents**: One thing the first evaluation does not require.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible label
|
||||
- `content`: explanation of the boundary
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- no-big-bang-rollout
|
||||
- no-admin-center-replacement
|
||||
- no-helpdesk-switch
|
||||
- no-automatic-remediation
|
||||
- no-fake-compliance
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Cards must reduce buyer fear without weakening the trust boundary.
|
||||
- Cards must not drift into dismissive or vague wording.
|
||||
|
||||
## Timeline Entry
|
||||
|
||||
**Represents**: One example phase in the evaluation timeline.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `key`: stable content key
|
||||
- `title`: visible phase label
|
||||
- `content`: short explanation
|
||||
|
||||
**Required rows**:
|
||||
|
||||
- orientation
|
||||
- technical-review
|
||||
- pilot
|
||||
- wrap-up-review
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- The set must be framed as an example timeline rather than a guaranteed delivery promise.
|
||||
|
||||
## Buyer FAQ Item
|
||||
|
||||
**Represents**: One buyer-facing frequently asked question and answer.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `question`: visible question
|
||||
- `answer`: direct buyer-facing answer
|
||||
|
||||
**Required coverage**:
|
||||
|
||||
- productive-tenant-needed
|
||||
- required-permissions
|
||||
- avv-tom-status
|
||||
- admin-center-replacement
|
||||
- helpdesk-or-psa
|
||||
- automatic-changes
|
||||
- provider-scope
|
||||
- compliance-boundary
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Answers must stay direct and cautious.
|
||||
- Answers must not claim guaranteed compliance, automation, or unsupported provider coverage.
|
||||
|
||||
## Discovery Link
|
||||
|
||||
**Represents**: A public-site entry point to the evaluation page.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `label`: visible link label
|
||||
- `href`: localized route
|
||||
- `placement`: homepage, platform page, trust page, use-case page, review-pack page, or footer
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- `href` must resolve to a real route.
|
||||
- Links must follow the current locale strategy.
|
||||
- Discovery surfaces must stay light and must not require a main-nav refactor.
|
||||
|
||||
## Metadata Contract
|
||||
|
||||
**Represents**: The route title and description for the new public page.
|
||||
|
||||
**Fields**:
|
||||
|
||||
- `title`
|
||||
- `description`
|
||||
- `canonicalPath`
|
||||
|
||||
**Validation rules**:
|
||||
|
||||
- Metadata must mention evaluation, demo, pilot, security review, privacy questions, provider permissions, or rollout readiness safely.
|
||||
- Metadata must not claim `DSGVO-konform`, `ISO-zertifiziert`, `NIS2-konform`, `automatic remediation`, `automatic restore`, `one-click restore`, `Google supported`, or `AWS supported`.
|
||||
290
specs/409-evaluation-procurement-rollout/plan.md
Normal file
290
specs/409-evaluation-procurement-rollout/plan.md
Normal file
@ -0,0 +1,290 @@
|
||||
# Implementation Plan: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
**Branch**: `409-evaluation-procurement-rollout` | **Date**: 2026-05-30 | **Spec**: [spec.md](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**: `siteCopy` locale 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 in `apps/website/src/components/pages`, and `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
- **New abstraction introduced? why?**: none beyond one bounded `EvaluationPage.astro` component 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 build`
|
||||
- `corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts`
|
||||
- `corepack 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/website` plus 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)
|
||||
|
||||
```text
|
||||
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)
|
||||
|
||||
```text
|
||||
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 `/trust` with `/en/*` counterparts.
|
||||
- `/platform/review-packs` is 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 `/evaluierung` fits the site’s German-first public surface while `/en/evaluation` keeps 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.
|
||||
- `/start` or `/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: `/contact` and `/en/contact`
|
||||
- Trust handoff: `/trust` and `/en/trust`
|
||||
- Product context: `/platform` and `/en/platform`
|
||||
- Adjacent story context: `/platform/review-packs`, `/use-cases/msp`, and `/use-cases/mittelstand` plus locale equivalents when those links are surfaced
|
||||
|
||||
Reasoning:
|
||||
|
||||
- Existing public CTA patterns already use `/contact` as 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 anfragen` should 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.ts` under one dedicated `evaluation` section 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 || true`
|
||||
- `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/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 with `prettier --write` and are clean.
|
||||
- `corepack pnpm --filter @tenantatlas/website build` — Pass (`astro check` + `astro build` + `process-html.mjs`); both `/evaluierung` and `/en/evaluation` are 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/src` and `apps/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 `/evaluierung` and `/en/evaluation` were 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 `/evaluierung` and EN `/evaluation` use different slugs, which broke the shared `LanguagePicker` and `Meta.astro` hreflang/x-default alternates (they naively prefixed `/en`). A centralized `localizeRoutePath(strippedPath, fromLocale, toLocale)` helper with a `slugAliasGroups` map was added in `apps/website/src/i18n.ts` and adopted by `LanguagePicker.astro` and `Meta.astro` so 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 `/contact` with "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-only` shows changes confined to `apps/website/**` and `specs/409-evaluation-procurement-rollout/**` (plus the standard auto-updated `.github/agents/copilot-instructions.md` agent-context file). `apps/platform/**` remained untouched.
|
||||
|
||||
### Quickstart validation
|
||||
|
||||
- `specs/409-evaluation-procurement-rollout/quickstart.md` steps (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.
|
||||
206
specs/409-evaluation-procurement-rollout/quickstart.md
Normal file
206
specs/409-evaluation-procurement-rollout/quickstart.md
Normal file
@ -0,0 +1,206 @@
|
||||
# Quickstart: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
## 1. Confirm Scope
|
||||
|
||||
Work from repository root:
|
||||
|
||||
```bash
|
||||
cd /Users/ahmeddarrazi/Documents/projects/wt-website
|
||||
pwd
|
||||
git status --short --branch
|
||||
cat package.json
|
||||
cat pnpm-workspace.yaml 2>/dev/null || true
|
||||
cat apps/website/package.json
|
||||
find apps/website -maxdepth 3 -type f | sort | sed -n '1,280p'
|
||||
```
|
||||
|
||||
Scope boundaries:
|
||||
|
||||
- Allowed: `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/**`
|
||||
- Allowed: `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/409-evaluation-procurement-rollout/**`
|
||||
- Forbidden: `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform/**`
|
||||
- Forbidden: root workspace script contract changes
|
||||
|
||||
## 2. Implement The Route
|
||||
|
||||
Preferred routes:
|
||||
|
||||
- `/evaluierung`
|
||||
- `/en/evaluation`
|
||||
|
||||
Expected files:
|
||||
|
||||
```text
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/evaluierung.astro
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/en/evaluation.astro
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/components/pages/EvaluationPage.astro
|
||||
```
|
||||
|
||||
Follow the existing thin-route plus shared-page-component pattern used by `TrustPage.astro`, `ContactPage.astro`, and `PricingPage.astro`.
|
||||
|
||||
## 3. Add Localized Content
|
||||
|
||||
Use the existing copy file:
|
||||
|
||||
```text
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/data_files/site-copy.ts
|
||||
```
|
||||
|
||||
Add German and English evaluation copy with:
|
||||
|
||||
- page metadata
|
||||
- hero copy and CTA labels
|
||||
- evaluation path steps
|
||||
- preparation cards
|
||||
- pilot scenario cards
|
||||
- stakeholder cards
|
||||
- security/procurement checklist items
|
||||
- Microsoft 365 access principles
|
||||
- non-requirement cards
|
||||
- example timeline
|
||||
- FAQ entries
|
||||
- final CTA labels and routes
|
||||
|
||||
## 4. Keep Discovery Contextual
|
||||
|
||||
Preferred discovery surfaces:
|
||||
|
||||
- homepage teaser
|
||||
- compact platform-page teaser
|
||||
- review-pack page crosslink
|
||||
- MSP use-case crosslink
|
||||
- Mittelstand / Enterprise IT use-case crosslink
|
||||
- footer link
|
||||
|
||||
Do not add a main-nav item unless implementation proves the current IA still reads cleanly.
|
||||
|
||||
## 5. Keep CTA Targets Real
|
||||
|
||||
Preferred CTA targets:
|
||||
|
||||
- `/contact` or `/en/contact` for `Demo buchen`, `Pilot anfragen`, and `Security-Unterlagen anfragen`
|
||||
- `/trust` or `/en/trust` for trust/privacy handoff
|
||||
- `/platform` or `/en/platform` for product-context fallback
|
||||
|
||||
Do not introduce:
|
||||
|
||||
- `href="#"`
|
||||
- fake calendar widgets
|
||||
- fake AVV/TOM downloads
|
||||
- fake security-pack downloads
|
||||
- fake procurement or trial portals
|
||||
|
||||
## 6. Keep Claims Conservative
|
||||
|
||||
Do not introduce hard claims for:
|
||||
|
||||
- instant trial
|
||||
- self-service onboarding
|
||||
- automated provisioning
|
||||
- `DSGVO-konform`
|
||||
- `ISO-zertifiziert`
|
||||
- `NIS2-konform`
|
||||
- `in Deutschland gehostet`
|
||||
- `no customer data stored`
|
||||
- Google/AWS support
|
||||
- automatic remediation
|
||||
- automatic restore
|
||||
- one-click restore
|
||||
|
||||
Prefer wording like:
|
||||
|
||||
- `evaluieren`
|
||||
- `anfragen`
|
||||
- `Status klären`
|
||||
- `je nach Pilot-Scope`
|
||||
- `kontrollierter Rollout`
|
||||
|
||||
## 7. Update Smoke Coverage
|
||||
|
||||
Expected test updates:
|
||||
|
||||
```text
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/public-routes.spec.ts
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/interaction.spec.ts
|
||||
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/smoke-helpers.ts
|
||||
```
|
||||
|
||||
Cover:
|
||||
|
||||
- `/evaluierung`
|
||||
- `/en/evaluation`
|
||||
- metadata for both routes
|
||||
- homepage/platform/review-pack/use-case/footer discovery links as implemented
|
||||
- no placeholder links
|
||||
- no forbidden public claims
|
||||
- no horizontal overflow
|
||||
- readable desktop/mobile layout
|
||||
|
||||
## 8. Run Validation
|
||||
|
||||
Run only scripts that currently exist:
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @tenantatlas/website build
|
||||
corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts
|
||||
corepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts
|
||||
```
|
||||
|
||||
Optional if formatting was touched broadly:
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @tenantatlas/website format:check
|
||||
```
|
||||
|
||||
Run the static scan from the plan against source:
|
||||
|
||||
```bash
|
||||
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 || true
|
||||
```
|
||||
|
||||
If generated output is committed, scan `apps/website/dist` as well.
|
||||
|
||||
## 9. Browser Smoke
|
||||
|
||||
If local preview is available:
|
||||
|
||||
```bash
|
||||
WEBSITE_PORT=${WEBSITE_PORT:-4321} corepack pnpm --filter @tenantatlas/website preview
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
- `/evaluierung` loads
|
||||
- `/en/evaluation` loads
|
||||
- homepage/platform/review-pack/use-case/footer links work if implemented
|
||||
- trust CTA points to a real route
|
||||
- evaluation path is understandable
|
||||
- pilot preparation is understandable
|
||||
- Microsoft 365 access section is understandable
|
||||
- FAQ is buyer-friendly
|
||||
- no fake downloads, fake forms, or fake calendar widgets appear
|
||||
- no false legal, provider, or runtime claims appear
|
||||
- desktop and mobile layouts remain readable
|
||||
99
specs/409-evaluation-procurement-rollout/research.md
Normal file
99
specs/409-evaluation-procurement-rollout/research.md
Normal file
@ -0,0 +1,99 @@
|
||||
# Research: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
## Decision: Use `/evaluierung` and `/en/evaluation`
|
||||
|
||||
**Rationale**: The current public website already uses root-level buyer and commercial routes such as `/contact`, `/pricing`, and `/trust`, with English counterparts under `/en/*`. The evaluation journey spans demo, pilot, trust, and procurement readiness rather than one product feature, so it fits the top-level buyer-route family better than a nested `/platform/*` path.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- `/platform/evaluation`: too tightly nested under product detail for a broader buyer-readiness flow.
|
||||
- `/procurement`: too narrow relative to evaluation and rollout readiness.
|
||||
- `/start` or `/demo-pilot`: weaker SEO and weaker alignment with the existing public route family.
|
||||
|
||||
## Decision: Reuse the localized thin-route plus shared-page-component pattern
|
||||
|
||||
**Rationale**: Existing public pages already use thin locale route files plus shared page components, for example `platform.astro`, `trust.astro`, `contact.astro`, and their English wrappers. The evaluation page is section-heavy in both German and English, so one shared `EvaluationPage.astro` is the narrowest way to avoid duplicating large amounts of markup.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Duplicate full German and English route markup: acceptable, but repetitive and harder to maintain.
|
||||
- MDX/docs content route: mismatched with the current marketing-page CTA and metadata pattern.
|
||||
- Inline-only homepage or platform section: weaker SEO, weaker smoke coverage, and weaker discoverability.
|
||||
|
||||
## Decision: Keep all localized page copy in `site-copy.ts`
|
||||
|
||||
**Rationale**: The website already centralizes public copy, metadata, navigation labels, footer links, homepage copy, platform copy, trust copy, review-pack copy, and use-case copy in `apps/website/src/data_files/site-copy.ts`. Adding a dedicated `evaluation` section there keeps the new page aligned with the existing locale strategy and avoids a second content source.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Page-local constants: simpler for one file, but weaker for German/English parity and CTA consistency.
|
||||
- Separate JSON or YAML content file: splits public copy away from the current marketing-content source of truth.
|
||||
- Runtime content source or CMS: out of scope for a website-only feature.
|
||||
|
||||
## Decision: Use `/contact` as the real conversion path for demo, pilot, and security-document requests
|
||||
|
||||
**Rationale**: The existing public site already routes buyer-facing demo and walkthrough CTAs to `/contact` and `/en/contact`. The current public CTA pattern is route-based rather than `mailto:`-based, so `Demo buchen`, `Pilot anfragen`, and `Security-Unterlagen anfragen` should all map to the same real contact destination unless implementation discovers another real route.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- `mailto:` links: technically possible, but not the prevailing public CTA pattern.
|
||||
- Fake demo-booking widget: explicitly forbidden.
|
||||
- New dedicated request form route: out of scope unless it already exists.
|
||||
|
||||
## Decision: Keep discovery contextual and global, but skip a new main-nav item
|
||||
|
||||
**Rationale**: The current main nav is already dense. The stronger discovery path is contextual: homepage teaser, platform-page teaser, review-pack page crosslink, MSP page crosslink, Mittelstand page crosslink, and a footer link for global reachability.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Main-nav item: globally visible, but too expensive for current IA density.
|
||||
- Footer only: too weak for a commercially important page.
|
||||
- Homepage/platform only: helpful, but weaker for audience-specific discovery.
|
||||
|
||||
## Decision: Reuse existing smoke helpers and route metadata inventory as the narrowest proof
|
||||
|
||||
**Rationale**: `apps/website/tests/smoke/public-routes.spec.ts` and `apps/website/tests/smoke/smoke-helpers.ts` already validate route rendering, metadata, placeholder-link bans, forbidden public claims, trust handoffs, and layout stability. Extending those tests is the narrowest proof for this feature.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Manual-only browser review: insufficient for metadata and claim-guardrail regressions.
|
||||
- New unit tests for copy objects: more brittle than public-route smoke for this use case.
|
||||
- Platform-side tests: wrong layer because `apps/platform` is explicitly out of scope.
|
||||
|
||||
## Decision: Use only existing website commands for validation
|
||||
|
||||
**Rationale**: `apps/website/package.json` currently exposes `build`, `test`, `test:smoke`, `format:check`, and `preview`. The plan must not invent a `check` script because `astro check` already runs inside `build`.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- `pnpm --filter @tenantatlas/website check`: not present.
|
||||
- Root script changes: out of scope and would break workspace contracts.
|
||||
- Platform/Sail validation: wrong scope for a static website-only page.
|
||||
|
||||
## Decision: Treat static claim scans as implementation blockers
|
||||
|
||||
**Rationale**: The main risk in this feature is overclaiming rather than runtime breakage. Static scans over `apps/website/src`, `apps/website/public`, and optionally `apps/website/dist` should block placeholder links, internal architecture jargon, false legal or provider claims, fake self-service promises, and invented downloads.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Code review only: too easy to miss metadata or generated-output regressions.
|
||||
- New custom linter: too heavy for one bounded website feature.
|
||||
- Placeholder-link scan only: insufficient because the main risk is claim language.
|
||||
|
||||
## Decision: Reuse existing trust and review-story routes as adjacent handoffs
|
||||
|
||||
**Rationale**: `/trust`, `/en/trust`, `/platform/review-packs`, and their locale-aware discovery surfaces already exist today. They are the safest real destinations for trust, security, privacy, and review-story follow-up questions from the new page.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Omit trust and review crosslinks: safer, but weaker than the spec goal of connecting evaluation readiness to adjacent proof surfaces.
|
||||
- Invent a security-pack download or procurement portal route: explicitly forbidden.
|
||||
|
||||
## Decision: Keep the docs evaluation checklist as documentation, not as the feature route
|
||||
|
||||
**Rationale**: The docs route `/guides/first-project-checklist/` already touches evaluation language, but it is a documentation asset rather than a buyer-facing public conversion page. The new route should sit in the marketing/site IA, not inside docs.
|
||||
|
||||
**Alternatives considered**:
|
||||
|
||||
- Reusing the docs route as the public destination: wrong tone, weaker CTA handling, and weaker buyer-path visibility.
|
||||
- Linking only to docs from existing marketing pages: too indirect for the primary sales goal.
|
||||
339
specs/409-evaluation-procurement-rollout/spec.md
Normal file
339
specs/409-evaluation-procurement-rollout/spec.md
Normal file
@ -0,0 +1,339 @@
|
||||
# Feature Specification: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
**Feature Branch**: `409-evaluation-procurement-rollout`
|
||||
**Created**: 2026-05-30
|
||||
**Status**: Draft
|
||||
**Input**: User description: "Create a public website page that explains how MSPs and Enterprise IT can evaluate, procure, and roll out Tenantial through a structured demo, pilot, security review, and rollout-readiness path without any `apps/platform` runtime changes."
|
||||
|
||||
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
|
||||
|
||||
- **Problem**: Public buyers still lack one concrete public page that explains how Tenantial is evaluated, reviewed internally, piloted, and prepared for controlled rollout.
|
||||
- **Today's failure**: After the homepage, trust, provider taxonomy, use-case pages, and review/evidence story, prospects still need to ask the same manual questions about demos, pilot scope, Microsoft 365 access, security/privacy review, and procurement readiness.
|
||||
- **User-visible improvement**: A first-time MSP, IT lead, security reviewer, Datenschutz contact, or procurement stakeholder can understand in one visit how to start, what to prepare, which questions matter, and what Tenantial does not promise.
|
||||
- **Smallest enterprise-capable version**: One dedicated public website page, lightweight discoverability from existing IA, page-specific metadata, real CTA routing only, and explicit claim boundaries around demo, pilot, trust, security review, and rollout readiness.
|
||||
- **Explicit non-goals**: No `apps/platform` changes, no onboarding runtime, no CRM, no billing, no trial provisioning, no Microsoft consent runtime, no Graph permission logic, no legal document generation, no fake AVV/TOM downloads, no fake security-pack downloads, no fake calendar booking, no fake customer logos, and no placeholder routes or links.
|
||||
- **Permanent complexity imported**: One bounded public page, optional lightweight homepage/platform/trust/use-case/review discovery, public metadata updates, CTA/link guardrails, and copy-review obligations. No models, persistence, runtime abstractions, or product-state machinery are introduced.
|
||||
- **Why now**: Specs 404 through 408 established public positioning, trust, provider scope, audience-specific use cases, and the review/evidence story. The remaining commercial friction is the practical evaluation, procurement, and rollout-readiness path.
|
||||
- **Why not local**: Small copy additions on existing pages would keep the buyer journey fragmented across trust, use-case, and review surfaces and would not answer evaluation-readiness questions in one coherent destination.
|
||||
- **Approval class**: Core Enterprise.
|
||||
- **Red flags triggered**: Public overclaim risk, legal/security/procurement promise boundary, IA touch across multiple public entry points, and Microsoft 365 access wording that could drift into unverified permission claims.
|
||||
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 11/12**
|
||||
- **Decision**: approve.
|
||||
|
||||
### Red Flag Defense
|
||||
|
||||
This spec is intentionally limited to a buyer-readiness page on the public website. It improves sales and evaluation clarity without pretending that trial provisioning, procurement automation, legal downloads, or security workflows already exist as self-service product truth. The scope stays inside one bounded page plus existing public discovery surfaces.
|
||||
|
||||
## Scope
|
||||
|
||||
This spec defines one dedicated public website page that explains how MSPs and Enterprise IT teams can evaluate Tenantial through a controlled demo, pilot, security/privacy review, and rollout-readiness path.
|
||||
|
||||
- **Relevant application for later implementation**: public website only
|
||||
- **Depends on**: Spec 404 - Public Website Sales Copy & Positioning Rewrite; Spec 405 - DACH Trust, Datenschutz & Security Website Surface; Spec 406 - Provider & Policy Domain Public Taxonomy; Spec 407 - MSP & Mittelstand Use-Case Pages; Spec 408 - Customer-safe Review, Evidence & Decision Story
|
||||
- **Must not depend on**: `apps/platform` runtime changes
|
||||
- **Primary audience**: MSP owners, MSP operators, IT leaders, Microsoft 365 admins, security reviewers, Datenschutz / DPO stakeholders, procurement / vendor-management stakeholders, DACH Mittelstand evaluators, and enterprise IT buyers
|
||||
- **Public message**: Tenantial can be evaluated in a structured way through focused demos, clear pilot scope, transparent provider-permission discussions, trust-oriented security/privacy review, and realistic rollout expectations for Microsoft 365 governance
|
||||
- **Out of scope**: self-service onboarding, CRM workflows, billing, subscriptions, trial provisioning, Graph consent runtime, legal-document generation, fake procurement portals, fake downloadable documents, fake calendar widgets, fake security or compliance artifacts, root workspace contract changes, and non-website implementation work
|
||||
|
||||
## Goals
|
||||
|
||||
- **G1**: Explain a concrete evaluation path from first walkthrough to pilot and next-step decision.
|
||||
- **G2**: Make pilot requirements and preparation work visible before a prospect asks for a manual explanation.
|
||||
- **G3**: Prepare procurement, security, and Datenschutz review through clear, bounded public guidance.
|
||||
- **G4**: Show which internal and external stakeholders should be involved in the evaluation.
|
||||
- **G5**: Prevent fake self-service, legal, provider, security, or automation claims.
|
||||
- **G6**: Improve conversion quality through real CTAs that match actual routes, forms, or contact methods.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- No `apps/platform` runtime work.
|
||||
- No onboarding backend, tenant connection wizard, or consent flow.
|
||||
- No CRM or lead-routing backend.
|
||||
- No billing, subscriptions, or trial provisioning.
|
||||
- No Microsoft Graph permission logic or exact permission matrix.
|
||||
- No legal-document generation or fake AVV/TOM downloads.
|
||||
- No fake calendar scheduling widget.
|
||||
- No fake procurement portal.
|
||||
- No fake downloadable security pack, legal pack, or procurement checklist.
|
||||
- No fake logos, case studies, certifications, or compliance claims.
|
||||
- No placeholder links, placeholder buttons, or `href="#"`.
|
||||
|
||||
## Spec Scope Fields *(mandatory)*
|
||||
|
||||
- **Scope**: N/A - public website surface outside authenticated workspace, tenant, or canonical product flows
|
||||
- **Primary Routes**: preferred public route family `/evaluierung` for German-first IA or `/evaluation` for English-first IA; real fallback route families such as `/demo-pilot`, `/procurement`, or `/start` only when current IA requires them
|
||||
- **Data Ownership**: no workspace-owned, tenant-owned, provider-owned, procurement, trust, legal, customer, or runtime product data is created, changed, or persisted by this feature
|
||||
- **RBAC**: public read-only content only; no membership, role, capability, authorization, or authenticated product behavior changes
|
||||
|
||||
For canonical-view specs, the spec MUST define:
|
||||
|
||||
- **Default filter behavior when tenant-context is active**: N/A - no tenant-context or canonical product view is introduced
|
||||
- **Explicit entitlement checks preventing cross-tenant leakage**: N/A - no authenticated tenant, workspace, provider, or customer data is involved
|
||||
|
||||
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
|
||||
|
||||
- **Cross-cutting feature?**: yes
|
||||
- **Interaction class(es)**: public navigation, footer links, homepage teaser, platform-page teaser, trust/use-case/review crosslinks, CTA links, and metadata
|
||||
- **Systems touched**: current public website shell, page-layout conventions, homepage, platform page, trust page, use-case pages, review/evidence page, navigation, footer, and page metadata
|
||||
- **Existing pattern(s) to extend**: existing public website layout, section, card/grid, CTA, teaser, and metadata conventions
|
||||
- **Shared contract / presenter / builder / renderer to reuse**: current website content structures and reusable presentation components
|
||||
- **Why the existing shared path is sufficient or insufficient**: the public site already has the shell and adjacent buyer-story surfaces; this feature needs one focused evaluation-readiness destination inside that shell rather than a second microsite or a new design system
|
||||
- **Allowed deviation and why**: a dedicated evaluation route is allowed when the current IA supports it because demo, pilot, security review, and rollout-readiness questions need one coherent destination
|
||||
- **Consistency impact**: Microsoft 365-first wording, provider-permission transparency, trust-language boundaries, no-instant-trial posture, and real-CTA behavior must stay aligned across the new page and any discovery surfaces
|
||||
- **Review focus**: verify that the evaluation path is understandable, the stakeholder and preparation sections are practical, all CTAs are real, and copy does not drift into unsupported legal, provider, automation, or self-service claims
|
||||
|
||||
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
|
||||
|
||||
- **Touches OperationRun start/completion/link UX?**: no
|
||||
- **Shared OperationRun UX contract/layer reused**: N/A
|
||||
- **Delegated start/completion UX behaviors**: N/A
|
||||
- **Local surface-owned behavior that remains**: none
|
||||
- **Queued DB-notification policy**: N/A
|
||||
- **Terminal notification path**: N/A
|
||||
- **Exception required?**: none
|
||||
|
||||
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
|
||||
|
||||
- **Shared provider/platform boundary touched?**: yes
|
||||
- **Boundary classification**: mixed public vocabulary only
|
||||
- **Seams affected**: Microsoft 365 access-readiness wording, provider-permission transparency, consent/admin-role language, trust-language handoff, and controlled-rollout versus blind-automation positioning
|
||||
- **Neutral platform terms preserved or introduced**: evaluation, pilot scope, security review, trust documents, provider permissions, stakeholder readiness, review objective, success criteria, and controlled rollout
|
||||
- **Provider-specific semantics retained and why**: Microsoft 365, consent, and admin-role language remain explicit because the public buying context is still Microsoft 365 governance and the evaluation path must feel concrete
|
||||
- **Why this does not deepen provider coupling accidentally**: the feature explains evaluation boundaries and buyer preparation only; it does not introduce a runtime permission matrix, provider capability registry, or provider-owned product contract
|
||||
- **Follow-up path**: none in this feature; later provider-expansion or permission-detail work belongs in follow-up website or platform specs only if product truth changes
|
||||
|
||||
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
|
||||
|
||||
N/A - public website buyer-readiness surface only; no authenticated operator-facing product surface is changed.
|
||||
|
||||
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
|
||||
|
||||
N/A - no operator-facing product surface change.
|
||||
|
||||
## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*
|
||||
|
||||
N/A - public buyer-facing copy only; no operator diagnostics, support mode, or raw evidence surface is added here.
|
||||
|
||||
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
|
||||
|
||||
N/A - no operator-facing product surface change.
|
||||
|
||||
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
|
||||
|
||||
N/A - no operator-facing product surface change.
|
||||
|
||||
## Proportionality Review *(mandatory when structural complexity is introduced)*
|
||||
|
||||
- **New source of truth?**: no
|
||||
- **New persisted entity/table/artifact?**: no
|
||||
- **New abstraction?**: no
|
||||
- **New enum/state/reason family?**: no
|
||||
- **New cross-domain UI framework/taxonomy?**: no - the feature reuses the current public website shell and existing page patterns
|
||||
- **Current operator problem**: buyers and internal reviewers cannot yet plan a Tenantial evaluation without manually reconstructing the path across multiple public pages and conversations
|
||||
- **Existing structure is insufficient because**: homepage, trust, use-case, and review/evidence surfaces answer adjacent questions, but they do not present one coherent evaluation and rollout-readiness journey
|
||||
- **Narrowest correct implementation**: one dedicated public page plus lightweight discoverability from current IA
|
||||
- **Ownership cost**: public copy, metadata, and CTA targets must stay aligned with actual trust, contact, and product truth as the commercial process evolves
|
||||
- **Alternative intentionally rejected**: spreading the story across homepage, trust, and platform blurbs only, because that would keep evaluation readiness fragmented and harder to verify
|
||||
- **Release truth**: current public website truth only; no runtime product promise or future abstraction is introduced
|
||||
|
||||
### Compatibility posture
|
||||
|
||||
This feature assumes a pre-production environment.
|
||||
|
||||
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.
|
||||
|
||||
Canonical replacement is preferred over preservation.
|
||||
|
||||
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
|
||||
|
||||
- **Test purpose / classification**: Browser
|
||||
- **Validation lane(s)**: browser, confidence
|
||||
- **Why this classification and these lanes are sufficient**: public website quality is proven by reachable routes, readable desktop/mobile layouts, real CTA targets, static claim scans, and any existing website build/check/test commands that validate the public site
|
||||
- **New or expanded test families**: none beyond website-only static checks and any existing public-site smoke coverage
|
||||
- **Fixture / helper cost impact**: none
|
||||
- **Heavy-family visibility / justification**: none
|
||||
- **Special surface test profile**: N/A - public website surface
|
||||
- **Standard-native relief or required special coverage**: ordinary public-site coverage only; verify route reachability, readable layout, real CTA links, crosslink integrity, and claim-boundary compliance
|
||||
- **Reviewer handoff**: confirm only website-facing files change, no `apps/platform` files change, the chosen route follows current IA, CTA targets are real, and copy stays bounded around security, privacy, procurement, and pilot readiness
|
||||
- **Budget / baseline / trend impact**: none expected
|
||||
- **Escalation needed**: follow-up-spec only if later work introduces a real procurement workflow, trial automation, or legal/security document delivery surface
|
||||
- **Active feature PR close-out entry**: Smoke Coverage
|
||||
- **Planned validation commands**:
|
||||
- inspect root and website package manifests before running scripts
|
||||
- run only existing website `check`, `build`, or `test` commands if present
|
||||
- run static scans for placeholder links, banned internal phrases, and unsupported claims in website source and committed public assets
|
||||
- run desktop and mobile browser smoke for the evaluation page and any homepage/platform/trust/use-case/review discovery links if local preview is available
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 - Buyers Understand The Evaluation Path (Priority: P1)
|
||||
|
||||
An MSP owner or internal IT evaluator opens the page and quickly understands how Tenantial is evaluated from first walkthrough through pilot and next-step decision.
|
||||
|
||||
**Why this priority**: The page exists primarily to remove the practical evaluation ambiguity that remains after the earlier public-site specs.
|
||||
|
||||
**Independent Test**: Can be fully tested by opening the page and confirming that the hero, evaluation-path section, timeline, and CTA language clearly explain how to start without implying instant self-service onboarding.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a first-time public buyer lands on the page, **When** they read the hero and evaluation-path section, **Then** they understand that Tenantial is evaluated through a structured sequence of demo, scope clarification, review, pilot, and next-step decision.
|
||||
2. **Given** a visitor comparing products quickly, **When** they scan the page sections, **Then** they do not interpret Tenantial as an instant-trial product, blind automation tool, or generic procurement portal.
|
||||
3. **Given** a visitor reaches the final CTA, **When** they review the call to action, **Then** they see a bounded next step such as demo, pilot request, trust review, or platform view through a real destination.
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - Security And Procurement Stakeholders Know What To Prepare (Priority: P1)
|
||||
|
||||
A security reviewer, Datenschutz contact, or procurement stakeholder can identify which internal roles, trust questions, and document-status checks belong in the evaluation.
|
||||
|
||||
**Why this priority**: Enterprise and MSP buying friction usually appears in security, privacy, and procurement conversations rather than in product positioning alone.
|
||||
|
||||
**Independent Test**: Can be fully tested by reviewing the preparation, stakeholder, security/procurement, and FAQ sections to confirm that the page names the relevant contacts, questions, and review boundaries in buyer-facing language.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a security or Datenschutz stakeholder opens the page, **When** they review the security/procurement section, **Then** they can identify trust, AVV/DPA/TOM status, provider-permission, hosting/subprocessor, and retention-related review topics.
|
||||
2. **Given** a procurement or vendor-management stakeholder reads the page, **When** they review the stakeholder and preparation sections, **Then** they can see which internal owners should be involved before a pilot or rollout decision.
|
||||
3. **Given** a reviewer looks for legal or compliance promises, **When** they scan the page, **Then** they do not see fake downloads, fake approvals, or unverifiable compliance/certification claims.
|
||||
|
||||
---
|
||||
|
||||
### User Story 3 - Technical Owners Understand Pilot Scope And Access Boundaries (Priority: P2)
|
||||
|
||||
A Microsoft 365 admin or technical owner can understand what a realistic pilot needs, what sort of access may be discussed, and what is explicitly not required for a first evaluation.
|
||||
|
||||
**Why this priority**: The page must answer technical-readiness questions without drifting into an unverified permissions matrix or overpromising write/remediation behavior.
|
||||
|
||||
**Independent Test**: Can be fully tested by reviewing the pilot-scenario, Microsoft 365 access, and "what is not required" sections to confirm that they explain scope-dependent access and controlled rollout language.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a technical owner reads the Microsoft 365 access section, **When** they review read-oriented access, recovery-adjacent access, and consent/admin-role wording, **Then** they understand that access requirements depend on pilot scope and are not blind defaults.
|
||||
2. **Given** a visitor fears a forced big-bang rollout, **When** they read the "what Tenantial does not require" section, **Then** they understand that a limited-scope evaluation or pilot is possible.
|
||||
3. **Given** a visitor asks whether a productive tenant is always required, **When** they review the FAQ, **Then** they see a careful answer that allows bounded starting scope without promising unrealistic outcomes from a zero-context setup.
|
||||
|
||||
---
|
||||
|
||||
### User Story 4 - Visitors Discover The Page Through Real IA Entry Points (Priority: P2)
|
||||
|
||||
A public visitor should be able to find the evaluation page through the existing website information architecture without broken links, placeholders, or fake CTA targets.
|
||||
|
||||
**Why this priority**: The page only reduces friction if it is reachable from the places where buyers first decide whether to ask for a demo or pilot.
|
||||
|
||||
**Independent Test**: Can be fully tested by following homepage, platform, trust, use-case, review/evidence, navigation, or footer links to the page on desktop and mobile.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a visitor uses any homepage, platform, trust, use-case, review/evidence, navigation, or footer teaser added by this feature, **When** they follow the CTA, **Then** they reach the evaluation page through a real route.
|
||||
2. **Given** a visitor uses any in-page CTA added by this feature, **When** they open the target, **Then** the destination resolves as a real route, form, or mailto target without placeholder behavior.
|
||||
3. **Given** a mobile visitor opens the new page, **When** they scan the hero, core sections, FAQ, and CTA, **Then** the page remains readable and actionable.
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- What happens when the current website IA does not support `/evaluierung` or `/evaluation` cleanly? The implementation must choose a real route family that matches current conventions and document the decision.
|
||||
- What happens when a suggested CTA target such as trust, demo, pilot request, platform view, or security-contact route does not exist as a real destination? The CTA must be omitted or mapped to an existing real destination.
|
||||
- What happens when exact Microsoft 365 permissions are not verified in public source truth? The page must keep the access section at the level of scope-dependent readiness and must not publish an exact permission matrix.
|
||||
- What happens when a buyer wants to know whether a productive tenant is required immediately? The page must answer cautiously and allow a bounded starting scope without implying that every meaningful evaluation can run with no real context.
|
||||
- What happens when the active site language is German-first, English-first, or mixed? The implementation must follow current site conventions instead of introducing a new localization foundation.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- The current public website can support one real evaluation-readiness destination without changing root workspace contracts.
|
||||
- At least one real destination exists for primary CTA flows such as demo/contact, trust, platform, or mailto contact; unavailable CTA variants may be omitted.
|
||||
- AVV/DPA/TOM and security-document readiness can be described as status, discussion, or request-based handoff without claiming downloadable self-service artifacts.
|
||||
- Microsoft 365 access requirements remain purpose- and pilot-scope-dependent and should not be marketed as a fixed universal permission set.
|
||||
- The current site language strategy may be German-first or mixed; implementation should follow that convention instead of normalizing the whole site.
|
||||
|
||||
## Requirements *(mandatory)*
|
||||
|
||||
This feature introduces no Microsoft Graph calls, no write/change product behavior, no persistence, no OperationRun flow, no RBAC mutation, and no provider runtime capability. Its only additions are bounded public website copy, route exposure, discoverability links, and metadata that translate existing product truth into an evaluation, procurement, and rollout-readiness story.
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
#### Scope And Route
|
||||
|
||||
- **FR-001**: The implementation MUST remain public-website-only and MUST NOT require `apps/platform` runtime changes.
|
||||
- **FR-002**: The public website MUST provide one dedicated page for evaluation, procurement, and rollout readiness.
|
||||
- **FR-003**: The implementation MUST follow the current website route family; the preferred destination is `/evaluierung` for German-first IA or `/evaluation` for English-first IA, with real fallback route families only when current IA requires them.
|
||||
- **FR-004**: The chosen route and IA decision MUST be documented during implementation.
|
||||
- **FR-005**: The new page MUST be reachable from at least one existing public-site entry point such as the homepage, platform page, trust page, use-case pages, review/evidence page, navigation, or footer.
|
||||
- **FR-006**: Every CTA, teaser, nav link, footer link, and in-page link added by this feature MUST resolve to a real destination; placeholder links and `href="#"` are forbidden.
|
||||
|
||||
#### Core Story And Page Structure
|
||||
|
||||
- **FR-007**: The page MUST position Tenantial as a structured and controlled evaluation path for Microsoft 365 governance rather than as instant self-service software.
|
||||
- **FR-008**: The page MUST explain a buyer journey from initial walkthrough or demo through scope clarification, security and Datenschutz review, technical readiness check, focused pilot, and review or commercial next-step decision.
|
||||
- **FR-009**: The page MUST include a hero section, evaluation-path section, preparation section, pilot-scenario section, stakeholder section, security/procurement section, Microsoft 365 access section, "what Tenantial does not require" section, example timeline, buyer FAQ, and final CTA.
|
||||
- **FR-010**: The hero and supporting copy MUST make safe evaluation and controlled pilot positioning clear without implying instant signup, automatic provisioning, or blind rollout.
|
||||
- **FR-011**: The evaluation-path section MUST explain that Tenantial should be evaluated through clear scope, controlled review, and explicit next-step decisions rather than blind production introduction.
|
||||
- **FR-012**: The page MUST make clear that Tenantial is not positioned as a helpdesk, admin-center replacement, PSA platform, or blind automation/remediation engine.
|
||||
|
||||
#### Preparation, Pilot Scope, Stakeholders, And Timeline
|
||||
|
||||
- **FR-013**: The preparation section MUST include use case, Microsoft 365 scope, technical owner, security/privacy contact, review objective, and success criteria.
|
||||
- **FR-014**: The preparation copy MUST explain that evaluation does not require months of preparation but benefits from clear ownership, scope, and expected outcomes.
|
||||
- **FR-015**: The pilot-scenario section MUST include MSP customer review, internal IT governance, policy backup/versioning, evidence/audit preparation, and provider-permission readiness examples.
|
||||
- **FR-016**: Pilot-scenario copy MUST describe these as typical examples and MUST NOT imply that every scenario is fully automated or self-service today.
|
||||
- **FR-017**: The stakeholder section MUST include MSP service owner, MSP operator or cloud engineer, IT leadership, Microsoft 365 admin, security, Datenschutz / DPO, and procurement or vendor management, with optional auditor or compliance involvement when relevant.
|
||||
- **FR-018**: Stakeholder copy MUST explain what each role evaluates in buyer-facing language.
|
||||
- **FR-019**: The timeline section MUST be framed as a cautious example and MUST NOT guarantee delivery or rollout duration.
|
||||
|
||||
#### Security, Procurement, And Microsoft 365 Access
|
||||
|
||||
- **FR-020**: The security/procurement section MUST cover trust/privacy posture, AVV/DPA/TOM status, provider permissions, hosting and subprocessors, audit/retention/export/delete posture where available, and commercial fit.
|
||||
- **FR-021**: Trust, security, or procurement CTAs MAY link only to existing trust routes, contact routes, forms, or mailto destinations.
|
||||
- **FR-022**: The Microsoft 365 access section MUST explain read-oriented access, write- or recovery-adjacent access, consent/admin-role readiness, and no-blind-execution positioning.
|
||||
- **FR-023**: Access wording MUST explain that relevant permissions depend on pilot scope and MUST NOT list exact Microsoft Graph permissions unless separately verified as public source truth.
|
||||
- **FR-024**: The page MUST explain that a productive tenant is not always required for a first conversation, but meaningful evaluation outcomes may still require a realistic Microsoft 365 context.
|
||||
- **FR-025**: The page MUST explain that security, privacy, and procurement review happen through transparent discussion and status clarification rather than fake downloads, fake approvals, or fake self-service portals.
|
||||
|
||||
#### Boundaries And Buyer FAQ
|
||||
|
||||
- **FR-026**: The "what Tenantial does not require" section MUST include no big-bang rollout, no admin-center replacement, no helpdesk switch, no automatic remediation, and no fake compliance positioning.
|
||||
- **FR-027**: The buyer FAQ MUST address productive-tenant expectations, scope-dependent permissions, AVV/DPA/TOM status, admin-center replacement, helpdesk or PSA status, automatic changes, provider scope, and compliance boundaries in direct buyer-friendly language.
|
||||
- **FR-028**: FAQ and page copy MUST avoid legal, provider, security, or automation overclaim and MUST keep answers at the level of verified product truth.
|
||||
|
||||
#### Discovery, CTA, Metadata, And Claim Guardrails
|
||||
|
||||
- **FR-029**: Primary CTAs MAY include Demo buchen, Pilot anfragen, Security-Unterlagen anfragen, Trust & Datenschutz ansehen, and Plattform ansehen, but only when each target is a real destination.
|
||||
- **FR-030**: Any unavailable CTA MUST be omitted or mapped to an existing real destination rather than faked.
|
||||
- **FR-031**: The homepage MAY expose a compact evaluation teaser when the current homepage structure supports it without a heavy IA rewrite.
|
||||
- **FR-032**: The platform page MAY expose a compact demo and pilot teaser when current structure supports it.
|
||||
- **FR-033**: Trust, use-case, and review/evidence pages MAY crosslink to the evaluation page only when those routes exist as real destinations.
|
||||
- **FR-034**: Navigation or footer MAY expose the page only where current IA supports it; the feature MUST NOT introduce placeholder dropdowns or a heavy navigation refactor solely for this page.
|
||||
- **FR-035**: Page metadata MUST describe demo, pilot, security review, privacy questions, provider permissions, and rollout readiness in Microsoft 365 governance language for MSPs and enterprise IT buyers.
|
||||
- **FR-036**: Visible copy and metadata MUST use strong but safe terms such as Tenantial evaluieren, Demo buchen, Pilot anfragen, Security Review, Datenschutzfragen, Provider-Berechtigungen, Technical Readiness Check, Pilot-Scope, Erfolgskriterien, Trust-Unterlagen, AVV/DPA/TOM-Status, and kontrollierter Rollout.
|
||||
- **FR-037**: Visible copy and metadata MUST NOT use internal phrases such as procurement readiness website surface, productization gap, repo-real foundation, workspace-first route context, capability registry, provider-neutral artifact taxonomy, cutover guardrails, or implementation truth.
|
||||
- **FR-038**: Visible copy and metadata MUST NOT claim instant trial, self-service onboarding availability, automated provisioning, DSGVO-konform, ISO-zertifiziert, NIS2-konform, in Deutschland gehostet, no customer data stored, Google/AWS support, automatic remediation, automatic restore, or one-click restore unless separately verified as current product truth.
|
||||
- **FR-039**: The feature MUST NOT introduce fake downloadable documents, fake AVV/TOM files, fake security-pack downloads, fake calendar widgets, fake customer logos, fake case studies, or fake certifications.
|
||||
|
||||
#### Scope Safety
|
||||
|
||||
- **FR-040**: The implementation MUST preserve root workspace contracts, including existing root script names, the website package name, the `WEBSITE_PORT` convention, and the `apps/*` workspace convention.
|
||||
- **FR-041**: The implementation MUST follow the current site language strategy and MUST NOT introduce a new localization foundation.
|
||||
- **FR-042**: The implementation MUST NOT add onboarding runtime, CRM behavior, billing or trial provisioning, Microsoft consent runtime, Graph permission logic, or legal-document generation.
|
||||
- **FR-043**: The implementation MUST record the exact validation commands and results used to verify the public website change.
|
||||
- **FR-044**: The implementation close-out MUST explicitly confirm that changed application files are limited to `apps/website/**`.
|
||||
|
||||
## UI Action Matrix *(mandatory when Filament is changed)*
|
||||
|
||||
N/A - no Filament Resource, RelationManager, or Page is changed by this feature.
|
||||
|
||||
### Key Entities *(include if feature involves data)*
|
||||
|
||||
- **Evaluation Readiness Page**: A public buyer-facing page that explains how Tenantial is evaluated, reviewed internally, piloted, and prepared for controlled rollout.
|
||||
- **Evaluation Path**: The buyer-facing sequence from first walkthrough or demo through scope clarification, security/privacy review, technical readiness, pilot, and next-step decision.
|
||||
- **Pilot Scope**: The bounded combination of use case, Microsoft 365 context, stakeholder ownership, access readiness, and success criteria used to evaluate Tenantial safely.
|
||||
- **Trust Handoff**: The buyer-facing explanation of which trust, privacy, AVV/DPA/TOM, hosting, and security questions are reviewed during evaluation.
|
||||
- **Stakeholder Set**: The collection of commercial, technical, security, privacy, and procurement contacts that should participate in a meaningful evaluation.
|
||||
|
||||
## Success Criteria *(mandatory)*
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: Structured internal copy-review notes record that a first-time MSP or enterprise IT evaluator can identify within 60 seconds how Tenantial moves from first demo to focused pilot and next-step decision.
|
||||
- **SC-002**: Structured internal copy-review notes record that a security, Datenschutz, or procurement reviewer can identify within 90 seconds which questions, contacts, and trust topics belong in the evaluation.
|
||||
- **SC-003**: Structured internal copy-review notes record that a technical owner can identify within 60 seconds that Microsoft 365 access depends on pilot scope and that blind automation or forced big-bang rollout is not being promised.
|
||||
- **SC-004**: QA finds zero placeholder links or broken exposed routes across the new page and any homepage, platform, trust, use-case, review/evidence, navigation, or footer discovery points changed by this feature.
|
||||
- **SC-005**: Static copy review finds zero occurrences of banned internal phrases, fake self-service or download claims, and unverified legal, provider, or automation claims on new or updated public surfaces created by this feature.
|
||||
- **SC-006**: Desktop and mobile smoke review confirms that the page remains readable, keeps its primary CTA visible, explains the evaluation path and FAQ clearly, and shows no fake widgets or document-download affordances.
|
||||
249
specs/409-evaluation-procurement-rollout/tasks.md
Normal file
249
specs/409-evaluation-procurement-rollout/tasks.md
Normal file
@ -0,0 +1,249 @@
|
||||
# Tasks: Evaluation, Procurement & Rollout Readiness Website Surface
|
||||
|
||||
**Input**: Design documents from `/specs/409-evaluation-procurement-rollout/`
|
||||
**Prerequisites**: `plan.md` (required), `spec.md` (required), `research.md`, `data-model.md`, `quickstart.md`, `contracts/evaluation-readiness-routes.openapi.yaml`
|
||||
|
||||
**Tests**: Runtime behavior changes are in scope for `apps/website`, so browser smoke, route/metadata assertions, and static claim scans are required.
|
||||
|
||||
## Test Governance Checklist
|
||||
|
||||
- Lane assignment: `Browser` in `browser, confidence` remains the narrowest sufficient proof for this feature.
|
||||
- New or changed tests stay inside the existing public-website smoke family in `apps/website/tests/smoke/`.
|
||||
- Shared helpers and fixtures stay cheap by default; no new heavy helpers, factories, or setup layers are introduced.
|
||||
- Planned validation commands remain limited to `build`, `public-routes.spec.ts`, and `interaction.spec.ts` from `apps/website/package.json`.
|
||||
- Surface test profile stays `public website`, with `document-in-feature` as the escalation path recorded in `specs/409-evaluation-procurement-rollout/plan.md`.
|
||||
|
||||
## Phase 1: Setup (Shared Infrastructure)
|
||||
|
||||
**Purpose**: Confirm repo contracts, current website conventions, and the exact public surfaces that the feature may touch.
|
||||
|
||||
- [X] T001 Confirm active feature scope, user stories, and selected route family in `specs/409-evaluation-procurement-rollout/spec.md` and `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
- [X] T002 Verify root workspace contracts remain unchanged in `package.json` and `pnpm-workspace.yaml`
|
||||
- [X] T003 Verify website validation scripts and package contract in `apps/website/package.json`
|
||||
- [X] T004 Map localized routing, canonical-path handling, and real CTA target rules in `apps/website/src/i18n.ts`, `apps/website/src/pages/contact.astro`, and `apps/website/src/pages/en/contact.astro`
|
||||
- [X] T005 [P] Map current homepage, platform, trust, review-pack, and footer discovery surfaces in `apps/website/src/components/pages/HomePage.astro`, `apps/website/src/components/pages/PlatformPage.astro`, `apps/website/src/components/pages/TrustPage.astro`, `apps/website/src/components/pages/ReviewPacksPage.astro`, and `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T006 [P] Map current use-case entry points and smoke helpers in `apps/website/src/pages/use-cases/msp.astro`, `apps/website/src/pages/use-cases/mittelstand.astro`, `apps/website/src/pages/en/use-cases/msp.astro`, `apps/website/src/pages/en/use-cases/mittelstand.astro`, `apps/website/tests/smoke/public-routes.spec.ts`, and `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational (Blocking Prerequisites)
|
||||
|
||||
**Purpose**: Establish the shared route, page scaffold, copy schema, and smoke hooks that every user story depends on.
|
||||
|
||||
**Critical**: No user story work should begin before this phase is complete.
|
||||
|
||||
- [X] T007 Create thin localized route shells in `apps/website/src/pages/evaluierung.astro` and `apps/website/src/pages/en/evaluation.astro`
|
||||
- [X] T008 Create the shared evaluation page scaffold in `apps/website/src/components/pages/EvaluationPage.astro`
|
||||
- [X] T009 Add localized `evaluation` copy schema, metadata, and CTA containers in `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T010 Extend evaluation route inventory and public-claim helper coverage in `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
- [X] T011 Add baseline title and description assertions for `/evaluierung` and `/en/evaluation` in `apps/website/tests/smoke/public-routes.spec.ts`
|
||||
- [X] T012 Keep the final route family and CTA-target contract aligned between `specs/409-evaluation-procurement-rollout/plan.md` and `specs/409-evaluation-procurement-rollout/contracts/evaluation-readiness-routes.openapi.yaml`
|
||||
|
||||
**Checkpoint**: Foundation is ready for story implementation.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 1 - Buyers Understand The Evaluation Path (Priority: P1) 🎯 MVP
|
||||
|
||||
**Goal**: Deliver the core page framing so buyers understand the evaluation sequence from first walkthrough to focused pilot and next-step decision.
|
||||
|
||||
**Independent Test**: Open `/evaluierung` and `/en/evaluation`, then confirm the hero, evaluation-path section, example timeline, and CTA language explain a structured demo-to-pilot journey without implying instant self-service onboarding.
|
||||
|
||||
### Tests for User Story 1
|
||||
|
||||
- [X] T013 [P] [US1] Add route title and description assertions for `/evaluierung` and `/en/evaluation` in `apps/website/tests/smoke/public-routes.spec.ts`
|
||||
- [X] T014 [P] [US1] Add hero, evaluation-path, example-timeline, and CTA-boundary assertions in `apps/website/tests/smoke/interaction.spec.ts`
|
||||
|
||||
### Implementation for User Story 1
|
||||
|
||||
- [X] T015 [US1] Implement hero, evaluation-path steps, example timeline, and primary/final CTA copy in `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T016 [US1] Render hero, evaluation-path, example timeline, and final CTA sections in `apps/website/src/components/pages/EvaluationPage.astro`
|
||||
- [X] T017 [US1] Wire localized metadata and shared page props in `apps/website/src/pages/evaluierung.astro` and `apps/website/src/pages/en/evaluation.astro`
|
||||
|
||||
**Checkpoint**: User Story 1 is independently functional and demonstrable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 2 - Security And Procurement Stakeholders Know What To Prepare (Priority: P1)
|
||||
|
||||
**Goal**: Explain preparation needs, stakeholder involvement, security/privacy review, procurement questions, and buyer FAQ boundaries without fake legal or document promises.
|
||||
|
||||
**Independent Test**: Open the evaluation page and confirm the preparation, stakeholder, security/procurement, and FAQ sections identify who should be involved, what must be reviewed, and what is intentionally not overclaimed.
|
||||
|
||||
### Tests for User Story 2
|
||||
|
||||
- [X] T018 [P] [US2] Add preparation, stakeholder, security/procurement, and FAQ assertions in `apps/website/tests/smoke/interaction.spec.ts`
|
||||
- [X] T019 [P] [US2] Extend forbidden-claim and real trust/contact-target coverage for evaluation routes in `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
|
||||
### Implementation for User Story 2
|
||||
|
||||
- [X] T020 [US2] Implement preparation cards, stakeholder cards, security/procurement checklist items, and buyer FAQ copy in `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T021 [US2] Render preparation, stakeholder, security/procurement, and FAQ sections in `apps/website/src/components/pages/EvaluationPage.astro`
|
||||
- [X] T022 [US2] Keep trust and security-request CTA targets aligned between `apps/website/src/data_files/site-copy.ts` and `specs/409-evaluation-procurement-rollout/contracts/evaluation-readiness-routes.openapi.yaml`
|
||||
|
||||
**Checkpoint**: User Story 2 is independently functional and demonstrable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 3 - Technical Owners Understand Pilot Scope And Access Boundaries (Priority: P2)
|
||||
|
||||
**Goal**: Show what a realistic pilot can cover, how Microsoft 365 access is framed, and what the first evaluation explicitly does not require.
|
||||
|
||||
**Independent Test**: Open the evaluation page and verify the pilot-scenario, Microsoft 365 access, non-requirements, and related FAQ content explain scope-dependent access and controlled rollout without publishing an unverified permission matrix.
|
||||
|
||||
### Tests for User Story 3
|
||||
|
||||
- [X] T023 [P] [US3] Add pilot-scenario, Microsoft 365 access, and non-requirement assertions in `apps/website/tests/smoke/interaction.spec.ts`
|
||||
- [X] T024 [P] [US3] Add cautious access-language and rollout-boundary assertions for evaluation routes in `apps/website/tests/smoke/public-routes.spec.ts`
|
||||
- [X] T025 [P] [US3] Extend banned permission-matrix and automation-overclaim coverage for evaluation routes in `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [X] T026 [US3] Implement pilot scenario, Microsoft 365 access-principle, non-requirement, and access-adjacent FAQ copy in `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T027 [US3] Render pilot-scenario, Microsoft 365 access, and non-requirement sections in `apps/website/src/components/pages/EvaluationPage.astro`
|
||||
- [X] T028 [US3] Keep access-boundary wording aligned between `apps/website/src/data_files/site-copy.ts` and `specs/409-evaluation-procurement-rollout/contracts/evaluation-readiness-routes.openapi.yaml`
|
||||
|
||||
**Checkpoint**: User Story 3 is independently functional and demonstrable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: User Story 4 - Visitors Discover The Page Through Real IA Entry Points (Priority: P2)
|
||||
|
||||
**Goal**: Make the evaluation page reachable from current public-site entry points without broken links, placeholders, or a heavy IA rewrite.
|
||||
|
||||
**Independent Test**: Reach the page from the homepage, platform, review-pack, trust, use-case, and footer entry points that are implemented, then confirm the route stays readable on desktop and mobile.
|
||||
|
||||
### Tests for User Story 4
|
||||
|
||||
- [X] T029 [P] [US4] Extend localized evaluation route inventory and allowed-discovery-link coverage in `apps/website/tests/smoke/smoke-helpers.ts`
|
||||
- [X] T030 [P] [US4] Add discovery-link and placeholder-link assertions for evaluation entry points in `apps/website/tests/smoke/public-routes.spec.ts`
|
||||
- [X] T031 [P] [US4] Add click-through and mobile-readability assertions for evaluation entry points in `apps/website/tests/smoke/interaction.spec.ts`
|
||||
|
||||
### Implementation for User Story 4
|
||||
|
||||
- [X] T032 [US4] Add homepage teaser copy and localized route mapping in `apps/website/src/data_files/site-copy.ts` and `apps/website/src/components/pages/HomePage.astro`
|
||||
- [X] T033 [US4] Add compact platform and review-pack crosslinks in `apps/website/src/data_files/site-copy.ts`, `apps/website/src/components/pages/PlatformPage.astro`, and `apps/website/src/components/pages/ReviewPacksPage.astro`
|
||||
- [X] T034 [US4] Add trust and use-case crosslinks in `apps/website/src/data_files/site-copy.ts`, `apps/website/src/components/pages/TrustPage.astro`, `apps/website/src/pages/use-cases/msp.astro`, `apps/website/src/pages/use-cases/mittelstand.astro`, `apps/website/src/pages/en/use-cases/msp.astro`, and `apps/website/src/pages/en/use-cases/mittelstand.astro`
|
||||
- [X] T035 [US4] Add localized footer discovery links without a main-nav refactor in `apps/website/src/data_files/site-copy.ts`
|
||||
- [X] T036 [US4] Record any intentionally omitted discovery surface and the final IA decision in `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
|
||||
**Checkpoint**: User Story 4 is independently functional and demonstrable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Polish & Cross-Cutting Concerns
|
||||
|
||||
**Purpose**: Run the required validation, record proof, and close out claim-boundary and scope checks.
|
||||
|
||||
- [X] T037 [P] Run formatting check via `corepack pnpm --filter @tenantatlas/website format:check` using `apps/website/package.json`
|
||||
- [X] T038 Run static forbidden-term scans on `apps/website/src` and `apps/website/public` using the command set in `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
- [X] T039 [P] If `apps/website/dist` is regenerated, run static forbidden-term scans on `apps/website/dist` using the command set in `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
- [X] T040 Run build validation via `corepack pnpm --filter @tenantatlas/website build` using `apps/website/package.json`
|
||||
- [X] T041 Run route smoke via `corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts` for `apps/website/tests/smoke/public-routes.spec.ts`
|
||||
- [X] T042 Run interaction smoke via `corepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts` for `apps/website/tests/smoke/interaction.spec.ts`
|
||||
- [X] T043 Perform timed comprehension checks on desktop/mobile for buyer (60 seconds), security/procurement (90 seconds), and technical-owner (60 seconds) reviewers on `/evaluierung` and `/en/evaluation`, then record pass/fail notes for SC-001 through SC-006 in `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
- [X] T044 Record validation commands, scan outcomes, `Smoke Coverage` close-out, omitted surfaces, and `apps/platform/**` scope confirmation in `specs/409-evaluation-procurement-rollout/plan.md` and `specs/409-evaluation-procurement-rollout/checklists/requirements.md`
|
||||
- [X] T045 Run quickstart validation against `specs/409-evaluation-procurement-rollout/quickstart.md` and record any documentation drift in `specs/409-evaluation-procurement-rollout/plan.md`
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Execution Order
|
||||
|
||||
### Phase Dependencies
|
||||
|
||||
- **Setup (Phase 1)**: No dependencies; starts immediately.
|
||||
- **Foundational (Phase 2)**: Depends on Setup completion and blocks all story work.
|
||||
- **User Stories (Phases 3-6)**: Depend on Foundational completion.
|
||||
- **Polish (Phase 7)**: Depends on all selected user stories being complete.
|
||||
|
||||
### User Story Dependencies
|
||||
|
||||
- **US1 (P1)**: Starts after Phase 2; no dependency on other stories.
|
||||
- **US2 (P1)**: Starts after Phase 2; can overlap with US1 once the shared page scaffold exists.
|
||||
- **US3 (P2)**: Depends on the core route and section structure from US1; can overlap late US2 copy work.
|
||||
- **US4 (P2)**: Depends on the evaluation routes existing and at least one implemented discovery surface from US1-US3.
|
||||
|
||||
### Within Each User Story
|
||||
|
||||
- Route and smoke assertions should be added before or alongside implementation and must fail before final pass.
|
||||
- Shared page structure comes before route wiring and discovery-link integration.
|
||||
- Copy and section rendering complete before build and browser validation.
|
||||
|
||||
### Parallel Opportunities
|
||||
|
||||
- Setup tasks marked `[P]` can run in parallel.
|
||||
- Foundational smoke-hook work can run in parallel with shared page scaffolding after route selection is fixed.
|
||||
- US1 and US2 can proceed in parallel after Phase 2 if file ownership is coordinated.
|
||||
- US4 homepage, platform, trust, review-pack, and use-case discoverability tasks can be split across implementers once route copy is stable.
|
||||
- Phase 7 scan, build, and smoke tasks can be split once implementation is frozen.
|
||||
|
||||
---
|
||||
|
||||
## Parallel Example: User Story 1
|
||||
|
||||
```bash
|
||||
Task: "T013 [US1] Add route title and description assertions for /evaluierung and /en/evaluation in apps/website/tests/smoke/public-routes.spec.ts"
|
||||
Task: "T014 [US1] Add hero, evaluation-path, example-timeline, and CTA-boundary assertions in apps/website/tests/smoke/interaction.spec.ts"
|
||||
```
|
||||
|
||||
## Parallel Example: User Story 2
|
||||
|
||||
```bash
|
||||
Task: "T018 [US2] Add preparation, stakeholder, security/procurement, and FAQ assertions in apps/website/tests/smoke/interaction.spec.ts"
|
||||
Task: "T019 [US2] Extend forbidden-claim and real trust/contact-target coverage for evaluation routes in apps/website/tests/smoke/smoke-helpers.ts"
|
||||
```
|
||||
|
||||
## Parallel Example: User Story 3
|
||||
|
||||
```bash
|
||||
Task: "T023 [US3] Add pilot-scenario, Microsoft 365 access, and non-requirement assertions in apps/website/tests/smoke/interaction.spec.ts"
|
||||
Task: "T024 [US3] Add cautious access-language and rollout-boundary assertions for evaluation routes in apps/website/tests/smoke/public-routes.spec.ts"
|
||||
Task: "T025 [US3] Extend banned permission-matrix and automation-overclaim coverage for evaluation routes in apps/website/tests/smoke/smoke-helpers.ts"
|
||||
```
|
||||
|
||||
## Parallel Example: User Story 4
|
||||
|
||||
```bash
|
||||
Task: "T029 [US4] Extend localized evaluation route inventory and allowed-discovery-link coverage in apps/website/tests/smoke/smoke-helpers.ts"
|
||||
Task: "T030 [US4] Add discovery-link and placeholder-link assertions for evaluation entry points in apps/website/tests/smoke/public-routes.spec.ts"
|
||||
Task: "T031 [US4] Add click-through and mobile-readability assertions for evaluation entry points in apps/website/tests/smoke/interaction.spec.ts"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### MVP First (P1 Slice: User Stories 1 and 2)
|
||||
|
||||
1. Complete Phase 1 (Setup).
|
||||
2. Complete Phase 2 (Foundational).
|
||||
3. Complete Phase 3 (US1).
|
||||
4. Complete Phase 4 (US2).
|
||||
5. Validate the P1 slice independently with route metadata and browser smoke.
|
||||
6. Demo or ship the first buyer-facing slice.
|
||||
|
||||
### Incremental Delivery
|
||||
|
||||
1. Finish Setup plus Foundational once.
|
||||
2. Deliver US1 and US2 as the P1 slice, then validate them independently.
|
||||
3. Add US3 and validate technical-readiness framing.
|
||||
4. Add US4 and validate discovery plus mobile readability.
|
||||
5. Finish Phase 7 proof and close-out notes.
|
||||
|
||||
### Parallel Team Strategy
|
||||
|
||||
1. One implementer completes Setup plus Foundational.
|
||||
2. After Phase 2:
|
||||
- Implementer A: US1 core route story
|
||||
- Implementer B: US2 security/procurement and stakeholder story
|
||||
- Implementer C: US4 discoverability surfaces
|
||||
3. Fold US3 technical-readiness framing in after the shared route story stabilizes.
|
||||
4. Run Phase 7 validation together before merge.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- `[P]` tasks touch different files or can be completed without waiting on another incomplete task in the same phase.
|
||||
- `[US1]` to `[US4]` labels map directly to the user stories in `spec.md` for traceability.
|
||||
- MVP scope is the P1 slice: User Stories 1 and 2. User Stories 3 and 4 layer on the same shared page once the core route story is stable.
|
||||
Loading…
Reference in New Issue
Block a user