Die Pocket-Seite beschrieb „Lese-Liste → URLs hinzufügen → Pocket-Export (.zip)". Diese Schaltflaeche gab es nie: kein Treffer fuer .zip, jszip oder eine Datei-Annahme im ganzen Web- und API-Code. Gleichzeitig lag der Bulk-Weg der API (POST /api/v1/imports, 200 je Auftrag) seit Lambda-5 fertig da — api.startBulkImport() war definiert und wurde von keiner Zeile aufgerufen. Also gebaut statt gestrichen: - $lib/url-list.ts zieht Adressen aus beliebigem Text (CSV, HTML-Ausfuhr, eingefuegte Liste). Bewusst kein Format-Erkenner — Spaltennamen unterscheiden sich je Dienst und je Jahr, Adressen nicht. Entdoppelt ueber Schluss-Schraegstrich, Fragment und Wirt-Schreibweise, wirft Bilder und Skripte raus. 13 Tests. - Neuer erster Abschnitt in /lese-liste/settings: Datei waehlen oder einfuegen, zaehlen, importieren. Ueber 200 Adressen laufen als mehrere Auftraege NACHEINANDER — parallel staenden bei 5000 Adressen 25 Auftraege in derselben Extraktions-Kette. Fortschritt, Abbruch, und beim Verlassen der Seite haelt die Schleife an. - ZIP wird nicht ausgepackt, und die Oberflaeche sagt das. Ein Test fand einen Fehler, den der Code nicht zeigte: der Adress-Sucher endet am Semikolon (es trennt in CSV und HTML die Felder), damit wurde "...?a=1&b=2" zu "...?a=1&". Entitaeten werden jetzt vor dem Suchen aufgeloest. Dazu drei Stellen, an denen Text und Stand auseinanderliefen: - getpocket.com/export ist zu (gemessen: 302 auf /home; Mozilla hat die Daten am 2025-11-12 geloescht). Die Seite schickte Leute trotzdem hin. Jetzt sagt sie, was heute noch geht. - Das PWA-Manifest bewarb "Feed, Lese-Liste, Recherche" und legte Verknuepfungen auf /feed und /recherche — beide ruhen seit 2026-06-01 und leiten weiter. Ein installiertes Symbol fuehrte ins Leere. - /konto sagte Gaesten, die Lese-Liste brauche ein Konto, und nannte die ruhende Recherche. Jetzt steht dort der Satz aus der i18n-Quelle, den auch die Native-App zeigt. - llms.txt versprach Maschinen ".zip inkl. Tags und Highlights" und "Export aller Daten als JSON jederzeit". Beides unwahr. Offen und nicht selbst entschieden: eine Ausfuhr der ganzen Liste auf Knopfdruck gibt es nirgends — der Text ist jetzt ehrlich, der Knopf fehlt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MhVjQpDUkFZGtFWsLid4PT
27 KiB
Pageta — Status
Letzter Stand: 2026-09-05. LIVE 🚀 + voll-featured
2026-09-05 — Der Umzugs-Weg gab es nur auf dem Papier
Ein Durchgang durch App, Landing und Doku hat eine Lücke gefunden, die niemand meldet, weil beide Seiten für sich stimmig aussahen: die Landing beschrieb einen Import, den die App nicht hatte.
/pocket-importsagte „Lese-Liste → ‚URLs hinzufügen' → ‚Pocket-Export (.zip)'". Diese Schaltfläche gab es nie. Im ganzen Web- und API-Code steht kein einziger Treffer für.zip,jszipoder eine Datei-Annahme.- Sie schickte Leute auf
getpocket.com/export. Gemessen am 2026-09-05: 302 auf/home. Mozilla hat den Export geschlossen und die Konten-Daten am 2025-11-12 gelöscht. Der Weg war also nicht nur unbeschrieben, er war zu. - Der Bulk-Weg der API (
POST /api/v1/imports, 200 je Auftrag) lag seit λ-5 fertig da — ohne jede Oberfläche.api.startBulkImport()war im Client definiert und wurde von keiner Zeile aufgerufen.
Gebaut statt gestrichen. Die Zusage war die richtige, nur ohne Umsetzung — also hat die App jetzt den Import, den die Landing versprach:
$lib/url-list.ts— zieht Adressen aus beliebigem Text (CSV, HTML- Ausfuhr, eingefügte Liste). Bewusst kein Format-Erkenner: die Spaltennamen unterscheiden sich je Dienst und je Jahr, Adressen nicht. Entdoppelt über Schluss-Schrägstrich, Fragment und Wirt-Schreibweise, wirft Bilder/Skripte raus. 13 Tests.- Neue Fläche in
/lese-liste/settings(erster Abschnitt): Datei wählen oder einfügen → zählen → importieren. Listen über 200 laufen als mehrere Aufträge nacheinander (nicht parallel — sonst stehen bei 5 000 Adressen 25 Aufträge gleichzeitig in derselben Extraktions-Kette). Fortschritt, Abbruch, und beim Verlassen der Seite hält die Schleife an. - ZIP wird nicht ausgepackt und die Oberfläche sagt das, statt eine Binärdatei zu durchsuchen und „nichts gefunden" zu melden.
🛑 Der Test hat einen Fehler gefunden, den der Code nicht zeigte: der
Adress-Sucher endet am Semikolon (es trennt in CSV und HTML die Felder) —
…?a=1&b=2 wurde damit zu …?a=1&. Entitäten werden jetzt VOR
dem Suchen aufgelöst. Ohne den einen Test wäre jede Adresse mit zwei
Abfrage-Feldern aus einer HTML-Ausfuhr still kaputt importiert worden.
Drei weitere Stellen, an denen Text und Stand auseinanderliefen:
- Das PWA-Manifest bewarb „Feed, Lese-Liste, Recherche" und legte
Verknüpfungen auf
/feedund/recherche. Beide ruhen seit 2026-06-01 und leiten weiter — ein installiertes Symbol führte ins Leere. Jetzt: Lese-Liste, Markierungen, Artikel speichern. /kontosagte Gästen „Lese-Liste, Markierungen und Recherche brauchen ein mana-Konto" — nannte die ruhende Recherche und widersprach der local-first-Zusage der eigenen i18n-Quelle. Jetzt steht dort der Satz ausmana/i18n/pageta.de.json, den auch die Native-App zeigt.llms.txtversprach Maschinen „Pocket-Import (.zip) inkl. Tags und Highlights" und „Export aller Daten als JSON jederzeit". Beides unwahr; korrigiert.
🔴 Offen und bewusst nicht selbst entschieden: eine Ausfuhr der
ganzen Liste auf Knopfdruck gibt es nicht. Weder pageta noch das
mana-Konto haben eine Schaltfläche dafür; die DSGVO-Route ist
Service-Key-gesichert, ein Mensch muss sie auslösen. Die Landing hat das
bis heute als „jederzeit verfügbar" behauptet — der Satz ist jetzt
ehrlich („auf Anfrage"), aber der Wert datensouveraenitaet verlangt den
Knopf. Local-first heisst: die Daten liegen im Gerät, eine Ausfuhr wäre
clientseitig und klein.
🛑 Und ein Betriebsfund: pnpm --filter @pageta/web check scheiterte
mit einem unverständlichen vite-Typfehler — zwei vite-Instanzen im Baum
(terser 5.49 gegen 5.51), obwohl das Lockfile nur eine kennt. pnpm install räumt es weg, danach 0 Fehler. Wer den Fehler liest, sucht
sonst im eigenen Code.
2026-07-30 — Tagging am echten Bestand: drei Funde
40 Artikel über die Mana-Cloud getaggt (claude-haiku-4.5, ~1,5 s je Artikel).
Die Tag-Qualität stimmt (Handelspolitik, Justizirrtum, Kinderschutz,
Batterietechnik), aber der erste Blick auf die Karte hat drei Dinge
aufgedeckt:
- Nabenknoten.
tech(der einzige Alt-Tag) wurde an 39 von 40 Artikeln vorgeschlagen und zog die Karte zu einem Stern zusammen. Tags ab 80 % Anteil werden jetzt aus der Zeichnung genommen — benannt statt verschwiegen, abschaltbar, am Artikel bleiben sie. - Beschriftungs-Salat. Das Kräfte-Layout trennt Kreise, nicht Wörter.
Neu: Beschriftungslängen fließen ins Layout ein, und
label-placement.tssetzt jedes Wort deterministisch unten / oben / gar nicht. - Vokabular wuchs nicht mit. Der Stapel lud die vergebenen Tags einmal
beim Öffnen — Artikel 40 kannte nur den Stand vor Artikel 1. Folge: 60 Tags
auf 40 Artikel (fast jeder genau einmal, also kaum Verbindungen) plus
Dubletten wie „Kryptografie" neben „Kryptographie".
GrowingVocabularyreicht jetzt das mitwachsende Vokabular in jeden Prompt.
Zweiter Durchlauf nachgeholt (nach Neu-Login). Mit mitwachsendem Vokabular kamen 84 Tags für 38 Artikel — und diesmal überwiegend vorhandene (Recht, Kinderschutz, Prompting, Nachhaltigkeit, Energieeffizienz). Genau die Querverbindungen, die vorher fehlten: aus einem Feld von Zweier-Inseln wurde ein zusammenhängendes Netz.
Dritter Fund dabei: das dichte Netz war unlesbar — 43 von 75 Beschriftungen fielen weg. Mehr Fläche hilft nicht (ein größerer viewBox skaliert die Schrift proportional mit herunter; gemessen: 2000×1350 = 0 Kollisionen bei ~8 px Schrift, höher-statt-breiter bringt 12→7). Bei deutschen Komposita passen ~40 Wörter auf einen Bildschirm, nicht 75. Also filtert die Karte auf wiederkehrende Tags (ab 2 Artikeln) — selbst- entscheidend ab 45 Knoten und nur, wenn danach ≥8 übrig bleiben, sonst wäre eine kleine Lese-Liste leer. Ergebnis: 30 Knoten, 2 ausgeblendete Wörter.
Stand jetzt: 32 Tags aus 46 getaggten Artikeln, keiner mehr ohne Tag (die letzten 6 lagen nur an der 40er-Obergrenze je Lauf und wurden nachgezogen).
Dubletten-Werkzeug (packages/pageta-domain/src/tag-merge.ts):
findTagVariants gruppiert Schreibvarianten (ß→ss, ph→f, Bindestriche weg)
und Tippfehler (Editierdistanz 1, erst ab 8 Zeichen + gleicher Wortanfang).
Am Bestand gefunden und zusammengeführt: Kryptografie/Kryptographie,
Music-/Musik-Streaming, Webstandards/Web-Standards. Die Zielform wählt der
Mensch — bei Gleichstand entscheidet die Heuristik alphabetisch und schlug
prompt „Music-Streaming" für eine deutsche Liste vor.
2026-07-29 — Themenkarte + Tag-Vorschläge
Zwei Stufen, live unter /rueckblick/themen und im Werkzeug-Menü der
Lese-Liste.
- Themenkarte (
packages/pageta-domain/src/graph.ts,apps/web/src/lib/graph-layout.ts): Tags als Ko-Vorkommens-Graph — Knoten sind Tags (auf Wunsch auch Quellen), eine Kante heißt „kommt am selben Artikel vor". Kein LLM, kein Server: Zählarbeit über den lokalen Event-State, Layout als eigenes Fruchterman-Reingold, deterministisch (Goldwinkel-Spirale stattMath.random) und einmal fertig gerechnet statt laufender Simulation. Die Lese-Liste versteht jetzt?tag=. - Tag-Vorschläge (
packages/pageta-domain/src/autotag.ts): Vokabular- Weg über das Modell (die bereits vergebenen Tags gehen in den Prompt, höchstens EIN neuer Begriff — sonst Wildwuchs) mit KI-freiem Rückfall über TF-IDF gegen die eigene Liste. Einzeln im Reader, im Stapel aus der Lese-Liste (max. 40 je Lauf). Geschrieben wird erst auf Bestätigung, über das bestehendeArticleTagsSet-Event — bewusst kein eigener Event-Typ, das hätte@mana/shared-schemasmitgezogen. - Neue Route
POST /api/v1/tags/suggest(JWT, 60/min), greift nur bei erlaubtem Cloud-Pfad.
Am Live-Bestand geprüft, zwei Funde: die ganze Lese-Liste trug genau 1 Tag (die Karte blieb also leer — Auto-Tagging war die Voraussetzung, nicht die Kür), und der statistische Weg schlug anfangs Wortformen statt Begriffe vor („Ausländischer", „Führte", „Kilometern"). Behoben über die deutsche Großschreibung als Substantiv-Signal plus vorsichtige Grundform-Zusammenführung.
Offen: ohne lokales Modell und ohne erlaubte Mana-Cloud bleibt nur der statistische Weg; dessen Labels sind Wörter, keine Begriffe. Der Vokabular-Weg ist ungetestet gegen ein echtes Modell, weil im Testkonto beides aus ist.
2026-07-27 — Mehrseitige Artikel kommen vollständig an
Bookmarklet und Erweiterung sammeln Folgeseiten jetzt im Tab des Nutzers und schicken sie als Liste; der Server extrahiert jede Seite einzeln und fügt sie in Lese-Reihenfolge zusammen.
Anlass: golem.de/news/…-2607-211258.html hat drei Seiten, gespeichert
wurde bisher nur Seite 1 (911 von rund 2400 Wörtern). Serverseitig ist da
nichts zu holen — Golem beantwortet auch Seite 2 ohne Zustimmungs-Cookie
mit der Abfrage. Ein fetch aus dem Tab bekommt sie (gemessen: 200, kein
Redirect).
- Folgeseiten-Erkennung ohne quellenspezifische Selektoren
(
apps/web/src/lib/page-collector.js): ein Link zählt, wenn seine Adresse sich von der aktuellen nur in einem Seitenzähler unterscheidet (-2.html,?page=2,/seite/2/); ohne Seitenliste folgt esrel="next". Deckel: 20 Seiten, 6 MB, 300 ms Pause je Abruf. - Gestrippt vor dem Senden —
<style>/<noscript>/<template>raus, Skript-Inhalte geleert, Tags/Attribute und JSON-LD bleiben (sonst verlörensiteNameFromJsonLdund die CMP-Signaturen inconsent-wall.tsihre Grundlage). Gemessen: Golem 401 → 145 KB, Extraktions-Ergebnis nachweislich unverändert (Titel, Wortzahl, siteName, Bild, Datum identisch an the-decoder.de und winfuture.de). - API:
POST /articles/extract/previewnimmt zusätzlichpages(max 20), antwortet mitpageCount.htmlbleibt gültig — Bookmarklets liegen im Lesezeichen des Nutzers und werden nicht mitdeployt. - Ehrlich bei Lücken: kam eine erkannte Folgeseite nicht durch, springt die add-Seite nicht weiter, sondern sagt „x von y Seiten".
- Am Golem-Artikel verifiziert: 3 Seiten, 0 fehlend, 298 KB statt ~1,2 MB.
Wer schon ein Bookmarklet installiert hat, muss es einmal neu ablegen — ein altes speichert weiterhin nur Seite 1. Der Hinweis steht in den Einstellungen.
Offen: pageCount wird nicht im Event gespeichert (bräuchte ein Feld in
evt_article_saved_v1/evt_article_enriched_v1, also @mana/shared-schemas
mit 14 Konsumenten). Server-seitiges Nachladen für die Wege ohne Browser
(Bulk-Import, Feed-Archiv, „Neu extrahieren") steht ebenfalls noch aus —
derselbe Detektor, aber im API-Prozess.
2026-07-23 — Quellen / Blog-Hub
Artikel können einer Quelle (source:<hostname>) zugeordnet werden.
Hub unter /quelle/howtomarketagame.com. Feed-Import legt Quelle an und
verknüpft Artikel; ältere Imports nachträglich unter Settings. Lese-Liste
zeigt Quellen-Chips + Filter ?quelle=. Schema @mana/shared-schemas
0.1.23 (SourceUpserted / ArticleSourceLinked) — vorerst Vendor-Tarball,
bis Verdaccio-Publish wieder greift.
2026-07-23 — Blog/Feed einmalig importieren
Unter /lese-liste/settings: Blog- oder Feed-URL → Vorschau → Batch-Save
in die Lese-Liste. Backend: POST /api/v1/imports/from-feed[/preview]
(RSS-Discovery, WP-?paged=N, optional Sitemap-Fallback). Bulk-Worker
schreibt jetzt nach sync2 (emitArticleSaved), nicht mehr in die
legacy Postgres-saved_articles. Cap Feed-Archiv: 1000.
2026-06-03 — Rechtsklick-Kontextmenü auf der Lese-Liste
Geteiltes @mana/shared-ui/organisms ContextMenu auf jedem Artikel-<li>:
Lesen / Original öffnen / Status (gelesen·ungelesen) / Archivieren bzw.
Aus-Archiv / Taggen / Löschen — dieselben api.batch*-Handler wie die
Batch-Toolbar, aber direkt pro Artikel ohne Auswahl-Modus. Ergänzt die
sichtbaren Aktionen (Touch/Mobile bleibt bedienbar). svelte-check 0 neue
Fehler, build grün, Screenshot verifiziert, live auf app.pageta.com.
(683ff3f)
Folge-Sprint 2026-05-22 — Web-/Native-Parität + Cross-Device
Landing-Cutover 2026-05-22 19:30
Subdomain-Migration ausgeführt (LANDING_CUTOVER.md):
pageta.com zeigt jetzt auf die Astro-Marketing-Landing
(pageta-landing:3201), die App lebt unter app.pageta.com
(pageta-web:3100, war vorher pageta.com).
GET https://pageta.com/→ 200 Marketing-Landing (Title: „pageta — Pocket ist tot. Lies in Ruhe weiter.")GET https://pageta.com/{ueber,mitwirken,pocket-import}→ 200GET https://pageta.com/sitemap.xml→ 200 (4 Marketing-URLs)GET https://pageta.com/.well-known/apple-app-site-association→ 200 application/json (Universal Links bleiben funktional)GET https://pageta.com/{lese-liste,article/*,feed,konto,markierungen,recherche,auth/*}→ 301 → app.pageta.com/...GET https://app.pageta.com/→ 307 → /lese-liste (App-Default)GET https://app.pageta.com/{lese-liste,feed,konto,markierungen}→ 200GET https://pageta-api.mana.how/healthz→{"status":"ok"}POST https://pageta-api.mana.how/api/v1/summarize(kein JWT) → 401 ✓
Offene Punkte aus dem Cutover:
- Native iOS-App-AASA hardcoded auf
pageta.com— Universal-Links auf/article/*und/lese-liste/*werden weiterhin vom Landing-nginx korrekt ausgeliefert (gleicher JSON-Payload, gleiche App-IDs). Im nächsten TestFlight-Build verifizieren. - Erst-Login auf
app.pageta.combei einem User, der vorher aufpageta.comeingeloggt war: ggf. erneutes Login nötig, weil App- spezifische Cookies (falls vorhanden) auf der alten Apex-Domain verwaisen. mana-auth-Cookie auf.mana.howist nicht betroffen.
Cross-Device Cookie-Wall via @mana/shared-schemas@0.1.11
warning: string | null lebt jetzt im event-sourced ArticleState,
nicht mehr in localStorage. Zwei neue Events:
ArticleWarningFlaggedsetztstate.warning(heute nur"probable_consent_wall")ArticleWarningClearedlöscht ihn (UI „Hinweis ausblenden")
Bewusst eigene Events statt ArticleSaved-Payload-Erweiterung —
evt_article_saved_v1 bleibt frozen. Native + Web schreiben + lesen
beide via ev/article:<id>-Aggregat; Banner zeigt sich auf jedem
Gerät, das den Event-Stream replayed hat.
Schaden + Recovery 2026-05-22 13:43:
Beim ersten Publish-Versuch wurde @mana/shared-schemas versehentlich
komplett unpublished (DELETE auf /-rev/latest). 0.1.1/0.1.6/0.1.7/
0.1.8/0.1.10 sind weg, nur 0.1.11 ist live. Recovery via Lockfile-Bump
pnpm installin allen 8 Schwester-Apps (uload/moodlit/werdrobe/ comicello/nutriphi/wordeck/mukke/herbatrium) auf^0.1.11. Funktional unkritisch — Schema-Änderungen nur in pageta-Sub-Schema, andere Sub-Schemas byte-gleich.
Konkret eingefügt, alles im Web:
- Routing-Restructure:
/redirected auf/lese-liste(= Standardseite, wie Native). Feed-Tab lebt jetzt auf/feed. Tab-Reihenfolge im Layout spiegelt Native: Lese-Liste · Markierungen · Feed · Recherche · Konto. /kontoneue Seite: E-Mail/Tier/Konto-ID, Abmelden + „Konto verwalten ↗",ThemeToggle+VariantPicker(alle 8 mana-Themes), Bookmarklet-Link, Über-Sektion (Datenschutz/Verein/pageta.com). ThemeToggle ist aus dem Header raus (lebt jetzt in /konto), genau wie bei Native.- Save-from-Feed: Feed-Items haben jetzt einen „+ In Lese-Liste"-Button (zuvor read-only, nur Original-Link).
- Vor/Nach-Sibling-Navigation im Reader-Footer (Pfeil + Titel-Karte, identisch zur Native-Variante).
- Cookie-Wall-Banner im Web-Reader. Lokal-persistiert via
localStorage-Map keyed by articleId (Schema-Bump in@mana/shared-schemasvermieden). Banner mit „Original im Browser öffnen" + „Hinweis ausblenden". - Tag-Read-back:
Article.tagsdurchgereicht ausArticleState. Reader zeigt Tags als Pills + Tag-Hinzufügen-Input; emittiertArticleTagsSet. Native kann Tags ab sofort auch sehen, sobald sie das DTO-Feld liest (eigener Followup, betrifftpageta-native/Sources/Core/Domain/Article.swift). - Reading-Progress persistiert: Window-Scroll-Listener mit Debounce
(1.5 s), emit
ArticleProgressUpdatedab 2 %-Differenz; beim Re-Open springt der Reader an die gespeicherte Position.beforeunload-Hook flusht Pending-Progress vor Tab-Close. - LLM-Zusammenfassung im Reader: neue Route
POST /api/v1/summarizein pageta-api ruftmana-llmmit Aliasmana/fast-text. Client-Sektion „Zusammenfassen ✨" im Reader, ohne Persistierung (Volltext bleibt Source-of-Truth). Pendant zum NativeArticleSummarySection(Foundation Models / Gemma).
Phase
λ-0 ✅ + λ-1 ✅ + λ-2 ✅ + λ-3 ✅ + λ-4 ✅ + λ-5 ✅ + λ-6 ✅ +
Lift-A ✅ + Lift-B ✅ + CI ✅ + Deploy ✅ + Login-Flow ✅ +
Verein-Landing ✅ — pageta.mana.how ist erreichbar, alle
ursprünglich geplanten λ-Phasen sind live.
Folge-Sprint 2026-05-17
- Echter Login-Flow — Cards-Pattern: SSO-Cookie → /auth/refresh → JWT
in localStorage.
apps/web/src/lib/auth/session.svelte.ts,apps/web/src/routes/auth/callback/+page.svelte, AuthGate im Layout mit silent-refresh + Redirect zum Auth-Portal. mana-auth-web hatlesenin der App-Allowlist (Forest-Branding, pageta.mana.how + localhost:3100 als erlaubte Redirect-Origins). - Verein-Landing — mana-ev.ch zeigt Lesen als 12. App-Card +
Intro „elf eigenständige Produkte". Eigenes
lesen.svg. - λ-5 Bulk-Import — POST /api/v1/imports (cap 200/Job), Tick-Worker
alle 2s mit Postgres
pg_try_advisory_lock, State-Machine pending → extracting → saved/duplicate/error. Worker bootet im Container. - λ-6 Tool-Handler — 5 Tools live unter /api/v1/tools/:name
(save_article, list_articles, archive_article, add_article_tag,
add_article_highlight). Alle JWT-gated + zod-validated. JSON-Schemas
pro Tool im
app-manifest.json#tools[]für mana-mcp-Discovery.
Live-Smoke (2026-05-16 19:13)
GET https://pageta.mana.how/→ 200 (SvelteKit-SSR)GET https://pageta-api.mana.how/healthz→{"status":"ok","app":"pageta"}GET https://pageta-api.mana.how/.well-known/mana-app.json→ ManifestGET https://pageta-api.mana.how/api/v1/feed(kein JWT) → 401POST https://pageta-api.mana.how/api/v1/dsgvo/export(kein Key) → 401POST .../dsgvo/export(Service-Key) → 200, leerer User-Exportmana-news-poolTick: 1133 Artikel im Pool
Container (alle healthy)
| Container | Port | Wo |
|---|---|---|
pageta-postgres |
127.0.0.1:5447 | pageta-postgres-Volume /Volumes/ManaData/pageta/postgres/ |
pageta-api |
127.0.0.1:3099 | im Netz pageta_default + manacore-monorepo_default |
pageta-web |
127.0.0.1:3100 | im Netz pageta_default |
mana-news-pool |
127.0.0.1:3079 | im Netz manacore-monorepo_default, DB mana_news_pool auf mana-infra-postgres |
Was steht
| Phase | Inhalt | Status |
|---|---|---|
| λ-0 | Repo-Skelett: pnpm-workspace, turbo, tsconfig, prettier, docker-compose | ✅ |
| λ-0 | apps/api Hono-Skeleton (/healthz, /.well-known/mana-app.json) |
✅ |
| λ-0 | apps/web SvelteKit-Skeleton mit drei Tab-Stubs |
✅ |
| λ-0 | packages/pageta-domain Pure-TS Feed-Engine + Types + Sources, 9/9 Tests grün |
✅ |
| λ-0 | PORTS.md-Eintrag in mana/ (pageta-api: 3099, pageta-web: 3100) |
✅ |
| λ-1 | DB-Schema (Drizzle, 8 Tabellen in Schema reader), db:push grün |
✅ |
| λ-2 | Auth-Middleware (JWKS + serviceKey), /dsgvo/export+delete, /search, /share/receive, /tools/:name |
✅ |
| λ-3 | Core-API: /feed (Pool-Proxy + Server-side-Ranking), /articles CRUD, /highlights, /preferences, /reactions mit Auto-Weight-Diff, /extract/preview |
✅ |
| λ-4 | Web-UI: 3 Tabs, API-Client, Feed + Lese-Liste, Reader-Detail /article/[id] mit Highlight-Selection (4 Farben, Selection-Listener, Plain-Text-Offsets, Highlight-Liste mit Delete), Status-Toggles, Favorit, Delete |
✅ |
| CI | .github/workflows/ci.yml — install, type-check, db:push, build, web-check, domain-tests |
✅ |
| Compose | infrastructure/docker-compose.production.yml + Dockerfiles für api/web; .env.production.example |
✅ |
| λ-5 | Bulk-Import-Worker (Job/Items/Pickup-Pipeline gegen 200 URLs/Job) | offen |
| λ-6 | Föderation: accepts: [url] Handler vollständig, Tools-Handler-Implementierungen |
offen |
| λ-7 | Deployment auf mana-server (pageta.mana.how, pageta-api.mana.how) | bereit, ausstehend |
Plattform-Lifts (parallel, vor λ-7)
| Phase | Inhalt | Status |
|---|---|---|
| Lift-A | @mana/shared-rss aus managarten nach mana/packages/ + Verdaccio |
✅ (Code in mana/packages/shared-rss/, npm publish pending) |
| Lift-B | news-ingester aus managarten → mana-news-pool Plattform-Service (Port 3079) |
✅ (Code in mana/services/mana-news-pool/, eigene DB mana_news_pool, Schema pool, Dockerfile, Compose-Snippet im CLAUDE.md) |
| Lift-C | News-Research-Endpoints in mana-research integrieren |
deferred |
Verifizierter Stand (lokal, 2026-05-16)
pnpm installgrünpnpm docker:up→ Postgres :5443pnpm --filter @pageta/api db:push→ 8 Tabellen + 11 Indizes in Schemareaderpnpm --filter @pageta/api type-check→ grünpnpm --filter @pageta/api dev→ bootet auf :3099GET /healthz→ 200GET /.well-known/mana-app.json→ Manifest 200GET /api/v1/feed(ohne Auth) → 401GET /api/v1/articles(ohne Auth) → 401POST /api/v1/articles/extract/preview(ohne Auth) → 401POST /api/v1/dsgvo/export(ohne Service-Key) → 401POST /api/v1/dsgvo/export(mit Service-Key + userId) → 200 leerer Export
pnpm --filter @pageta/domain test→ 9/9 grünpnpm --filter @pageta/web check→ 0 errors / 0 warnings (252 files)pnpm --filter @pageta/web build→ grün, adapter-node Bundle
Was noch fehlt für „real benutzbar"
Historisch — Stand λ-6, Mai 2026. Alles in dieser Liste ist seither erledigt (Auth, Reader, Recherche-Anbindung, CI, Deploy). Sie bleibt als Protokoll stehen; wer den heutigen Stand sucht, liest die Einträge oben.
- Echte Auth-Integration: heute
localStorage['pageta.dev_token']-Stub. Migration auf@mana/shared-authmit Auth-Portal-Redirect kommt mit λ-6 (oder mit dem Auth-Portal-Plan im Memoryproject_auth_portal_migration). - Echter Pool-Endpoint:
/api/v1/feedruftMANA_NEWS_POOL_URL/feed— zeigt heute auflocalhost:3066(managartens news-ingester). Nach Lift-B wechseln aufmana-news-pool:3079. - Reader-Detail-View
/article/[id]mit Highlight-Selection - Recherche-Tab (heute Stub) braucht mana-research-Endpoints
- CI (.github/workflows/ci.yml)
- Deploy (docker-compose.macmini.yml + Cloudflared)
Offene Punkte
- Port-Range knapp: 3099+3100 sind die letzten freien. Memoro/Who-Range (3100+) wird damit bewusst angekratzt — beide haben eigene Repos.
Encryption AUS— überholt, seit 2026-08-02 falsch. Verschlüsselt wird auf JEDEM Schreibpfad, Client wie Server (enc:1:…, fail-closed). Die geltende Fassung steht als Invariante 4 inCLAUDE.md— dort nachlesen, nicht hier.shared-rssvendored: Code-Copy inapps/api/src/lib/shared-rss/. Wechsel auf Verdaccio-Paket nach Lift-A.- Tier-Gate: Manifest sagt
tier_required: "public". Wenn Lesen Beta bleiben soll bis Mature, hier umstellen +auth.apps-Eintrag bei mana-auth. - Source-Liste: SOURCES_META in
packages/pageta-domain/src/sources.tsmuss synchron mitmana-news-poolbleiben. Heute Source-of-Truth istmanagarten/services/news-ingester/src/sources.ts. Drift-Risiko bis Lift-B durch. - DEV-Token-Setup: kein lokaler mana-auth gestartet → man kann lokal
keine Live-Calls testen. Quick-Fix:
pageta.dev_tokenim Browser- LocalStorage von einemmana-auth-Token aus einer anderen App übernehmen. Sauber: Login-Flow gegenauth.mana.howin λ-6.