Replace PathResourceResolver SPA fallback with SpaController that injects OG/Twitter meta-tags into cached index.html template. Event pages get event-specific tags (title, date, location), all other pages get generic fete branding. Includes og-image.png brand asset and forward-headers-strategy for proxy support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.7 KiB
2.7 KiB
Data Model: Link Preview (Open Graph Meta-Tags)
Feature: 012-link-preview | Date: 2026-03-09
Overview
This feature does NOT introduce new database entities. It reads existing event data and projects it into HTML meta-tags. The "model" here is the meta-tag value object used during HTML generation.
Meta-Tag Value Objects
OpenGraphMeta
Represents the set of Open Graph meta-tags to inject into the HTML response.
| Field | Type | Source | Rules |
|---|---|---|---|
title |
String | Event title or "fete" | Max 70 chars, truncated with "..." |
description |
String | Composed from event fields or generic text | Max 200 chars |
url |
String | Canonical URL from request | Absolute URL |
type |
String | Always "website" | Constant |
siteName |
String | Always "fete" | Constant |
image |
String | Static brand image URL | Absolute URL to /og-image.png |
TwitterCardMeta
| Field | Type | Source | Rules |
|---|---|---|---|
card |
String | Always "summary" | Constant |
title |
String | Same as OG title | Max 70 chars |
description |
String | Same as OG description | Max 200 chars |
Data Flow
Request for /events/{token}
│
▼
LinkPreviewController
│
├── Resolve event token → Event domain object (existing EventRepository)
│
├── Build OpenGraphMeta from Event fields:
│ title ← event.title (truncated)
│ description ← formatDescription(event.dateTime, event.timezone, event.location, event.description)
│ url ← request base URL + /events/{token}
│ image ← request base URL + /og-image.png
│
├── Build TwitterCardMeta (mirrors OG values)
│
├── Inject meta-tags into cached index.html template
│
└── Return modified HTML
Request for / or /create (non-event pages)
│
▼
LinkPreviewController
│
├── Build generic OpenGraphMeta:
│ title ← "fete"
│ description ← "Privacy-focused event planning. Create and share events without accounts."
│ url ← request URL
│ image ← request base URL + /og-image.png
│
├── Build generic TwitterCardMeta
│
├── Inject meta-tags into cached index.html template
│
└── Return modified HTML
Existing Entities Used (Read-Only)
Event (from de.fete.domain.model.Event)
| Field | Used For |
|---|---|
title |
og:title, twitter:title |
description |
Part of og:description, twitter:description |
dateTime |
Part of og:description (formatted) |
timezone |
Date formatting context |
location |
Part of og:description |
eventToken |
URL construction |