From e5482dc40ce5e24e9a0a9ad1fc6ec516d875c63e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 12:27:56 +0000 Subject: [PATCH 1/6] Add admin panel notification for available GitHub releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Checks the GitHub releases API daily via the existing pg-boss scheduler (plus a manual "check now" button) and shows a badge in Admin → Updates when a newer version is published. Installing remains a manual `docker compose pull` since the app runs as an immutable container image and cannot replace itself. --- docs/self-hosting.md | 1 + messages/de.json | 16 ++- messages/en.json | 16 ++- src/app/[locale]/(app)/admin/actions.ts | 12 ++ src/app/[locale]/(app)/admin/updates/page.tsx | 10 ++ src/components/admin/admin-nav.tsx | 4 +- src/components/admin/update-status.tsx | 109 ++++++++++++++++++ src/lib/jobs/index.ts | 12 ++ src/lib/settings.ts | 12 ++ src/lib/update-check.ts | 63 ++++++++++ 10 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 src/app/[locale]/(app)/admin/updates/page.tsx create mode 100644 src/components/admin/update-status.tsx create mode 100644 src/lib/update-check.ts diff --git a/docs/self-hosting.md b/docs/self-hosting.md index cb66f7b..18974a7 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -71,6 +71,7 @@ Everything else is configured in **Admin → Settings**: | AI | providers (Anthropic, OpenAI, Google, Mistral, Groq, Ollama, OpenAI-compatible), models, default + embedding model (enables RAG), monthly token limits | | Email | SMTP for password resets and reminders, test email | | Branding | app name, max upload size | +| Updates | shows whether a newer release is available on GitHub (checked daily, or on demand) — installing it is a manual `docker compose pull && docker compose up -d` | ## Environment variables diff --git a/messages/de.json b/messages/de.json index 4b6f46c..ebba9e0 100644 --- a/messages/de.json +++ b/messages/de.json @@ -94,7 +94,8 @@ "auth": "Anmeldung & SSO", "ai": "KI", "email": "E-Mail", - "branding": "Branding" + "branding": "Branding", + "updates": "Updates" }, "users": { "title": "Benutzer", @@ -198,6 +199,19 @@ "appName": "App-Name", "maxUploadMb": "Max. Upload-Größe (MB)", "saved": "Gespeichert." + }, + "updates": { + "title": "Updates", + "description": "Prüft täglich auf GitHub, ob eine neue Version dieser App veröffentlicht wurde", + "currentVersion": "Aktuelle Version", + "updateAvailable": "Update verfügbar", + "newVersion": "Version {version} ist verfügbar", + "publishedOn": "Veröffentlicht am {date}", + "viewOnGithub": "Release auf GitHub ansehen", + "upToDate": "Diese Instanz ist auf dem neuesten Stand.", + "neverChecked": "Es wurde noch nicht geprüft.", + "lastChecked": "Zuletzt geprüft: {date}", + "checkNow": "Jetzt prüfen" } }, "assignments": { diff --git a/messages/en.json b/messages/en.json index f19a40f..1309e99 100644 --- a/messages/en.json +++ b/messages/en.json @@ -94,7 +94,8 @@ "auth": "Sign-in & SSO", "ai": "AI", "email": "Email", - "branding": "Branding" + "branding": "Branding", + "updates": "Updates" }, "users": { "title": "Users", @@ -198,6 +199,19 @@ "appName": "App name", "maxUploadMb": "Max upload size (MB)", "saved": "Saved." + }, + "updates": { + "title": "Updates", + "description": "Checks GitHub daily for new releases of this app", + "currentVersion": "Current version", + "updateAvailable": "Update available", + "newVersion": "Version {version} is available", + "publishedOn": "Published on {date}", + "viewOnGithub": "View release on GitHub", + "upToDate": "You're running the latest version.", + "neverChecked": "No check has run yet.", + "lastChecked": "Last checked: {date}", + "checkNow": "Check now" } }, "assignments": { diff --git a/src/app/[locale]/(app)/admin/actions.ts b/src/app/[locale]/(app)/admin/actions.ts index 3c34188..fa0a3d5 100644 --- a/src/app/[locale]/(app)/admin/actions.ts +++ b/src/app/[locale]/(app)/admin/actions.ts @@ -9,6 +9,7 @@ import { invite } from "@/db/schema" import { requireAdmin } from "@/lib/auth/session" import { bustAuthCache } from "@/lib/auth" import { sendEmail } from "@/lib/email" +import { checkForUpdate } from "@/lib/update-check" import { aiSettingsSchema, brandingSchema, @@ -114,3 +115,14 @@ export async function saveAiSettings(value: unknown) { revalidatePath("/", "layout") return { ok: true as const } } + +export async function checkForUpdatesNow() { + await requireAdmin() + try { + await checkForUpdate() + revalidatePath("/admin/updates") + return { ok: true as const } + } catch (error) { + return { ok: false as const, error: error instanceof Error ? error.message : "unknown" } + } +} diff --git a/src/app/[locale]/(app)/admin/updates/page.tsx b/src/app/[locale]/(app)/admin/updates/page.tsx new file mode 100644 index 0000000..932faf8 --- /dev/null +++ b/src/app/[locale]/(app)/admin/updates/page.tsx @@ -0,0 +1,10 @@ +import { requireAdmin } from "@/lib/auth/session" +import { getUpdateStatus } from "@/lib/update-check" +import { UpdateStatus } from "@/components/admin/update-status" + +export default async function AdminUpdatesPage() { + await requireAdmin() + const { current, latest, updateAvailable } = await getUpdateStatus() + + return +} diff --git a/src/components/admin/admin-nav.tsx b/src/components/admin/admin-nav.tsx index ed31891..1ab29a6 100644 --- a/src/components/admin/admin-nav.tsx +++ b/src/components/admin/admin-nav.tsx @@ -10,6 +10,7 @@ const items = [ { key: "ai", href: "/admin/ai" }, { key: "email", href: "/admin/email" }, { key: "branding", href: "/admin/branding" }, + { key: "updates", href: "/admin/updates" }, ] as const export function AdminNav() { @@ -19,7 +20,8 @@ export function AdminNav() { return ( From 3cd003cc4a2974bd999f334e8456a0690de0a867 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 15:51:08 +0000 Subject: [PATCH 6/6] Show the version jump in the sidebar instead of a bare dot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A dot didn't say what changed. Replace it with "v1.0.0 → v1.0.3" in place of the plain version text, linking to the release. --- src/components/layout/app-sidebar.tsx | 28 +++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/components/layout/app-sidebar.tsx b/src/components/layout/app-sidebar.tsx index 6d10392..51b2ee5 100644 --- a/src/components/layout/app-sidebar.tsx +++ b/src/components/layout/app-sidebar.tsx @@ -556,27 +556,25 @@ export function AppSidebar({
-