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",