feat(260925-bow): gesehene Version pro Benutzer merken - Spalte, Versionsfunktionen, API

- packages/shared: parseReleaseVersion, compareReleaseVersions, ReleaseNoticeResponse
- getRunningRelease(): einzige Quelle der laufenden Version (APP_VERSION der API)
- User.lastSeenReleaseVersion (nullbar, Migration 20260925120000)
- GET /users/me/release-notice, POST /users/me/release-seen (gebunden an Benutzer und Mandant)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-25 08:42:11 +02:00
parent b35edd5f31
commit 59db32a01f
6 changed files with 229 additions and 1 deletions
+22 -1
View File
@@ -1,4 +1,4 @@
import type { VersionResponse } from '@tessera/shared';
import { parseReleaseVersion, type VersionResponse } from '@tessera/shared';
/**
* Versionsstempel der API (quick-260914-ku1).
@@ -30,3 +30,24 @@ export function formatAppVersionLine(v: VersionResponse = getAppVersion()): stri
const base = `Tessera API ${v.version} (${v.channel})`;
return v.commit ? `${base} ${v.commit}` : base;
}
/**
* Laufende FREIGEGEBENE Version der API als `X.Y.Z` oder `null`
* (quick-260925-bow, D-02/D-04).
*
* Einzige Quelle der laufenden Version fuer das "Was ist neu"-Fenster:
* `APP_VERSION` der API. Warum die API und nicht das Web: zwei der drei
* Anlagewege neuer Benutzer laufen ohne jede Web-Anfrage (LDAP-Abgleich per
* Zeitplan, Erst-Administrator beim API-Start) und tragen die Version bei der
* Anlage ein; ausserdem prueft `POST /users/me/release-seen` gegen diesen
* Wert. Das Web nimmt `currentRelease` aus `GET /users/me/release-notice`
* und wertet seine eigene `NEXT_PUBLIC_APP_VERSION` dafuer nicht aus. Beide
* Abbilder bekommen im CI denselben `APP_VERSION`-Wert
* (`.gitea/scripts/publish-images.sh`).
*
* `v1.4.0-5-gabc1234` (Beta, Describe-Stand) → `1.4.0`; `dev` oder ein
* blosser Commit-Stempel → `null` (dann erscheint nie ein Fenster).
*/
export function getRunningRelease(): string | null {
return parseReleaseVersion(getAppVersion().version);
}