-
Notifications
You must be signed in to change notification settings - Fork 13
feat: update environment configuration and enhance Header component #1585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Pre-trial: run Chat locally (Developer Requirements) | ||
|
|
||
| Matches [Developer Requirements](https://www.notion.so/Developer-Requirements-Document-15026a7d835c8062bbcde49b59aa00e8) — **fork, clone, run on localhost:3000**, screenshot for Sweetman. | ||
|
|
||
| ## 1. Clone & install | ||
|
|
||
| ```bash | ||
| git clone <your-fork-or-repo-url> chat | ||
| cd chat | ||
| pnpm install | ||
| # If pnpm complains about TTY: $env:CI='true'; pnpm install | ||
| ``` | ||
|
|
||
| ## 2. Env (minimum to boot) | ||
|
|
||
| Copy `.env.example` → `.env.local`. | ||
|
|
||
| **Required for the app to start** | ||
|
|
||
| - `NEXT_PUBLIC_PRIVY_APP_ID` — create a free app at [Privy](https://dashboard.privy.io), add **http://localhost:3000** to allowed URLs. | ||
|
|
||
| **Required for account / DB features** | ||
|
|
||
| - `NEXT_PUBLIC_SUPABASE_URL` | ||
| - `NEXT_PUBLIC_SUPABASE_ANON_KEY` | ||
| - Often `SUPABASE_SERVICE_ROLE_KEY` (server routes) | ||
|
|
||
| Pre-trial devs: doc says you may **obtain your own** env or ask Sweetman for **specific** keys — not a generic “send everything” request. | ||
|
|
||
| ## 3. Run | ||
|
|
||
| ```bash | ||
| pnpm dev | ||
| ``` | ||
|
|
||
| Open **http://localhost:3000** → screenshot (that’s the pre-trial check). | ||
|
|
||
| ## 4. Recoup API (401 locally) | ||
|
|
||
| Local/preview uses **`https://test-recoup-api.vercel.app`** by default. If calls return **401**, the test deployment may not accept your Privy JWT yet. Options: | ||
|
|
||
| | Option | What to do | | ||
| |--------|------------| | ||
| | A | Ask Sweetman to align **test** API with your Privy app (proper fix for “all local”). | | ||
| | B | Temporarily set `NEXT_PUBLIC_RECOUP_API_URL=https://recoup-api.vercel.app` only if you’re allowed to hit prod from localhost. | | ||
| | C | Run **api** locally — see **`api/docs/RUN_LOCAL.md`** — then `NEXT_PUBLIC_RECOUP_API_URL=http://localhost:3001` in chat. | | ||
|
|
||
| **Pre-trial goal** is usually: app runs + login works + screenshot — not necessarily every API green on day one. | ||
|
|
||
| ## 5. “Run everything locally” | ||
|
|
||
| Not required for pre-trial. Full stack is roughly: | ||
|
|
||
| | Repo | Role | | ||
| |------|------| | ||
| | **chat** | UI (this repo) | | ||
| | **api** | Recoup HTTP API + sandbox setup route | | ||
| | **tasks** | Trigger.dev jobs (needs Trigger credentials) | | ||
| | **mono** | Cloned inside sandboxes by tasks — not run as a separate local server for chat | | ||
|
|
||
| For daily work, most devs use **deployed** test/prod API + local chat. | ||
|
|
||
| ## 6. Windows gotchas | ||
|
|
||
| - **EBUSY on `.next`**: stop all `pnpm dev`, delete `.next`, one dev server only; exclude `.next` from OneDrive/antivirus if needed. | ||
| - **Node**: LTS **20** or **22** if Next acts up on Node 24. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| "use client"; | ||
|
|
||
| import { useEffect } from "react"; | ||
| import { usePrivy } from "@privy-io/react-auth"; | ||
| import { useAccessToken } from "@/hooks/useAccessToken"; | ||
| import { setupSandbox } from "@/lib/sandboxes/setupSandbox"; | ||
|
|
||
| const SESSION_KEY = "sandboxSetupDone"; | ||
|
|
||
| export function useSandboxSetupOnLogin() { | ||
| const { authenticated } = usePrivy(); | ||
| const accessToken = useAccessToken(); | ||
|
|
||
| useEffect(() => { | ||
| if (!authenticated || !accessToken) { | ||
| return; | ||
| } | ||
|
|
||
| if (typeof window === "undefined") { | ||
| return; | ||
| } | ||
|
|
||
| if (window.sessionStorage.getItem(SESSION_KEY) === "1") { | ||
| return; | ||
| } | ||
|
|
||
| setupSandbox(accessToken) | ||
| .then(() => { | ||
| window.sessionStorage.setItem(SESSION_KEY, "1"); | ||
| }) | ||
| .catch((error) => { | ||
| // We deliberately log and continue so login UX is not blocked | ||
| console.error("Failed to setup sandbox on login:", error); | ||
| }); | ||
| }, [authenticated, accessToken]); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,7 +3,7 @@ import { Address } from "viem"; | |||||||||||||||||||||||
| export const IS_PROD = process.env.NEXT_PUBLIC_VERCEL_ENV === "production"; | ||||||||||||||||||||||||
| export const NEW_API_BASE_URL = IS_PROD | ||||||||||||||||||||||||
| ? "https://recoup-api.vercel.app" | ||||||||||||||||||||||||
| : "https://test-recoup-api.vercel.app"; | ||||||||||||||||||||||||
| : "http://localhost:3001"; | ||||||||||||||||||||||||
|
Comment on lines
4
to
+6
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid hardcoding localhost as the non-prod API base URL. Line 6 forces all non-prod clients to call 🔧 Proposed fix export const IS_PROD = process.env.NEXT_PUBLIC_VERCEL_ENV === "production";
-export const NEW_API_BASE_URL = IS_PROD
- ? "https://recoup-api.vercel.app"
- : "http://localhost:3001";
+const DEFAULT_NON_PROD_API_BASE_URL = "https://test-recoup-api.vercel.app";
+export const NEW_API_BASE_URL =
+ process.env.NEXT_PUBLIC_RECOUP_API_URL?.trim() ||
+ (IS_PROD
+ ? "https://recoup-api.vercel.app"
+ : DEFAULT_NON_PROD_API_BASE_URL);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| export const IN_PROCESS_PROTOCOL_ADDRESS = IS_PROD | ||||||||||||||||||||||||
| ? ("0x540C18B7f99b3b599c6FeB99964498931c211858" as Address) | ||||||||||||||||||||||||
| : ("0x6832A997D8616707C7b68721D6E9332E77da7F6C" as Address); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { NEW_API_BASE_URL } from "@/lib/consts"; | ||
|
|
||
| type SetupSandboxResponse = | ||
| | { | ||
| status: "success"; | ||
| runId: string; | ||
| } | ||
| | { | ||
| status: "error"; | ||
| error: string; | ||
| }; | ||
|
|
||
| export async function setupSandbox(accessToken: string): Promise<SetupSandboxResponse> { | ||
| const response = await fetch(`${NEW_API_BASE_URL}/api/sandboxes/setup`, { | ||
| method: "POST", | ||
| headers: { | ||
| Authorization: `Bearer ${accessToken}`, | ||
| "Content-Type": "application/json", | ||
| }, | ||
| }); | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error(`Failed to setup sandbox: ${response.status} ${response.statusText}`); | ||
| } | ||
|
|
||
| return (await response.json()) as SetupSandboxResponse; | ||
| } | ||
|
Comment on lines
+13
to
+27
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle API payload failures, not only HTTP failures.
Suggested fix type SetupSandboxResponse =
| {
status: "success";
runId: string;
}
| {
status: "error";
error: string;
};
-export async function setupSandbox(accessToken: string): Promise<SetupSandboxResponse> {
+export async function setupSandbox(
+ accessToken: string
+): Promise<{ status: "success"; runId: string }> {
const response = await fetch(`${NEW_API_BASE_URL}/api/sandboxes/setup`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
+ const data = (await response.json()) as SetupSandboxResponse;
+
if (!response.ok) {
- throw new Error(`Failed to setup sandbox: ${response.status} ${response.statusText}`);
+ throw new Error(
+ data.status === "error"
+ ? data.error
+ : `Failed to setup sandbox: ${response.status} ${response.statusText}`
+ );
}
- return (await response.json()) as SetupSandboxResponse;
+ if (data.status === "error") {
+ throw new Error(data.error);
+ }
+
+ return data;
}🤖 Prompt for AI Agents |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| "use client"; | ||
|
|
||
| import { useSandboxSetupOnLogin } from "@/hooks/useSandboxSetupOnLogin"; | ||
|
|
||
| const SandboxSetupOnLogin = () => { | ||
| useSandboxSetupOnLogin(); | ||
| return null; | ||
| }; | ||
|
|
||
| export default SandboxSetupOnLogin; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NEW_API_BASE_URLnow points all non-production environments tohttp://localhost:3001, which causes preview/test deployments (whereNEXT_PUBLIC_VERCEL_ENV !== "production") to send API calls to loopback instead of Recoup’s deployed API; any module importing this constant (e.g., hooks and server routes) will fail unless an API server is running in the same host/container. This is a regression from the previous non-prod default (https://test-recoup-api.vercel.app) and also makes the newly documentedNEXT_PUBLIC_RECOUP_API_URLineffective because this constant never reads it.Useful? React with 👍 / 👎.