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 ; + } + return (
; + } + + return ; +} + +function SelectOrgPageInner() { const navigate = useNavigate(); const [createOpen, setCreateOpen] = React.useState(false);