diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 8e73a4df..6a482c83 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -32,11 +32,22 @@ services:
- .:/app
- warmbly_gomodcache:/go/pkg/mod
- warmbly_gocache:/root/.cache/go-build
- # air's restart loop causes brief health flaps; depends_on can't
- # tolerate that, so disable. Consumer / worker fall back to
- # `service_started` below for the same reason.
+ # Relax the prod healthcheck instead of disabling it: dev needs to
+ # keep one because web, seed and the base consumer all depend on
+ # backend with `condition: service_healthy`, and compose refuses to
+ # bring up a service whose service_healthy target has no
+ # healthcheck.
+ #
+ # The bigger start_period gives air time to do a cold first compile
+ # (Go build cache empty in a fresh worktree → 60-90s isn't unusual).
+ # depends_on only gates initial startup, so the brief unhealthy
+ # blips on each subsequent rebuild don't bounce dependents.
healthcheck:
- disable: true
+ test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
+ interval: 10s
+ timeout: 3s
+ retries: 10
+ start_period: 180s
consumer:
image: warmbly-go-dev
@@ -86,18 +97,6 @@ services:
healthcheck:
disable: true
- # ─── web ──────────────────────────────────────────────────────────────
- # web still runs the same image as `make up`; we only re-declare it to
- # weaken the `depends_on: backend` from service_healthy → service_started.
- # In dev mode backend's healthcheck is disabled (air flaps would defeat
- # the gate), and compose refuses to bring up any service whose
- # `service_healthy` target has no healthcheck. web is a Vite dev server,
- # it doesn't reach out to backend at boot, so service_started is enough.
- web:
- depends_on:
- backend:
- condition: service_started
-
# ─── Elixir (realtime) ────────────────────────────────────────────────
realtime:
image: warmbly-elixir-dev
diff --git a/web/src/app/auth/layout.tsx b/web/src/app/auth/layout.tsx
index 360f1e9e..f7981fd4 100644
--- a/web/src/app/auth/layout.tsx
+++ b/web/src/app/auth/layout.tsx
@@ -1,6 +1,7 @@
import React from "react";
-import { Outlet, useNavigate } from "react-router-dom";
+import { Navigate, Outlet, useNavigate } from "react-router-dom";
import { APP_URL, WEBSITE_URL } from "@/lib/information";
+import getToken from "@/lib/helper/getToken";
import { Logo } from "@/components/svg";
import { Mail, BarChart3, Zap, Shield, Github, ArrowRight } from "lucide-react";
@@ -110,6 +111,14 @@ export default function AuthLayout() {
return () => window.removeEventListener("message", receiveMessage);
}, [navigate]);
+ // Already signed in? Skip the auth UI entirely and send the user
+ // into the app. /app's own guard will redirect onward to
+ // /select-org or /onboarding if needed. Sits after hooks so the
+ // Rules of Hooks aren't violated when the token state changes.
+ if (getToken()) {
+ return