diff --git a/.gitignore b/.gitignore index 9197675..6c45d1d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ venv/ # env & secrets .env .env.local +.env.production .env.*.local !.env.example diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index bad8e31..b1b11e2 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -4,7 +4,15 @@ const nextConfig = { // Workspace packages ship TypeScript source, so Next must transpile them. transpilePackages: ["@agy/ui", "@agy/contracts"], env: { - NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8000", + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL ?? "", + }, + async rewrites() { + return [ + { + source: "/api/:path*", + destination: "http://127.0.0.1:8000/api/:path*", + }, + ]; }, }; diff --git a/apps/web/package.json b/apps/web/package.json index 17577ef..fb3c203 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@agy/web", - "version": "0.1.1", + "version": "0.1.2", "private": true, "description": "Smart Organization frontend — Next.js App Router, RTL, dark-first.", "scripts": { diff --git a/apps/web/public/favicon.ico b/apps/web/public/favicon.ico new file mode 100644 index 0000000..20558e8 Binary files /dev/null and b/apps/web/public/favicon.ico differ diff --git a/apps/web/src/app/icon.svg b/apps/web/src/app/icon.svg new file mode 100644 index 0000000..bdae817 --- /dev/null +++ b/apps/web/src/app/icon.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/web/src/lib/api.ts b/apps/web/src/lib/api.ts index 4b9ea47..dc22973 100644 --- a/apps/web/src/lib/api.ts +++ b/apps/web/src/lib/api.ts @@ -8,8 +8,30 @@ import type { ApiErrorBody } from "@agy/contracts"; -export const API_BASE_URL = - process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8000"; +/** + * Resolves the API base URL. + * In a browser: + * - If NEXT_PUBLIC_API_URL is configured and not pointing to localhost on a remote host, use it. + * - Otherwise default to relative path "" so requests go directly to the current origin (e.g. /api/*) + * behind reverse proxies (Caddy), preventing ERR_CONNECTION_REFUSED on clients. + * In SSR / Node / tests: + * - Fall back to NEXT_PUBLIC_API_URL or "http://localhost:8000". + */ +export function getApiBaseUrl(): string { + const configured = process.env.NEXT_PUBLIC_API_URL?.trim(); + if (typeof window !== "undefined") { + const isLocalhost = + window.location.hostname === "localhost" || + window.location.hostname === "127.0.0.1"; + if (!configured || (!isLocalhost && configured.includes("localhost"))) { + return ""; + } + return configured; + } + return configured || "http://localhost:8000"; +} + +export const API_BASE_URL = getApiBaseUrl(); export class ApiError extends Error { readonly status: number; @@ -73,9 +95,10 @@ export async function apiRequest(path: string, options: RequestOptions = {}): const authToken = token ?? getStoredToken(); if (authToken) headers.Authorization = `Bearer ${authToken}`; + const baseUrl = getApiBaseUrl(); let response: Response; try { - response = await fetch(`${API_BASE_URL}${path}`, { + response = await fetch(`${baseUrl}${path}`, { method, headers, body: body === undefined ? undefined : JSON.stringify(body), diff --git a/apps/web/src/lib/version.ts b/apps/web/src/lib/version.ts index fc4be2f..9235c65 100644 --- a/apps/web/src/lib/version.ts +++ b/apps/web/src/lib/version.ts @@ -12,7 +12,7 @@ * "the app is on the wrong version" bug into a failing test, which is the * whole point of keeping them separate. */ -export const APP_VERSION = "0.1.1"; +export const APP_VERSION = "0.1.2"; /** What the footer pill renders — ``v`` prefix keeps it unambiguous in the UI. */ export const APP_VERSION_LABEL = `v${APP_VERSION}`; diff --git a/package.json b/package.json index a343adb..034c729 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "smart-org", - "version": "0.1.1", + "version": "0.1.2", "private": true, "description": "Smart Organization — AI Workforce Platform. Standalone multi-tenant SaaS, independent of the Telegram bot runtime.", "packageManager": "pnpm@9.12.0",