From 3f9c1d99e2c8bc77923f9346635881f50e4520c6 Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Fri, 22 May 2026 22:26:49 -0700 Subject: [PATCH] Fix invite link showing http and show draft board card during live draft - Use x-forwarded-proto header (allowlisted to http/https only) when building the invite link origin so it shows https behind a TLS proxy - Show the "View Draft Board" bare card in the right column while a draft is running, matching the card already shown for active/completed seasons Co-Authored-By: Claude Sonnet 4.6 --- app/routes/leagues/$leagueId.server.ts | 10 +- app/routes/leagues/$leagueId.tsx | 4 +- docs/ci-build-optimization.md | 133 +++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 docs/ci-build-optimization.md diff --git a/app/routes/leagues/$leagueId.server.ts b/app/routes/leagues/$leagueId.server.ts index a2cfb61..e10b048 100644 --- a/app/routes/leagues/$leagueId.server.ts +++ b/app/routes/leagues/$leagueId.server.ts @@ -203,8 +203,14 @@ export async function loader(args: Route.LoaderArgs) { // Check if draft order is set const isDraftOrderSet = draftSlots.length > 0; - // Extract origin for client use (avoids SSR/client mismatch on invite URLs) - const origin = new URL(args.request.url).origin; + // Extract origin for client use (avoids SSR/client mismatch on invite URLs). + // Respect x-forwarded-proto so the invite URL shows https when behind a TLS-terminating proxy. + const requestUrl = new URL(args.request.url); + const rawProto = args.request.headers.get("x-forwarded-proto"); + const proto = rawProto?.split(",")[0].trim() ?? ""; + const origin = (proto === "https" || proto === "http") + ? `${proto}://${requestUrl.host}` + : requestUrl.origin; // Fetch recent audit log entries for the "Recent Activity" summary widget const recentActivity = season diff --git a/app/routes/leagues/$leagueId.tsx b/app/routes/leagues/$leagueId.tsx index dbc089d..a7dcccd 100644 --- a/app/routes/leagues/$leagueId.tsx +++ b/app/routes/leagues/$leagueId.tsx @@ -329,8 +329,8 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) { /> )} - {/* Draft historical view - active/completed only */} - {season && isActiveOrCompleted && ( + {/* Draft historical view - active/completed/draft */} + {season && (isActiveOrCompleted || season.status === "draft") && ( Note: If Forgejo's runner doesn't support the cache action, this silently no-ops (harmless). An alternative is merging the three parallel jobs into one that installs once and runs all checks sequentially — unconditionally saves two `npm ci` calls. + +--- + +## Expected Results + +`docker pull` on the server is incremental — it only downloads layers that changed since the last deploy. After the Dockerfile fix, most deploys only pull the small build-output layer instead of the full node_modules. + +| Step | Before | After (code change) | After (dep change) | +|---|---|---|---| +| Setup buildx | ~5 min | ~30 sec | ~30 sec | +| Build + push | ~5 min | ~1-2 min | ~3-4 min | +| Deploy (docker pull + up) | ~5 min | ~1-2 min | ~3-4 min | +| **Total** | **~15 min** | **~3-5 min** | **~8-10 min** | + +--- + +## Verification + +1. Push a code-only commit (no package.json change) — confirm Docker build uses registry cache for npm install layers and the build step completes in under 2 minutes +2. Push a commit changing package.json — confirm npm cache is correctly invalidated and reruns +3. Check the `setup-buildx-action` log — should show ~30s, no QEMU download +4. Check deploy job — `docker compose pull` should show most layers as `Already exists` +5. Confirm deployed app is functional -- 2.45.3