Skip to content

Commit 597ff71

Browse files
authored
Merge pull request #734 from Anasabubakar/chore/fresh-clone-install-build-test
Fresh-clone reliability: install/build/test, coverage gates, logging/error tracking, dep audits, env docs, CI typecheck, UI file splits
2 parents daae3cb + 2728791 commit 597ff71

30 files changed

Lines changed: 1639 additions & 702 deletions

.env.example

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ NEXT_PUBLIC_POOL_CONTRACT_ID=CAKEWH7SJCXGV2MH2WZYIX3QDPTSSBQFXYVYBOWAGLNBBZMPLE2
8484
# Required: yes
8585
NEXT_PUBLIC_ESCROW_CONTRACT_ID=CAJWGUKDTTC3SKN4RAAY72J4DVIIYSCFHX6GIMNTT22ABMISJK4GBCEH
8686

87+
# NEXT_PUBLIC_AGENT_REGISTRY_CONTRACT_ID
88+
# Layer: frontend, SDK
89+
# Type: Stellar contract ID string
90+
# Required: no (until Underwrite's agent-registry contract is deployed;
91+
# mirrors the backend AGENT_REGISTRY_CONTRACT below)
92+
# Default: none
93+
NEXT_PUBLIC_AGENT_REGISTRY_CONTRACT_ID=
94+
8795
# ── Asset configuration (frontend / SDK) ─────────────────────────────────────
8896
# NEXT_PUBLIC_USDC_ISSUER
8997
# Layer: frontend, SDK
@@ -189,6 +197,17 @@ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/trusttrove?sslmode=di
189197
# Source: Neon direct connection, migration tooling, or admin tasks
190198
DATABASE_URL_UNPOOLED=
191199

200+
# TEST_DATABASE_URL
201+
# Layer: indexer/backend (test-only)
202+
# Type: PostgreSQL connection URL
203+
# Required: no
204+
# Default: none — when unset, the Go integration tests in indexer/db and
205+
# indexer/listener skip instead of failing (`go test ./...`
206+
# passes either way). Set this to a disposable Postgres instance
207+
# to actually exercise those tests and their coverage locally.
208+
# Source: local .env or CI service container
209+
TEST_DATABASE_URL=
210+
192211
# API_PORT
193212
# Layer: indexer/backend
194213
# Type: integer port
@@ -213,6 +232,26 @@ PORT=
213232
# Source: local .env or deployment env
214233
INDEXER_POLL_INTERVAL_MS=5000
215234

235+
# INDEXER_MIGRATIONS_DIR
236+
# Layer: indexer/backend
237+
# Type: absolute or relative directory path
238+
# Required: no
239+
# Default: auto-detected relative to the running binary/working directory
240+
# (indexer/db/migrations); only needed when that auto-detection
241+
# doesn't apply, e.g. running the compiled binary from an unusual
242+
# working directory or in CI.
243+
# Source: local .env or deployment env
244+
INDEXER_MIGRATIONS_DIR=
245+
246+
# APP_ENV
247+
# Layer: indexer/backend
248+
# Type: string enum: development | production
249+
# Required: no
250+
# Default: development
251+
# Source: local .env or deployment env. In production, JWT_SECRET and
252+
# SERVER_SEED below become required instead of auto-generated.
253+
APP_ENV=development
254+
216255
# JWT_SECRET
217256
# Layer: indexer/backend
218257
# Type: string secret
@@ -229,6 +268,18 @@ JWT_SECRET=change_me_before_production
229268
# Source: local .env or deployment env
230269
JWT_EXPIRY_HOURS=24
231270

271+
# SERVER_SEED
272+
# Layer: indexer/backend
273+
# Type: string secret (Stellar keypair seed, starts with 'S')
274+
# Required: yes in production; leave empty for local/development — the
275+
# indexer generates a valid random keypair automatically at
276+
# startup when this is unset. Unlike JWT_SECRET, this is parsed
277+
# as a real Stellar strkey immediately, so a placeholder string
278+
# like "change_me" fails startup instead of just being insecure.
279+
# Default: none (auto-generated when empty and APP_ENV != production)
280+
# Source: generated Stellar keypair in local/deployment secret manager
281+
SERVER_SEED=
282+
232283
# ALLOWED_ORIGINS
233284
# Layer: indexer/backend
234285
# Type: comma-separated URLs
@@ -237,6 +288,30 @@ JWT_EXPIRY_HOURS=24
237288
# Source: Render or local .env
238289
ALLOWED_ORIGINS=https://trustrove.vercel.app,http://localhost:3000
239290

291+
# CORS_ALLOWED_ORIGINS
292+
# Layer: indexer/backend
293+
# Type: comma-separated URLs
294+
# Required: no
295+
# Default: only read when ALLOWED_ORIGINS above is unset
296+
# Source: alternate name for ALLOWED_ORIGINS; set one or the other, not both
297+
CORS_ALLOWED_ORIGINS=
298+
299+
# RATE_LIMIT_RPS
300+
# Layer: indexer/backend
301+
# Type: integer requests per second (per client)
302+
# Required: no
303+
# Default: 10
304+
# Source: local .env or deployment env
305+
RATE_LIMIT_RPS=10
306+
307+
# SENTRY_DSN
308+
# Layer: indexer/backend
309+
# Type: URL string (Sentry project DSN)
310+
# Required: no
311+
# Default: none — leave empty to disable error tracking entirely
312+
# Source: Sentry project settings, set as a secret in the deployment env
313+
SENTRY_DSN=
314+
240315
# ── Frontend-only deployment settings ────────────────────────────────────────
241316
# NEXT_PUBLIC_API_BASE_URL
242317
# Layer: frontend
@@ -245,3 +320,22 @@ ALLOWED_ORIGINS=https://trustrove.vercel.app,http://localhost:3000
245320
# Default: http://localhost:8080 if the frontend API helper is left unconfigured
246321
# Source: Vercel env or local .env.local
247322
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
323+
324+
# NEXT_PUBLIC_APP_URL
325+
# Layer: frontend
326+
# Type: URL string
327+
# Required: no
328+
# Default: http://localhost:3000, used to build absolute links (e.g. shared
329+
# invoice URLs) when the request's own origin isn't available
330+
# Source: Vercel env or local .env.local
331+
NEXT_PUBLIC_APP_URL=http://localhost:3000
332+
333+
# ── Ambient / CI-provided (do not set by hand) ───────────────────────────────
334+
# CI
335+
# Layer: frontend (apps/web/playwright.config.ts)
336+
# Type: boolean-ish string, any non-empty value is truthy
337+
# Required: no
338+
# Default: unset locally; automatically set to "true" by GitHub Actions and
339+
# most other CI providers. Only affects Playwright's own retry/
340+
# worker/dev-server-reuse behavior — leave unset in .env.local.
341+
CI=

.github/dependabot.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "npm"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
8+
- package-ecosystem: "npm"
9+
directory: "/apps/web"
10+
schedule:
11+
interval: "weekly"
12+
13+
- package-ecosystem: "npm"
14+
directory: "/packages/sdk"
15+
schedule:
16+
interval: "weekly"
17+
18+
- package-ecosystem: "gomod"
19+
directory: "/indexer"
20+
schedule:
21+
interval: "weekly"

.github/workflows/ci.yml

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ jobs:
2929
- name: Install Dependencies
3030
run: pnpm install --frozen-lockfile
3131

32+
- name: Typecheck
33+
run: pnpm typecheck
34+
35+
- name: Audit npm dependencies
36+
# pnpm-workspace.yaml's auditConfig.ignoreGhsas lists the specific,
37+
# already-triaged advisories this ignores (next 14->15 and toml 3->4,
38+
# both needing a major-version bump, not a patch override) and why.
39+
# Any new high/critical advisory not on that list fails the build.
40+
run: pnpm audit --audit-level=high
41+
3242
- name: Build Packages (SDK & Web App)
3343
run: pnpm build
3444
env:
@@ -50,14 +60,29 @@ jobs:
5060
name: Verify Go Indexer & API
5161
runs-on: ubuntu-latest
5262

63+
services:
64+
postgres:
65+
image: postgres:15-alpine
66+
env:
67+
POSTGRES_USER: postgres
68+
POSTGRES_PASSWORD: postgres
69+
POSTGRES_DB: trusttrove_test
70+
ports:
71+
- 5432:5432
72+
options: >-
73+
--health-cmd "pg_isready -U postgres"
74+
--health-interval 5s
75+
--health-timeout 5s
76+
--health-retries 10
77+
5378
steps:
5479
- name: Checkout Code
5580
uses: actions/checkout@v4
5681

5782
- name: Setup Go
5883
uses: actions/setup-go@v5
5984
with:
60-
go-version: "1.22"
85+
go-version: "1.25"
6186

6287
- name: Get Dependencies
6388
run: |
@@ -72,7 +97,32 @@ jobs:
7297
- name: Test Go Services
7398
run: |
7499
cd indexer
75-
go test -v ./...
100+
go test -v -coverprofile=coverage.out ./...
101+
env:
102+
TEST_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/trusttrove_test?sslmode=disable
103+
INDEXER_MIGRATIONS_DIR: ${{ github.workspace }}/indexer/db/migrations
104+
105+
- name: Enforce indexer/db coverage threshold
106+
run: |
107+
cd indexer
108+
go test -covermode=atomic -coverprofile=db-coverage.out ./db/... \
109+
| tee /dev/stderr \
110+
| grep -oE 'coverage: [0-9.]+% of statements' \
111+
| grep -oE '[0-9.]+' \
112+
> /tmp/db_coverage_pct.txt
113+
pct=$(cat /tmp/db_coverage_pct.txt)
114+
echo "indexer/db statement coverage: ${pct}%"
115+
awk -v pct="$pct" 'BEGIN { exit !(pct >= 70) }' \
116+
|| (echo "indexer/db coverage ${pct}% is below the required 70% threshold" && exit 1)
117+
env:
118+
TEST_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/trusttrove_test?sslmode=disable
119+
INDEXER_MIGRATIONS_DIR: ${{ github.workspace }}/indexer/db/migrations
120+
121+
- name: Vulnerability scan (govulncheck)
122+
run: |
123+
go install golang.org/x/vuln/cmd/govulncheck@latest
124+
cd indexer
125+
govulncheck ./...
76126
77127
- name: Lint Go Services
78128
run: |

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ indexer/indexer.exe
1717
*.wasm
1818
*.exe
1919

20+
# Test coverage output
21+
coverage/
22+
*.out
23+
2024
# Debug logs
2125
npm-debug.log*
2226
yarn-debug.log*

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Yield distributes to LP shares
7272
| Wallet | Freighter browser extension |
7373
| Payments | USDC on Stellar |
7474
| SDK | Custom TypeScript contract client wrappers |
75-
| Indexer | Go 1.22, chi router, pgx v5 |
75+
| Indexer | Go 1.25, chi router, pgx v5 |
7676
| Database | PostgreSQL 15 |
7777
| Hosting | Vercel (frontend), Render (indexer + database) |
7878

@@ -105,7 +105,7 @@ Yield distributes to LP shares
105105

106106
- Node.js 20+
107107
- pnpm 9+
108-
- Go 1.22+
108+
- Go 1.25+
109109
- Docker
110110
- [Freighter](https://freighter.app) browser extension
111111

@@ -148,6 +148,25 @@ Open [http://localhost:3000](http://localhost:3000), connect Freighter on testne
148148

149149
---
150150

151+
## Build & Test
152+
153+
Run these from the repository root after `pnpm install`. CI runs the same commands on every push and pull request against `main` (see [`.github/workflows/ci.yml`](./.github/workflows/ci.yml)).
154+
155+
```bash
156+
# Build the SDK and the web app
157+
pnpm build
158+
159+
# Run the SDK and web app unit test suites
160+
pnpm test
161+
162+
# Run the Go indexer's test suite
163+
cd indexer && go test ./...
164+
```
165+
166+
Building the web app reads `NEXT_PUBLIC_*` variables from `.env.local` (see step 2 above) — without it, `pnpm build` still succeeds but the app logs `Missing required environment variables` warnings.
167+
168+
---
169+
151170
## Contributing
152171

153172
We welcome contributions from the Stellar community. Before opening a PR, please read [CONTRIBUTING.md](./CONTRIBUTING.md).

apps/web/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ See the root [`README.md`](../../README.md) for the full project overview and de
2222

2323
- Node.js 20+
2424
- pnpm 9+
25-
- Go 1.22+
25+
- Go 1.25+
2626
- PostgreSQL 15+ or Docker Compose
2727
- Freighter wallet configured for Stellar Testnet
2828

0 commit comments

Comments
 (0)