Spezifikation v0.2 als lebendes Dokument + Ansicht in der App
Deploy App / deploy (push) Successful in 3m10s

Neue Funktionale/Technische Spezifikation (SPEZIFIKATION.md) mit
Aenderungshistorie; ersetzt die bisherigen FDD/TDD-Dokumente v1-v5.

In der App unter dem Menueintrag "SPEZIFIKATION" (Sidebar, unter den Plaenen)
lesbar: /api/spec liefert das Markdown, SpecView rendert es. Styling ueber die
bestehenden Farb-Tokens, folgt damit allen drei Schemata.

Die MD-Datei war ueber .dockerignore (*.md) vom Image ausgeschlossen -> Ausnahme
ergaenzt und Kopie in die Runner-Stage aufgenommen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 22:22:44 +02:00
parent dfebbeb397
commit 87e6a5f564
9 changed files with 3422 additions and 10 deletions
+50
View File
@@ -0,0 +1,50 @@
"use client";
import { useEffect, useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import rehypeSlug from "rehype-slug";
import { FileText } from "lucide-react";
import { api } from "@/lib/api-client";
// Rendert SPEZIFIKATION.md (via /api/spec) als lesbares Dokument. Das Styling laeuft ueber
// die Klasse .md-doc in globals.css und folgt damit dem gewaehlten Farbschema.
export function SpecView() {
const [markdown, setMarkdown] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
api
.get<{ markdown: string }>("/api/spec")
.then((data) => setMarkdown(data.markdown))
.catch((e) => setError(e instanceof Error ? e.message : "Laden fehlgeschlagen."));
}, []);
if (error) return <p className="text-sm text-danger">{error}</p>;
if (markdown === null) return <p className="text-sm text-muted">Laedt</p>;
return (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-2">
<FileText className="h-5 w-5 text-accent" />
<h2 className="text-lg font-semibold text-fg">Spezifikation</h2>
</div>
<article className="md-doc rounded-xl border border-border bg-surface p-6 shadow-sm lg:p-8">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeSlug]}
components={{
// Breite Tabellen scrollen in ihrem eigenen Container statt die Seite zu dehnen.
table: ({ children, ...props }) => (
<div className="md-table-wrap">
<table {...props}>{children}</table>
</div>
),
}}
>
{markdown}
</ReactMarkdown>
</article>
</div>
);
}