All checks were successful
build-and-push / build (push) Successful in 15m15s
Authentication & RBAC
- Add confidential OIDC client (Authentik) with /auth/oidc/login +
/auth/oidc/callback: discovery, code exchange, id_token verify (go-oidc),
groups claim → role (Archivum-admin → admin, else user). Sessions carry groups.
- Rework ACL into an allow/deny model (new `effect` column + migration).
db.EffectiveAccess resolves user + all groups over the path and its ancestors:
default deny, explicit deny always beats allow.
- Enforce ACL for ALL non-admin users (not just guest) across list/read/save/
delete/move/create/history/diff/images/upload. Admins bypass.
- Seed built-in Archivum-admin / Archivum-reader groups; login allow-list on
users & groups; public (guest) user access is ACL-configurable.
Admin API & UI
- New GraphQL ops: oidcConfig/updateOidcConfig, group CRUD, membership,
setUserRole/setUserLogin/setGroupLogin, userGroups, loginOptions.
- Rebuilt AdminView: SSO config, user/group management + membership, login
toggles, and an allow/deny access-control matrix per path.
- LoginView: "Sign in with Authentik" + public-user option; OIDC callback route.
Rendering/editor
- Fix bug where inline marks (bold/italic/code/strike/link) were dropped on
TipTap→AsciiDoc save. Add RENDERING_IMPROVEMENTS.md with proposals.
CI / build
- .gitea/workflows/build.yaml: build on the Pi5 runner, push
localhost:5000/archivum:{latest,<sha>}. Add .dockerignore; bump Go image to 1.25.
- Docs: ARCHITECTURE.md, README.md, docs/AUTHENTIK_SETUP.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
121 lines
6.0 KiB
Markdown
121 lines
6.0 KiB
Markdown
# Förbättringsförslag — rendering & editor
|
||
|
||
Genomgång av renderings- och editorlagret (`frontend/src/bridge/*`,
|
||
`components/editor/*`) med konkreta, prioriterade förslag. En bekräftad bugg är
|
||
redan åtgärdad i denna gren (se punkt 0).
|
||
|
||
---
|
||
|
||
## 0. ÅTGÄRDAD bugg: inline-formatering tappades vid sparning
|
||
|
||
I `asciidoc-bridge.ts → renderTextNodes` byggdes den markerade strängen
|
||
(`*fet*`, `_kursiv_`, `` `kod` ``, länkar) men **lades aldrig till utdata** — i
|
||
stället lades den *omarkerade* texten till i ett andra `if`-block. Följd: all
|
||
inline-formatering försvann tyst varje gång ett dokument sparades från den
|
||
visuella editorn. Nu appliceras och skrivs marks korrekt (en enda gång).
|
||
|
||
> Rekommendation: lägg ett litet round-trip-test (`adoc → toTipTap → fromTipTap`)
|
||
> som CI-steg så att den här klassen av regressioner fångas automatiskt.
|
||
|
||
---
|
||
|
||
## 1. Round-trip-modellen är den största risken
|
||
|
||
Idag är flödet vid varje sparning:
|
||
|
||
```
|
||
.adoc ──asciidoctor.convert──▶ HTML ──generateJSON──▶ TipTap-JSON
|
||
▲ │
|
||
└─────────── fromTipTap (handskriven) ◀──────────────────┘
|
||
```
|
||
|
||
Två lossy konverteringar i rad. Allt som TipTap-schemat inte känner till
|
||
(attribut, `ifdef`/`ifeval`, `:attribut:`-definitioner, block-roller, kommentarer,
|
||
tabellformat, korsreferenser) går förlorat så fort man öppnar och sparar i den
|
||
visuella vyn.
|
||
|
||
**Förslag (välj en):**
|
||
- **A. Källan är sanningen.** Behandla `.adoc` som master. Visuella editorn får
|
||
bara redigera dokument som är "rena" (kan round-trippa förlustfritt), annars
|
||
öppnas källeditorn. Visa en varning "det här dokumentet innehåller avancerad
|
||
AsciiDoc — redigera i källvyn".
|
||
- **B. Patch-baserad sparning.** Spara bara de block som faktiskt ändrats i den
|
||
visuella vyn i stället för att reserialisera hela dokumentet.
|
||
- **C. Byt serialisering.** Använd en riktig AST (t.ex. `downdoc`/`@asciidoctor`
|
||
reducer) i stället för den handskrivna `TipTapToAsciidoc`-klassen.
|
||
|
||
Minst arbete/störst nytta på kort sikt: **A** + en tydlig indikator i UI.
|
||
|
||
---
|
||
|
||
## 2. Konkreta serialiseringsluckor i `fromTipTap`
|
||
|
||
| Nod / mark | Problem | Förslag |
|
||
|------------|---------|---------|
|
||
| Kombinerade marks (fet+kursiv) | Ger `*_text_*` — bräckligt intill andra tecken | Använd oконstruerad syntax (`**`, `__`) vid behov |
|
||
| Tabeller (`convertTable`) | Ingen header-rad (`[%header]`), inga kolumn-specar, colspan/align tappas | Detektera `tableHeader`, skriv `[options="header"]`, `cols=` |
|
||
| Listor (`convertListItem`) | Blandning av stycke + nästlad lista i samma item blir fel; principallista använder nivå-räkning som spretar | Rendera item-innehåll block för block med `+`-continuation för flerstycke |
|
||
| `blockquote` | Attribution/citat-källa tappas | Stöd `[quote, author, source]` |
|
||
| `admonition` | Bara 5 typer, alltid versalt block-format | Bevara ursprunglig form (inline `NOTE:` vs `[NOTE]`-block) |
|
||
| Bild | `role`/alignment/`link=` tappas | Utöka `AsciidocImage`-attribut och serialisering |
|
||
|
||
---
|
||
|
||
## 3. Renderingspipelinen (adoc → HTML)
|
||
|
||
- **Regex-omskrivning av admonitions** (`htmlContent.replace(/<div class="admonitionblock…`)
|
||
är känslig för nästlat innehåll och flera stycken. En admonition med en lista
|
||
eller ett kodblock inuti går sönder. → Rendera i stället admonitions via en
|
||
Asciidoctor-**converter/extension** i stället för att patcha HTML i efterhand.
|
||
- **`include::`** hanteras med regex och blir en platshållare. Riktiga includes
|
||
(t.ex. återanvändbara fragment) renderas aldrig. → Implementera en
|
||
include-resolver på backend (den har redan fil-I/O) och rendera server-side,
|
||
eller hämta fragmentet via API innan `convert`.
|
||
- **Passthrough (`+++`)**: fotnötter injiceras som rå-HTML före parsing. Fungerar,
|
||
men kringgår sanering. Låg risk internt, men värt en `DOMPurify` på
|
||
renderad HTML om publika/gäst-användare någonsin ska se opålitligt innehåll.
|
||
|
||
---
|
||
|
||
## 4. Prestanda / bundle
|
||
|
||
`DocumentView`-chunken är **~2,8 MB** (880 kB gzip). Två tunga poster:
|
||
|
||
- **`lowlight` med `all`** (`createLowlight(all)`) drar in *alla* språkgrammatiker.
|
||
→ Byt till `common` eller registrera bara de språk ni faktiskt använder
|
||
(go, js, ts, bash, python, yaml…). Sparar hundratals kB.
|
||
- **`asciidoctor.js`** är stort och laddas i varje dokumentvy. → Lazy-load
|
||
(`import()` först när ett dokument öppnas) — delvis redan gjort via
|
||
route-splitting, men Asciidoctor kan brytas ut ytterligare. Överväg
|
||
server-side-rendering av HTML (backend har redan Go; ett litet
|
||
`asciidoctor`-anrop eller cache av renderad HTML per commit-hash skulle ta bort
|
||
klientkostnaden helt och göra läsvyn snabb även på Pi5/mobil).
|
||
|
||
---
|
||
|
||
## 5. Editor-UX (presentation)
|
||
|
||
- **Synk mellan Visual och Source.** Gör "source of truth"-valet (punkt 1)
|
||
synligt: en toggle med en varningsikon när dokumentet inte kan round-trippa.
|
||
- **Live-förhandsvisning i källeditorn.** CodeMirror till vänster, renderad HTML
|
||
till höger (delad vy) — vanligt och uppskattat för teknisk dokumentation.
|
||
- **Innehållsförteckning / rubriknavigering.** Generera en TOC från rubrikerna
|
||
(finns redan `id` på `CustomHeading`) och visa i sidopanelen.
|
||
- **Bildhantering.** Uppladdning finns; lägg till drag-and-drop och inklistring
|
||
från urklipp direkt i editorn.
|
||
- **Autospar / utkast.** Spara utkast lokalt (IndexedDB) så inget tappas vid
|
||
session-timeout (sessioner ligger bara i minnet på servern).
|
||
- **Diff-vy i redigering.** `HistoryPanel`/`DiffViewer` finns — koppla en
|
||
"jämför med sparad version"-knapp direkt i editorn.
|
||
|
||
---
|
||
|
||
## Prioriteringsordning (rekommenderad)
|
||
|
||
1. ✅ Fixa marks-buggen (klar).
|
||
2. Lägg round-trip-test i CI.
|
||
3. Byt `lowlight` `all` → `common`/whitelist (snabb, stor bundle-vinst).
|
||
4. Inför "source of truth"-indikator + öppna källvyn för avancerade dokument.
|
||
5. Server-side- eller cachead HTML-rendering (störst läs-prestandavinst).
|
||
6. Robustare tabell-/list-serialisering.
|