From 542762e4419b5d7a710107d81bf1fab3e31dad80 Mon Sep 17 00:00:00 2001 From: brasse b Date: Fri, 10 Apr 2026 14:16:44 +0200 Subject: [PATCH] fix: double config path, stale service worker, empty op-name log - main.go: DOCKER_PATH=/config + /config.json (was /config/config.json) - vite.config.ts: skipWaiting+clientsClaim forces new SW immediately; navigateFallback: null prevents SW from serving stale index.html; globPatterns excludes HTML so navigation always hits the network - server.go: gqlOpName handles shorthand { field } syntax Co-Authored-By: Claude Sonnet 4.6 --- backend/cmd/server/main.go | 8 +++++++- backend/internal/graph/server.go | 17 +++++++++++------ frontend/vite.config.ts | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index ea8b818..9f1866c 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -39,8 +39,14 @@ func main() { } func configPath() string { + // CONFIG_DIR points directly to the config directory (preferred). + if p := os.Getenv("CONFIG_DIR"); p != "" { + return p + "/config.json" + } + // DOCKER_PATH is also set to the config directory in docker-compose + // (the container mounts the config dir at /config, so DOCKER_PATH=/config). if p := os.Getenv("DOCKER_PATH"); p != "" { - return p + "/config/config.json" + return p + "/config.json" } return "config.json" } diff --git a/backend/internal/graph/server.go b/backend/internal/graph/server.go index ae697c3..4f7ae2f 100644 --- a/backend/internal/graph/server.go +++ b/backend/internal/graph/server.go @@ -253,13 +253,18 @@ func writeGQLError(w http.ResponseWriter, msg string) { func gqlOpName(query string) string { q := strings.TrimSpace(query) - if strings.HasPrefix(q, "mutation") { - return "mutation " + firstWord(q[len("mutation"):]) + switch { + case strings.HasPrefix(q, "mutation"): + return "mutation " + firstWord(strings.TrimSpace(q[len("mutation"):])) + case strings.HasPrefix(q, "query"): + return "query " + firstWord(strings.TrimSpace(q[len("query"):])) + case strings.HasPrefix(q, "{"): + // Shorthand query: extract first field name from { field ... } + inner := strings.TrimSpace(q[1:]) + return "query {" + firstWord(inner) + "...}" + default: + return firstWord(q) } - if strings.HasPrefix(q, "query") { - return "query " + firstWord(q[len("query"):]) - } - return firstWord(q) } func firstWord(s string) string { diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 5c7fc0a..4e4f865 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -8,6 +8,9 @@ export default defineConfig({ vue(), VitePWA({ registerType: 'autoUpdate', + // Inject a cache-busting version based on build time so stale service + // workers are replaced immediately when a new image is deployed. + injectRegister: 'auto', manifest: { name: 'Archivum', short_name: 'Archivum', @@ -15,16 +18,26 @@ export default defineConfig({ theme_color: '#0f172a', background_color: '#0f172a', display: 'standalone', - // Icons are optional; add real PNG files to public/icons/ to enable PWA install. icons: [], }, workbox: { - globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'], + // Force the new service worker to activate immediately + // instead of waiting for all tabs to close. + skipWaiting: true, + clientsClaim: true, + // Only cache these explicit file types — do NOT cache HTML so the + // SPA shell is always fetched fresh (prevents stale SW loops). + globPatterns: ['**/*.{js,css,woff2,png,svg,ico}'], + // Navigation requests (HTML) always go to the network. + navigateFallback: null, runtimeCaching: [ { urlPattern: /\/graphql$/, handler: 'NetworkFirst', - options: { cacheName: 'api-cache' }, + options: { + cacheName: 'api-cache', + networkTimeoutSeconds: 5, + }, }, ], },