Ajoute le pipeline PageSpec (validation, rendu, publication /p/{slug}),
les démos TipTap /demo, et le simulateur Carnot (modes frigo/PAC/moteur,
énergie kJ vs puissance W, unités K/°C/°F) avec correctifs d’équations KaTeX.
Co-authored-by: Cursor <cursoragent@cursor.com>
30 lines
1.6 KiB
Markdown
30 lines
1.6 KiB
Markdown
# Publication — point de branchement `interactive-page`
|
||
|
||
## Canal existant (ne pas dupliquer)
|
||
|
||
| Élément | Emplacement |
|
||
|---|---|
|
||
| API | `app/api/notes/publish/route.ts` — `action: publish \| unpublish`, `mode?: simple \| ai \| interactive-page` |
|
||
| UI | `components/note-editor/note-editor-toolbar.tsx` (menu Globe) + `InteractivePagePublishDialog` |
|
||
| Page publique | `app/(public)/p/[slug]/page.tsx` → `/p/{publicSlug}` |
|
||
| Fetch | `getPublishedNote(slug)` dans `app/actions/notes-publishing.ts` |
|
||
| Templates | `lib/publish/types.ts` — `PUBLISH_TEMPLATES` = `magazine \| brief \| essay \| interactive-page` |
|
||
|
||
### Champs `Note` (Prisma)
|
||
|
||
- `isPublic`, `publicSlug`, `publishedAt`
|
||
- `publishedContent` — snapshot opaque (`String?`) : HTML aujourd’hui, **JSON PageSpecV1** pour `interactive-page`
|
||
- `publishedTemplate` — discriminant de rendu
|
||
- `publishedSourceHash` — détection stale (pas de régénération silencieuse)
|
||
|
||
## Branchement `interactive-page`
|
||
|
||
1. Étendre `PUBLISH_TEMPLATES` avec `'interactive-page'`.
|
||
2. Publish : générer/valider via `lib/interactive-page/` → stocker `JSON.stringify(PageSpecV1)` dans `publishedContent`, `publishedTemplate = 'interactive-page'`.
|
||
3. Rendu public : dans `PublishedNotePage`, si `publishedTemplate === 'interactive-page'` → parser → `<PageView spec={…} />` (SSR + hydrate démos).
|
||
4. Unpublish / stale : **même** cycle de vie que magazine/brief/essay (`publishedSourceHash` → badge « à régénérer »).
|
||
|
||
## Hors scope
|
||
|
||
- `NotebookSite` `/c/[slug]`, `NoteShare` (collab privée), server actions legacy `publishNote` incomplets.
|