Navigace
ELOWEN · Dokumentace

Poslední aktualizace: 20. října 2026

Procházet dokumentaci · Changelog persistence

Tento článek zatím není přeložen. Je dostupný v angličtině.

Developer reference

Changelog persistence

The authenticated read route GET /plugins/changelog/api/entries?guide=<slug>&lang=cs returns { entries: [{ version, date, title, itemId, href }] }. The host BFF adds its normal /api prefix. guide is one canonical lowercase kebab-case article slug (maximum 120 characters); invalid input returns 400. lang uses the existing cs/sk/en entry locale contract. Each result represents one visible release-note item linking that guide, with href: /p/changelog?entry=<version>#<itemId>. Multiple visible items in one release can yield multiple summaries. There is no raw body, unread flag or reader information in this projection.

Guides requests this route only when the live plugin listing exposes changelog. Empty success means no related updates; failure remains an error in that optional section. The request never acknowledges reading or writes seen state. Relationships come only from actual Markdown link tokens pointing to /guides/<slug>#<section> in the localized, audience/plugin-filtered content, not images, code examples, HTML anchors or metadata.

Item IDs are stable across translations and body ordering: guide-<slug> (or guide-<slug>--<section>) from the first guide target of a Markdown list item or prose block. An explicit <!-- changelog-item: <kebab-id> --> at the end of that item's paragraph overrides it, for example - [Guide](/guides/brain-chat) <!-- changelog-item: chat-files -->. Do not start a Markdown item with a comment: CommonMark treats that line as an HTML block, not a Markdown link. Repeated derived IDs must use distinct explicit IDs; duplicate explicit IDs fail. Translation validation compares item identity, guide targets and audience/plugin scope, ignoring link labels and prose.

Detail reads insert trusted, release-namespaced <span id="changelog-item-<version>-<itemId>"></span> anchors into guide-linked Markdown items; the host Markdown sanitizer still processes the complete body. IDs do not collide when several expanded releases link the same guide. Opening a deep link expands the requested visible release and scrolls its rendered item after the detail resolves. Hidden releases/items never acquire a target. Ordinary /guides/... Markdown links use the existing host navigation; modified clicks retain native browser behavior.

Reading state

The host awaits the entry point's migrate(db) export before calling register(ctx) while it loads the plugin; a missing export or a failed migration aborts that plugin's initialization. Registration awaits initSeenStore to open the already-migrated store before registering routes or surface facts. It obtains the host's asynchronous PluginDb through await ctx.db(). SQL qualifies the host-provided, quoted db.schema; for this plugin the read marker table is "plugin_changelog".seen. Core account metadata is read from elowen.users.

Each account has one BIGINT primary key and one non-null last_seen_version. Migration versions 1 through 4 create the table, normalize the markers written by earlier releases and drop the former timestamp. The canonical migrate(db) export applies only unapplied steps through PluginDb's transactional migration runner and requires no runtime context. Registration and store construction never run migrations. The daemon owns migration authority; runner and worker processes log a skip and consume its migrated schema. Direct fixtures call migrate(db) before registration, or after seeding a historical ledger and marker rows written by an earlier release.

lastSeen, markSeen, everyone, forgetUser and resetForAll return promises. API responses, navigation badges and account-removal handlers await their work and propagate failures. Open mode has no account marker or unread badge.

markSeen inserts a missing marker and locks it before comparing versions with the shared numeric comparator. Its SERIALIZABLE transaction retries SQLSTATE 40001 or 40P01 at most three attempts through PluginDb. Concurrent first visits, existing markers and administrator deletion resets cannot move a stale tab's marker backward. resetForAll locks account-backed markers in account order, tests their locked versions and updates or deletes them using only its transaction handle. A failed update rolls back the whole reset.

Plugin grants are resolved asynchronously once per referenced plugin for each request or badge resolution. The synchronous audience projections receive a predicate over those resolved grants. This keeps denied plugin items out of listings, details, reader reports and seen markers. Detail routes also await the plugin catalog before attaching pill metadata.

The focused suite tests/plugins/changelogPlugin.test.ts uses the ephemeral PostgreSQL harness with fresh database clones. Each clone opens the complete async createCoreDatabase registry with its pool size from DEFAULT_HARNESS_CONFIG.databasePoolDaemon and passes the required host preparation binding to native PluginDb. The plugin never reaches host stores inside a transaction, so the fixture rejects any attempted transaction host-store access. Core pools close before the harness drops the clones. It covers historical migration ledgers, monotonic concurrent writes, concurrent resets, reset rollback, routes, unread counts, account deletion and asynchronous grants. PluginDb supplies the generic SQL and migration implementation; the plugin owns no pool or adapter.