Contributors to Invoisio currently face friction when setting up their local environment because environment variable documentation is inconsistent across the four active app surfaces: the NestJS backend, the Next.js web app, the Expo mobile app, and the Soroban smart-contract client. The backend has a reasonably complete .env.example, but the web and mobile apps have no example files at all, and the Soroban client lacks a .env.example despite its README referencing one. This feature audits the required env vars for every active app and ensures each surface ships with a clear, complete, and consistently formatted example file so any contributor can get running with a single copy-and-edit step.
- Backend: The NestJS API located at
backend/, the primary runtime that coordinates Stellar payments, invoice management, and authentication. - Web: The Next.js frontend located at
web/, consumed by browser-based merchants. - Mobile: The Expo / React Native app located at
mobile/, consumed by merchants on iOS and Android. - Soroban_Client: The TypeScript helper library located at
soroban/client/, used by example scripts and the Backend to interact with the deployed Soroban smart contract. - Env_Example_File: A committed
.env.examplefile that documents every environment variable an app reads, with safe placeholder values and inline comments. - Critical_Var: An environment variable whose absence causes the app to fail to start, throw an unhandled error at runtime, or silently produce wrong behavior (e.g., connecting to the wrong Stellar network).
- Optional_Var: An environment variable that has a safe default and whose absence does not prevent the app from starting or operating in development mode.
- Contributor: A developer who clones the repository and wants to run one or more app surfaces locally.
- README: The per-app
README.mdthat a Contributor reads first when setting up a surface.
User Story: As a Contributor, I want the backend .env.example to document every variable the server reads, so that I can configure the backend without inspecting source code.
- THE Backend
backend/.env.exampleSHALL include every variable validated by the Joi schema inbackend/src/app.module.ts, specifically:PORT,CORS_ORIGIN,DATABASE_URL,JWT_SECRET,HORIZON_URL,STELLAR_NETWORK_PASSPHRASE,MERCHANT_PUBLIC_KEY,USDC_ISSUER,USDC_ASSET_CODE,MEMO_PREFIX,HORIZON_POLL_INTERVAL,SOROBAN_RPC_URL,SOROBAN_CONTRACT_ID,ADMIN_SECRET_KEY,SOROBAN_EVENT_TOPIC,THROTTLE_TTL,THROTTLE_LIMIT,THROTTLE_AUTH_TTL,THROTTLE_AUTH_LIMIT,THROTTLE_INVOICE_TTL,THROTTLE_INVOICE_LIMIT,REDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_DB,REDIS_KEY_PREFIX,SLOW_DB_THRESHOLD_MS, andSLOW_NETWORK_THRESHOLD_MS. Any variable present in the Joi schema but absent from the file SHALL cause this criterion to fail. - WHEN a variable has a safe default value defined in the Joi schema or config factory, THE Backend
backend/.env.exampleSHALL show that exact default as the placeholder value (e.g.,PORT=3001,REDIS_HOST=localhost). - WHEN a variable is required with no default — specifically
DATABASE_URLandJWT_SECRET— THE Backendbackend/.env.exampleSHALL include an inline comment on the same line or the line immediately above that describes what value to supply and, where applicable, how to generate it (e.g.,# generate with: openssl rand -base64 32forJWT_SECRET). - WHEN a variable is a secret — specifically
JWT_SECRET,ADMIN_SECRET_KEY, andREDIS_PASSWORD— THE Backendbackend/.env.exampleSHALL include a comment containing the exact textWARNING: never commit a real valueon the line immediately above or inline with that variable. - THE Backend
backend/.env.exampleSHALL group variables under clearly labeled comment sections using the# ── Section Name ──format, with the following sections present in order:Database,JWT,Stellar Network,Soroban Contract,Rate Limiting,Redis, andObservability. - Each variable in
backend/.env.exampleSHALL be annotated with either# requiredor# optionalas an inline or preceding comment, matching itsrequired()/optional()designation in the Joi schema.
User Story: As a Contributor, I want a .env.example file in the web app directory, so that I can configure the Next.js frontend without guessing which NEXT_PUBLIC_ variables are needed.
- THE Web app SHALL have a
.env.examplefile atweb/.env.example, and this file SHALL be tracked by git (i.e., not matched by any.gitignorepattern in the repository). - THE
web/.env.exampleSHALL includeNEXT_PUBLIC_API_URLwith a placeholder value ofhttp://localhost:3001and an inline comment of# required. - THE
web/.env.exampleSHALL includeNEXT_PUBLIC_USDC_ISSUERwith the valueGA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVNand an inline comment reading# Testnet default; replace with mainnet issuer for production. - THE
web/.env.exampleSHALL contain an entry for everyprocess.env.*variable read by web app source files (underweb/) without a hardcoded fallback value. IF aprocess.envread is added to the web app source without a corresponding entry inweb/.env.example, THEN the file SHALL be considered incomplete. - THE
web/README.mdSHALL include a setup step that contains the exact copy commandcp web/.env.example web/.env.local(or its OS equivalent) and instructs contributors to run it before executingnpm run dev.
User Story: As a Contributor, I want a .env.example file in the mobile app directory, so that I can set up the Expo app without reading internal source files to discover which @env variables are required.
- THE Mobile app SHALL have a
.env.examplefile atmobile/.env.example, and this file SHALL be tracked by git (i.e., not matched by any.gitignorerule — note the root.gitignoreuses.env.*which would match.env.example, so.env.exampleSHALL be explicitly unignored with a!.env.examplerule or equivalent). - THE
mobile/.env.exampleSHALL include all variables declared inmobile/types/env.d.ts:API_URL,STELLAR_NETWORK_PASSPHRASE,REOWN_PROJECT_ID, andAPP_NAME. If new variables are added toenv.d.ts, they SHALL be added tomobile/.env.examplein the same change. - IF a variable has a safe testnet default, THEN THE
mobile/.env.exampleSHALL show that default as the placeholder value:API_URL=http://localhost:3001,STELLAR_NETWORK_PASSPHRASE="Test SDF Network ; September 2015",APP_NAME=Invoisio. - IF a variable requires a contributor-specific value with no safe default — specifically
REOWN_PROJECT_ID— THEN THEmobile/.env.exampleSHALL include an inline comment reading# required — obtain from https://cloud.reown.com. - THE
mobile/SMOKE_TEST_CHECKLIST.mdSHALL include a setup step containing the exact copy commandcp mobile/.env.example mobile/.env(or its OS equivalent) and the Expo dev server start command, before any smoke test steps that require the app to run. - THE
mobile/.env.examplefile SHALL NOT be matched by any.gitignorepattern at the repo root or withinmobile/. A!mobile/.env.examplenegation rule (or equivalent) SHALL be added to the root.gitignoreto ensure the file is committed.
User Story: As a Contributor, I want a .env.example file in the Soroban client directory, so that I can run the example scripts without manually reconstructing the required variables from the README prose.
- THE Soroban_Client SHALL have a
.env.examplefile atsoroban/client/.env.example, tracked by git (not matched by any.gitignorepattern). - THE
soroban/client/.env.exampleSHALL includeSOROBAN_RPC_URLwith the valuehttps://soroban-testnet.stellar.organd an inline comment of# required. - THE
soroban/client/.env.exampleSHALL includeSTELLAR_NETWORK_PASSPHRASEwith the value"Test SDF Network ; September 2015"and an inline comment of# required. - THE
soroban/client/.env.exampleSHALL includeSOROBAN_CONTRACT_IDwith a placeholder (e.g.,CXXX...) and a comment reading# required — copy from soroban/contracts/invoice-payment/.contract-id after deployment. This variable is read by the TypeScript client scripts (e.g.,soroban-config.ts). - THE
soroban/client/.env.exampleSHALL includeCONTRACT_IDwith the same placeholder and a comment reading# required — same value as SOROBAN_CONTRACT_ID; read by query-config.ts via process.env.CONTRACT_ID. This addresses the fact thatquery-config.tsreadsprocess.env.CONTRACT_IDrather thanSOROBAN_CONTRACT_ID. - THE
soroban/client/.env.exampleSHALL includeADMIN_SECRET_KEYwith the placeholderSXXX...and a comment containing the exact textWARNING: never commit a real valueon the line immediately above or inline. - THE
soroban/client/.env.exampleSHALL includeSOURCE_PUBLIC_KEYwith the placeholderGXXX...and an inline comment reading# optional — used for read-only operations; fallback when ADMIN_SECRET_KEY is absent. - THE
soroban/client/.env.exampleSHALL includePAYER_PUBLIC_KEYwith the placeholderGXXX...and an inline comment reading# optional — payer address used in the example:record script; fallback to SOURCE_PUBLIC_KEY when absent. - THE
soroban/client/.env.exampleSHALL includeINVOICE_IDwith the placeholder valueinvoisio-demo-001and an inline comment reading# optional — overrides the default invoice ID in example scripts. - THE
soroban/README.md"TypeScript Client Helper" setup subsection SHALL contain acp soroban/client/.env.example soroban/client/.envstep, and the filesoroban/client/.env.exampleSHALL exist at that exact path so the command succeeds.
User Story: As a Contributor, I want the env example files across all apps to follow a consistent structure, so that I can scan any file and immediately understand which variables are required, which are optional, and how they relate to shared Stellar configuration.
- THE Env_Example_File for each of the four surfaces (
backend/.env.example,web/.env.example,mobile/.env.example,soroban/client/.env.example) SHALL use# ── Section Name ──comment headers to group related variables, and each variable SHALL carry either a# requiredor# optionalinline or preceding annotation. - WHEN the same Stellar network variable appears in multiple Env_Example_Files — specifically
STELLAR_NETWORK_PASSPHRASE,SOROBAN_RPC_URL(where applicable), andUSDC_ISSUER/NEXT_PUBLIC_USDC_ISSUER— THE placeholder values SHALL be byte-for-byte identical across all files that include that variable. - WHEN a variable is a secret — defined as: a private key (value starting with
Sfor Stellar secret keys), a JWT secret, a database password, or a third-party API key — THE Env_Example_File SHALL include a comment containing the exact textWARNING: never commit a real valueon the line immediately above or inline with that variable. - THE root
README.mdSHALL include or link to an "Environment Setup" section that explicitly names all four surfaces and their example files:backend/.env.example,web/.env.example,mobile/.env.example, andsoroban/client/.env.example, and directs contributors to the relevant per-app README or checklist for detailed setup instructions. - IF a variable is referenced in an app's source code via
process.env.*, a typed@envimport, or a config factory without a hardcoded fallback value, AND that variable is absent from the app's Env_Example_File, THEN the Env_Example_File SHALL be considered incomplete and SHALL be updated to include it before the change is merged. - Each of the four Env_Example_Files SHALL exist at its designated path as a committed, git-tracked file. The root
.gitignorepattern.env.*currently matches.env.examplefiles; therefore, a negation rule!**/.env.example(or per-path equivalents) SHALL be added to the root.gitignoreso that all four example files are tracked by git.