25 KiB
Implementation Plan: personal-homepage (andreknie.de)
Overview
Build a personal homepage for Dr. Andre Knie at andreknie.de using Vite 8 + React 19 (JSX), react-router-dom v7, Express 5 backend, CSS custom properties theming, file-based CMS (content/ directory with markdown + YAML), and Docker + Caddy deployment. The Projekt-KIQ-HP reference (cloned at reference/Projekt-KIQ-HP/) serves as a code reference for visual patterns (glass morphism, animated background, bottom dock, bento grid).
Tasks
-
1. Project scaffolding and core infrastructure
-
1.1 Initialize project with Vite 8 + React 19 and configure tooling
- Create new repository
andreknie.de/withnpm create vite@latest(React template) - Install dependencies: react-router-dom v7, vite (v8), vitest, fast-check, @testing-library/react
- Configure
vite.config.jswith plugin slot for content loader - Create
.env.examplewith SMTP and server config placeholders - Set up
vitest.config.jswith jsdom environment - Requirements: 18.1, 18.2
- Create new repository
-
1.2 Create CSS theming system with custom properties
- Create
src/index.csswith full:rootvariable block (colors, spacing, typography, transitions, radii) - Use placeholder neutral blue (
#4a9eff) as accent color - Define glass morphism utility classes (
.glass-panel,.text-gradient,.bento-glow) - Import Inter font from Google Fonts
- Implement dark theme base (
--bg-color: #0a0a0a) - Requirements: 17.1, 17.2
- Create
-
1.3 Create directory structure for content, server, and plugins
- Create
content/with subdirectories: posts/, kniepunkt/, podcast/, talks/, consulting/, resources/, events/, meta/ - Create
public/with subdirectories: images/, logos/, resources/, patterns/ - Create
server/with subdirectories: routes/, middleware/, services/, data/ - Create
plugins/directory - Create
src/with subdirectories: components/, pages/, hooks/, utils/, data/ - Requirements: 14.1, 14.3
- Create
-
1.4 Create sample content files for all content types
- Create
content/meta/profile.yamlwith stakeholder profile data (name, roles, summary, positioning, dHive info) - Create
content/meta/stats.yamlwith key facts (50+ Projekte, 13+ Jahre KI, 60+ Publikationen, 100% DSGVO & AI-Act) - Create
content/meta/audiences.yamlwith target audience descriptions - Create at least 1 sample file per content type (post, kniepunkt issue, podcast episode, talk, consulting example, resource, event)
- Follow exact YAML/frontmatter schemas from design document
- Requirements: 1.1, 1.2, 1.4, 2.1, 14.1, 15.1
- Create
-
-
2. Vite content plugin and content utilities
-
2.1 Implement
plugins/vite-plugin-content.jsfor build-time content transformation- Read all files from
content/subdirectories at build time - Parse markdown files with frontmatter (gray-matter) into JSON (title, date, tags, summary, body as HTML via marked/remark)
- Parse YAML files into JSON objects
- Validate required fields per content type (warn on missing, don't fail build)
- Export transformed content as virtual modules importable by React components
- Requirements: 14.1, 14.2, 14.3
- Read all files from
-
2.2 Implement
src/utils/contentLoader.jsfor runtime content access- Implemented as
src/hooks/useContent.js(loading by type, sorting by date desc, tag filtering) - Create utility functions to load content by type (getPosts, getTalks, getConsultingExamples, etc.)
- Implement sorting by publication date descending (newest first)
- Implement tag extraction for dynamic filter options (max 20 distinct tags)
- Implement content-area validation (reject invalid content-area values with error message)
- Requirements: 13.4, 13.5, 14.4, 14.5
- Implemented as
-
* 2.3 Write property tests for content transformation and validation (Property 10)
- Property 10: Content file validation
- Generate arbitrary content objects with random missing/invalid fields
- Assert: missing required attributes → rejection with error indicating missing fields
- Assert: invalid content-area → rejection with error listing valid areas
- Validates: Requirements 9.4, 14.1, 14.4
-
* 2.4 Write property tests for content list sorting (Property 2)
- Property 2: Content list sorting
- Generate arbitrary lists of content objects with random dates
- Assert: output is always sorted by publication date descending
- Validates: Requirements 3.3, 7.3, 8.2, 14.5
-
* 2.5 Write property tests for dynamic filter derivation (Property 8)
- Property 8: Dynamic filter options derived from content
- Generate arbitrary sets of content objects with random tags
- Assert: available filter options = complete set of distinct tags (up to 20)
- Validates: Requirements 13.4, 13.5
-
-
3. Checkpoint — Content pipeline verified
- Ensure all tests pass, ask the user if questions arise.
-
4. Shared UI components
-
4.1 Implement BackgroundPattern, GlassCard, and BentoGrid components
- BackgroundPattern implemented (canvas particle field); glass/grid realized via
.glass-panelutility + per-page grids BackgroundPattern.jsx+.css: animated drifting SVG background (mirrored-quadrant technique from reference)GlassCard.jsx+.css: reusable glass-morphism card with backdrop-filter blurBentoGrid.jsx+.css: responsive grid layout for content cards with hover glow effect- Reference: Projekt-KIQ-HP patterns for visual implementation
- Requirements: 17.1, 17.2
- BackgroundPattern implemented (canvas particle field); glass/grid realized via
-
4.2 Implement Navigation and BottomDock components
- Navigation uses written-out top-bar links (no hamburger overlay, per stakeholder preference)
Navigation.jsx+.css: top bar with logo + hamburger overlay menu (same overlay pattern from reference)BottomDock.jsx+.css: fixed bottom navigation pill with rotating conic-gradient light border- Navigation items: Home, Kniepunkt, Podcast, Speaking, Consulting, Resources, Kontakt
- Requirements: 1.1
-
4.3 Implement Footer with dHive cross-reference and newsletter form slot
Footer.jsx+.css: CTA section + newsletter form slot + legal links (Impressum, Datenschutz)- Include visible link to d-hive.de with stakeholder role (Founder & Managing Director)
- dHive branding ≤ 20% of section area, positioned after personal name/title
- Link opens in new tab (
target="_blank") - Requirements: 16.1, 16.2, 16.3
-
4.4 Implement ContentFilter and Pagination components
- OPEN: dedicated ContentFilter, Pagination, SEOHead components not yet implemented (ScrollToTop exists)
ContentFilter.jsx+.css: tag-based filtering UI, derives options dynamically from content metadataPagination.jsx+.css: page navigation for lists (10 items per page)ScrollToTop.jsx: scroll restoration on route changeSEOHead.jsx: meta tags per page- Requirements: 13.1, 13.2, 13.3, 8.3
-
* 4.5 Write property tests for content filtering (Property 7)
- Property 7: Content filtering returns only matching items
- Generate arbitrary content sets with random tags and arbitrary filter selections
- Assert: filtered result contains exactly those items whose tags include the selected criterion
- Validates: Requirements 13.1, 13.2
-
* 4.6 Write property tests for pagination (Property 12)
- Property 12: Pagination constraint
- Generate arbitrary lists of items (length 0–100)
- Assert: each page contains at most 10 items; pagination controls present when items > 10
- Validates: Requirements 8.3
-
-
5. App shell and routing
-
5.1 Implement App.jsx with react-router-dom v7 routing
- Set up
App.jsxwith BackgroundPattern, Navigation, Routes, Footer, BottomDock - Configure routes:
/,/kniepunkt,/kniepunkt/:slug,/podcast,/speaking,/consulting,/resources,/kontakt,/impressum,/datenschutz - Add 404 fallback route with friendly error page
- Implement
main.jsxentry point with BrowserRouter - Requirements: 3.4, 18.4
- Set up
-
5.2 Implement custom hooks (useContent, useFormSubmit)
- useContent, useFormSubmit, validation.js, formatDate.js all present
src/hooks/useContent.js: content loading, filtering by tag, sorting, paginationsrc/hooks/useFormSubmit.js: form submission with validation, error handling, loading statesrc/utils/validation.js: email format validation, field presence checks, length constraintssrc/utils/formatDate.js: German locale date formatting- Requirements: 13.1, 13.2, 4.4, 11.5, 12.5
-
-
6. Page implementations — Home and content pages
-
6.1 Implement HomePage with Hero, Stats, ContentHighlights, AudienceSection, CTASection
- Home includes Hero, StatsCube, photo-band, Mein-Ansatz (positioning), Audiences, LogoMarquee, Testimonials, UpcomingEvents
Hero.jsx: stakeholder name, professional photo, summary (≤150 words), all roles listedStats.jsx: key facts from stats.yaml in animated countersAudienceSection.jsx: explicitly name target audiences (mid-sized companies, HR, OD, IT leaders, managing directors)ContentHighlights.jsx: latest content from each areaCTASection.jsx: call-to-action for contact/speaking- Profile visible without scrolling on 1280×720 viewport
- Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 2.1, 2.3, 2.4, 17.3, 17.4, 17.5
-
6.2 Implement KniepunktPage and KniepunktIssuePage
Kniepunkt.jsx: distinct labeled section, list of all newsletter issues (title + date), sorted newest first, with ContentFilterKniepunktIssue.jsx: full rendered markdown content of selected issue- Visually separated from other homepage content
- Requirements: 7.1, 7.2, 7.3, 7.4
-
6.3 Implement PodcastPage
- 12 episodes with Spotify/Apple/YouTube/Castro links
Podcast.jsx: visually distinct section with podcast name, description, episode listing- Episodes: title, date, summary, sorted reverse-chronological
- Max 10 episodes per page with Pagination component
- Each episode links to audio on hosting platform or embedded player
- Empty state message when no episodes available
- Requirements: 8.1, 8.2, 8.3, 8.4, 8.5
-
6.4 Implement SpeakingPage with talk list and talk request form
Speaking.jsx: list of talks with topic title, description, format (keynote/workshop/panel), past events- Show at least 3 speaking examples with topic title, event name, and format
- Include TalkRequestForm component (implemented in task 7)
- Hide section if no talks available
- Requirements: 2.2, 5.1, 5.2, 5.3, 5.4
-
6.5 Implement ConsultingPage
- ServiceAccordion + 3 consulting examples (OPEN: more examples per MATERIAL-LISTE)
Consulting.jsx: BentoGrid of ExampleCards (3–10 examples)- Each card: title, industry tag, org-size category (50–5000 employees), problem domain, approach, outcomes
- No client names, revenue figures, or internal identifiers exposed
- Informational message if no examples available
- Requirements: 6.1, 6.2, 6.3, 6.4
-
6.6 Implement ResourcesPage with lead capture
- OPEN: no resource content files yet (content/resources/ empty)
Resources.jsx: list of resources with title, short description (≤200 chars), download indicatorLeadCaptureForm.jsx: modal form requiring name (max 100), email (validated), company (max 150)- Display required fields and purpose before submission
- Inline validation errors with data retention on failure
- Requirements: 4.1, 4.2, 4.3, 4.4, 4.6
-
6.7 Implement ContactPage, Impressum, and Datenschutz
- OPEN: Impressum/Datenschutz contain placeholder legal data (needs real address, USt-IdNr)
Contact.jsx: contact form with name, email, message (max 2000 chars), validation errors per fieldImpressum.jsx: static legal contentDatenschutz.jsx: static privacy policy content- Requirements: 11.1, 11.5
-
6.8 Implement Events display (within relevant pages or as section)
- UpcomingEvents component exists, but content/events/ is empty — OPEN: add event content
- Display events grouped by year, upcoming before past, each group sorted by date descending
- Each event: title, date (ISO 8601), location, event type, description (≤300 chars)
- Requirements: 9.1, 9.2, 9.3
-
* 6.9 Write property tests for content rendering completeness (Property 1)
- Property 1: Content rendering completeness
- Generate arbitrary content objects per type with all required fields
- Assert: rendered output contains all required fields for that type
- Validates: Requirements 3.1, 3.2, 3.5, 4.1, 5.2, 6.1, 6.3, 7.2, 8.2, 8.4
-
* 6.10 Write property tests for event chronological grouping (Property 9)
- Property 9: Event chronological grouping
- Generate arbitrary event sets with dates spanning past and future
- Assert: upcoming events appear before past events; each group sorted by date descending; grouped by year
- Validates: Requirements 9.2
-
-
7. Checkpoint — Frontend pages complete
- Ensure all tests pass, ask the user if questions arise.
-
8. Express 5 backend — form handling and confirmation flow
-
8.1 Set up Express 5 server with middleware
server/index.js: Express 5 entry point with JSON body parsing, CORS, error middlewareserver/middleware/rateLimiter.js: rate limiting per endpoint (contact: 3/h, talk: 3/h, newsletter: 5/h, resource: 10/h)server/middleware/validator.js: input validation middleware (field presence, email format, length constraints)- Health check endpoint:
GET /api/health - Requirements: 11.1, 12.1
-
8.2 Implement confirmation token service
server/services/confirmationToken.js: generate unique tokens (crypto.randomUUID), store with expiration, verify, cleanup expired- Token storage in JSON files under
server/data/ - Contact tokens expire after 24h, talk request and newsletter tokens after 48h
- Scheduled cleanup interval (every hour) for expired tokens
- Requirements: 10.3, 10.4, 11.2, 11.4, 12.2, 12.4
-
8.3 Implement mailer service with nodemailer
server/services/mailer.js: nodemailer configuration from environment variables- Email templates: confirmation email (with unique link), stakeholder notification email
- Send exactly one confirmation email per valid submission
- Requirements: 10.3, 11.2, 12.2
-
8.4 Implement contact form route with double opt-in
server/routes/contact.js: POST/api/contact— validate, store pending, send confirmation email- POST
/api/contact/confirm/:token— verify token, forward message to stakeholder, mark confirmed - Reject expired/invalid tokens with appropriate status codes (404/410)
- Requirements: 11.1, 11.2, 11.3, 11.4, 11.5
-
8.5 Implement talk request route with double opt-in
server/routes/talk-request.js: POST/api/talk-request— validate (name, email, event_name, topic, message), store pending, send confirmation- POST
/api/talk-request/confirm/:token— verify token (48h), forward to stakeholder - Requirements: 12.1, 12.2, 12.3, 12.4, 12.5
-
8.6 Implement newsletter signup route with double opt-in
server/routes/newsletter.js: POST/api/newsletter— validate email, check for existing subscription, store pending, send confirmation- GET
/api/newsletter/confirm/:token— verify token (48h), activate subscription, create Sales_Funnel entry - Detect and reject duplicate subscriptions with informational message
- Discard unconfirmed subscriptions after 48h
- Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6
-
8.7 Implement resource download route with lead capture
server/routes/resource-download.js: POST/api/resource-download— validate (name, email, company, resource_id), store lead record with timestamp, return download URL- Lead record must be retrievable for Sales_Funnel development
- Requirements: 4.2, 4.3, 4.5
-
* 8.8 Write property tests for form validation (Property 3)
- Property 3: Form validation rejects invalid input
- Generate arbitrary form payloads with random missing/invalid fields
- Assert: invalid submissions are rejected with field-level errors; valid data retained
- Validates: Requirements 4.4, 10.5, 11.5, 12.5
-
* 8.9 Write property tests for token expiration (Property 4)
- Property 4: Confirmation token expiration
- Generate tokens with arbitrary creation times and verify against expiration windows
- Assert: expired tokens are rejected; associated records discarded
- Validates: Requirements 10.4, 11.4, 12.4
-
* 8.10 Write property tests for valid submission triggering confirmation (Property 5)
- Property 5: Valid submission triggers confirmation email
- Generate arbitrary valid form submissions (all fields present, valid email)
- Assert: unique token generated, pending request stored, exactly one confirmation email sent
- Validates: Requirements 10.3, 11.2, 12.2
-
* 8.11 Write property tests for valid token confirmation (Property 6)
- Property 6: Valid token confirmation forwards to stakeholder
- Generate valid unexpired tokens with associated pending records
- Assert: confirmation results in forwarding to stakeholder and record marked confirmed
- Validates: Requirements 11.3, 12.3
-
* 8.12 Write property tests for lead data storage (Property 11)
- Property 11: Lead data storage integrity
- Generate arbitrary valid lead capture submissions
- Assert: stored record contains all submitted fields + resource_id + timestamp; record is retrievable
- Validates: Requirements 4.5
-
* 8.13 Write property tests for duplicate subscription detection (Property 13)
- Property 13: Duplicate subscription detection
- Generate arbitrary email addresses, some already in active subscriptions
- Assert: duplicate emails are rejected with informational message; no duplicate entry created
- Validates: Requirements 10.6
-
-
9. Checkpoint — Backend API complete
- Ensure all tests pass, ask the user if questions arise.
-
10. Integration and wiring
-
10.1 Wire frontend forms to backend API endpoints
- useFormSubmit posts to /api endpoints with success/error handling
- Connect ContactForm to POST
/api/contact - Connect TalkRequestForm to POST
/api/talk-request - Connect NewsletterForm to POST
/api/newsletter - Connect LeadCaptureForm to POST
/api/resource-download - Handle success/error responses with appropriate UI feedback (toast notifications, success messages)
- Requirements: 10.1, 11.1, 12.1, 4.2
-
10.2 Create confirmation landing pages
- OPEN: inline success messages exist, but dedicated email-confirmation landing pages / token-confirm routes in the SPA are not yet built
- Success page shown after email confirmation (contact, talk request)
- Newsletter confirmation success page
- Expired/invalid token error page
- Requirements: 11.2, 11.3, 12.2, 12.3
-
* 10.3 Write integration tests for form submission flows
- Test contact form: submit → pending stored → confirmation email triggered
- Test talk request: submit → pending stored → confirmation email triggered
- Test newsletter: submit → pending stored → double opt-in email triggered
- Test resource download: submit lead data → lead stored → download URL returned
- Requirements: 10.2, 10.3, 11.2, 11.3, 12.2, 12.3, 4.5
-
-
11. Deployment configuration
-
11.1 Create Dockerfile and docker-compose.yml for backend
- Dockerfile: Node.js image, install dependencies, run Express server on port 3003
- docker-compose.yml: single
backendservice, volume mount forserver/data/, env file reference - Requirements: 18.1
-
11.2 Create Caddyfile for production serving
- Auto HTTPS via Let's Encrypt for andreknie.de
- Reverse proxy
/api/*to Express backend on port 3003 - Serve static SPA files with
try_files {path} /index.html - Security headers (HSTS, X-Content-Type-Options, CSP)
- Gzip/zstd compression
- Immutable cache for
/assets/* - Requirements: 18.4
-
11.3 Configure Vite build with content plugin integration
- vite-plugin-content registered;
npm run buildproduces complete dist/ (verified) - Register
vite-plugin-contentinvite.config.js - Verify
npm run buildproduces completedist/with all content embedded - Ensure build output is deployable as static files to
/opt/andreknie/site/ - Requirements: 14.2
- vite-plugin-content registered;
-
-
12. Final checkpoint — Full integration verified
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks marked with
*are optional and can be skipped for faster MVP - Each task references specific requirements for traceability
- Checkpoints ensure incremental validation
- Property tests validate universal correctness properties from the design document (13 properties total)
- Unit tests validate specific examples and edge cases
- The project is created as a NEW repository — not inside the current CV workspace
- Use
reference/Projekt-KIQ-HP/as visual pattern reference (glass morphism, animated background, bottom dock, bento grid) - Colors are placeholder (neutral blue #4a9eff) — easily changeable via CSS custom properties in
:root - Content files in
content/ARE the CMS — no database needed for content - Backend only handles forms (contact, talk request, newsletter, resource download)
- All forms use double opt-in (confirmation email with token)
- fast-check is the property-based testing library; Vitest is the test runner
Task Dependency Graph
{
"waves": [
{ "id": 0, "tasks": ["1.1", "1.3"] },
{ "id": 1, "tasks": ["1.2", "1.4"] },
{ "id": 2, "tasks": ["2.1"] },
{ "id": 3, "tasks": ["2.2", "2.3", "2.4", "2.5"] },
{ "id": 4, "tasks": ["4.1", "4.2", "4.3", "4.4", "5.1"] },
{ "id": 5, "tasks": ["4.5", "4.6", "5.2"] },
{ "id": 6, "tasks": ["6.1", "6.2", "6.3", "6.4", "6.5", "6.6", "6.7", "6.8"] },
{ "id": 7, "tasks": ["6.9", "6.10", "8.1"] },
{ "id": 8, "tasks": ["8.2", "8.3"] },
{ "id": 9, "tasks": ["8.4", "8.5", "8.6", "8.7"] },
{ "id": 10, "tasks": ["8.8", "8.9", "8.10", "8.11", "8.12", "8.13"] },
{ "id": 11, "tasks": ["10.1", "10.2"] },
{ "id": 12, "tasks": ["10.3", "11.1", "11.2", "11.3"] }
]
}
Offene Themen (Stand-Abgleich)
Die Kernimplementierung (Frontend-Seiten, Backend-Formulare mit Double-Opt-In, Content-Pipeline, Deployment-Konfiguration) steht und baut fehlerfrei. Offen sind im Wesentlichen Inhalte, Verifikation und optionale Tests.
Inhalte / Redaktion (blockiert Go-Live)
- Impressum mit echten Daten füllen — Telefon entfernt, E-Mail kontakt@d-hive.de (Task 6.7)
- Datenschutzerklärung final juristisch prüfen — Inhalt vorhanden, Telefon entfernt, datenschutz@d-hive.de für Betroffenenrechte (Task 6.7)
- Weitere Consulting-Beispiele (Ziel 5+, aktuell 3) inkl. Leistungsübersicht & Ergebnis-Zahlen (Task 6.5, MATERIAL-LISTE) — in Arbeit beim Stakeholder
- Testimonials final freigeben (3 Entwürfe vorhanden, Freigabe der Personen ausstehend) — in Arbeit beim Stakeholder
Nice to have (Inhalte, kein Go-Live-Blocker)
- Event-Inhalte ergänzen —
content/events/ist leer (Task 6.8) - Resource-Inhalte ergänzen —
content/resources/ist leer (Task 6.6)
Funktionale Lücken
- Dedizierte ContentFilter-, Pagination- und SEOHead-Komponenten (Task 4.4)
- Confirmation-Landingpages im SPA (Token-Confirm-Routen, Erfolg/Abgelaufen) — bisher nur Inline-Erfolgsmeldungen (Task 10.2)
Verifikation & Deployment
- Backend lokal end-to-end testen (Formular → Bestätigungsmail → Weiterleitung); SMTP-Konfiguration in
.enverforderlich - Produktiv-Deployment durchführen (dist/ auf Server, Docker-Backend starten, Caddy)
Optionale Property-/Integrationstests (mit * markiert, MVP-übersprungen)
- 2.3, 2.4, 2.5 — Content-Validierung, Sortierung, Filter-Ableitung
- 4.5, 4.6 — Filterung, Pagination
- 6.9, 6.10 — Rendering-Vollständigkeit, Event-Gruppierung
- 8.8–8.13 — Formularvalidierung, Token-Ablauf, Bestätigungsmail, Lead-Speicherung, Duplikat-Erkennung
- 10.3 — Integrationstests der Formular-Flows
Material (siehe andreknie.de/MATERIAL-LISTE.md)
- Professionelles Hero-/Profilbild (freigestellt) — aktuell Platzhalter
andre-knie.jpg - Open-Graph-Image, Favicon
- Optional: Hero-Video, Testimonial-Videos, Podcast-Cover