Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/playwright-visual-regression.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Playwright Visual Regression

on:
pull_request:
branches:
- main

jobs:
visual-regression:
name: Visual regression
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'
cache-dependency-path: package-lock.json

- name: Install dependencies
run: npm install

- name: Install Playwright browsers
run: npx playwright install --with-deps

- name: Run visual regression tests
run: npm run test:visual

- name: Upload visual regression artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: visual-regression-artifacts
path: |
playwright-report
test-results
e2e/screenshots
284 changes: 220 additions & 64 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -1,115 +1,271 @@
# Deployment Guide
# Deployment Guide

This guide explains how to deploy the **Stellar Goal Vault** project:

- **Contract → Stellar testnet**
- **Backend → Render**
- **Frontend → Vercel**

---

## Backend Deployment (Render)
## Prerequisites

### 1. Create a Render Web Service
- Go to https://render.com
- Click **New → Web Service**
- Connect your GitHub repository
- GitHub repository access
- Node.js 18+ and npm 9+
- Render account for backend deployment
- Vercel account for frontend deployment
- Soroban CLI installed for contract deployment
- Stellar testnet account funded with friendbot

---

### 2. Configure the Service
## 1. Deploy the Soroban Contract (Testnet)

- **Root Directory:** `backend` *(update if your backend folder name differs)*
The backend uses `CONTRACT_ID` to enable the on-chain pledge flow.

### 1.1 Install Soroban CLI

Follow the official Soroban setup guide:
https://soroban.stellar.org/docs/getting-started/setup#install-the-soroban-cli

### 1.2 Fund a Testnet Account

If you do not already have a testnet account, fund one with friendbot:

```bash
PUBLIC_KEY="G..."
curl "https://friendbot.stellar.org/?addr=$PUBLIC_KEY"
```

### 1.3 Deploy the Contract

From the repository root:

```bash
SECRET_KEY="S..." npm run deploy:contract
```

If deploy succeeds, the script will:

1. Build the contract
2. Deploy it to Stellar testnet
3. Print the contract ID
4. Save the contract ID to `contracts/contract_id.txt`

### 1.4 Save the Contract ID

Set the backend environment variable:

```env
CONTRACT_ID=<your-contract-id>
```

If you want to override the default RPC endpoint or network passphrase:

```bash
SECRET_KEY="S..." NETWORK_PASSPHRASE="Test SDF Network ; September 2015" RPC_URL="https://soroban-testnet.stellar.org:443" npm run deploy:contract
```

---

## 2. Backend Deployment (Render)

### 2.1 Create a Render Web Service

1. Sign in to https://render.com
2. Click **New → Web Service**
3. Connect your GitHub repository
4. Choose the `backend` folder as the Root Directory

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix DB_PATH example to match the configured Render root directory.

Given Line 78 sets the Render Root Directory to backend, the example on Line 118 (DB_PATH=backend/data/campaigns.db) is path-inconsistent and will resolve to a nested backend/backend/... location. Use a path relative to the backend root instead.

Suggested doc fix
-DB_PATH=backend/data/campaigns.db
+DB_PATH=data/campaigns.db

Also applies to: 118-118

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@DEPLOYMENT.md` at line 78, The DB_PATH example is inconsistent with the
Render Root Directory being set to "backend"; update the example environment
variable so it is relative to that root (replace
DB_PATH=backend/data/campaigns.db with DB_PATH=data/campaigns.db) and apply the
same fix for any other occurrences of the redundant "backend/" prefix in the
DEPLOYMENT.md examples or env snippets to avoid creating nested backend/backend
paths.


### 2.2 Configure Build and Start

- **Build Command:**

```bash
npm install && npm run build
npm install && npx tsc -p ./tsconfig.json
```
Start Command:

- **Start Command:**

```bash
npm start
node dist/index.js
```
### 3. Environment Variables

Add the following variables in Render:
- **Health Check Path:**

```text
/api/health
```

Render will provide `PORT` automatically. The backend defaults to `3001` when `PORT` is unset, but Render will set it to the correct value in the service environment.

### 2.3 Required Environment Variables

Set these in Render's environment configuration:

```env
PORT=3000
ALLOWED_ASSETS=USDC,XLM,ARS
CONTRACT_ID=<your-contract-id>
SOROBAN_RPC_URL=https://soroban-testnet.stellar.org:443
CONTRACT_ID=your_contract_id
```
### 4. Database Notes

This project uses SQLite (`better-sqlite3`), which is file-based.
### 2.4 Recommended Backend Environment Variables

- SQLite does NOT persist reliably on Render
- Data may reset on redeploy
Optionally add:

Recommended:
Use a hosted database for production:
```env
ALLOWED_ASSETS=USDC,XLM
ALLOWED_ORIGINS=https://<your-vercel-domain>
DB_PATH=backend/data/campaigns.db
DEFAULT_MAX_PER_CONTRIBUTOR=0
```

- PostgreSQL (Neon, Supabase)
- MongoDB Atlas
- `ALLOWED_ORIGINS` restricts CORS to your frontend domain.
- Do not rely on SQLite for production data persistence on Render; the container filesystem is ephemeral.

### 5. Deployment Tips
- Ensure your Soroban contract is deployed before running backend
- Keep your `CONTRACT_ID` secure
- Confirm API is accessible after deployment
### 2.5 Notes on Render and SQLite

- The backend uses SQLite (`better-sqlite3`) by default.
- Render's storage is not permanent across redeploys.
- For production, use an external database and update `DB_PATH` accordingly.

---

## Frontend Deployment (Vercel)
## 3. Frontend Deployment (Vercel)

### 1. Import Project
- Go to https://vercel.com
- Click Add New Project
- Import your GitHub repository
### 3.1 Import the Project

### 2. Configure Project
- Root Directory: `frontend` (update if different)
1. Sign in to https://vercel.com
2. Click **Add New Project**
3. Select the Stellar Goal Vault repository
4. Use the `frontend` folder as the Root Directory

### 3.2 Configure Build

- **Build Command:**

Build Command:
```bash
npm run build
npm install && npm run build
```
Output Directory:
```bash

- **Output Directory:**

```text
dist
```

### 3. Environment Variables
Add:
### 3.3 Configure Environment Variables

Set the frontend base API URL:

```env
VITE_API_URL=https://your-backend-url.onrender.com
VITE_API_URL=https://<your-backend-service>.onrender.com
```

This value must be the Render backend URL without a trailing `/`.

### 3.4 Deploy

1. Save the environment variables
2. Trigger deploy
3. Wait until the build succeeds

---

## 4. Verify Deployment

### 4.1 Verify Backend

Open in browser or use curl:

```bash
curl https://<your-backend-service>.onrender.com/api/health
```

Expected response:

```json
{
"service": "stellar-goal-vault-backend",
"status": "ok",
"timestamp": "...",
"uptimeSeconds": 0,
"database": {
"status": "up",
"reachable": true
}
}
```

### 4. Deploy
### 4.2 Verify Frontend

1. Open your Vercel frontend URL
2. Confirm the app loads
3. Confirm the app makes API requests to the Render backend

If the app fails to load data, verify the frontend env variable `VITE_API_URL`.

Click Deploy and wait for build to complete.
### 4.3 Confirm Contract Integration

## Connecting Frontend to Backend
- Deploy backend first
- Copy backend URL from Render
- Set it as `VITE_API_URL` in Vercel
- Redeploy frontend if needed
If `CONTRACT_ID` is missing, the app may still run, but on-chain pledge integration will not function.

Use the backend health endpoint and the frontend deployment status in Vercel to verify end-to-end availability.

---

## 5. Troubleshooting

## Troubleshooting
Backend not responding
- Check logs in Render dashboard
- Confirm environment variables are set correctly
### Contract deployment failures

- `soroban-cli not installed`: install it from Soroban docs
- `SECRET_KEY` invalid: confirm the secret key belongs to a funded testnet account
- friendbot errors: regenerate the public address and retry
- contract ID not saved: inspect `contracts/contract_id.txt`

### Backend build or start errors

- If build fails, run locally:

```bash
cd backend
npm install
npx tsc -p ./tsconfig.json
```

- If Render cannot start the service:
- ensure the start command is `node dist/index.js`
- ensure `CONTRACT_ID` and `SOROBAN_RPC_URL` are set
- use Render logs to troubleshoot startup errors

### Frontend API errors

- If the frontend shows network failures:
- verify `VITE_API_URL` uses `https://`
- confirm the Vercel environment variable is deployed
- confirm Render backend health check passes at `/api/health`

### CORS errors

- Set `ALLOWED_ORIGINS=https://<your-vercel-domain>` on the backend
- If in development, leave `ALLOWED_ORIGINS` empty so the backend permits local origins

### Data persistence issues

- Backend uses SQLite by default
- Render storage is ephemeral; data may reset on redeploy
- For production, use an external database and add a persistent `DB_PATH`

---

Frontend not calling API
- Verify `VITE_API_URL` is correct
- Ensure backend allows CORS requests
## Quick Test Checklist

Data not persisting
- This is due to SQLite
- Switch to a hosted database for production
1. Contract deployed to testnet and `CONTRACT_ID` saved
2. Render backend service built with `npx tsc -p ./tsconfig.json`
3. Backend started with `node dist/index.js`
4. Render health check path set to `/api/health`
5. Vercel frontend configured with `VITE_API_URL`
6. Frontend loads and fetches data from the backend

## Summary
- Backend runs on Render using Node.js + Express
- Frontend runs on Vercel using Vite + React
- Environment variables must be configured correctly
- SQLite is suitable for development but not production
If these items pass, the deployment guide has been successfully applied.

## Related Documentation
- [Runbook — Common Operational Tasks](./RUNBOOK.md) — step-by-step procedures for resetting the database, rotating API keys, redeploying contracts, rolling back the backend, and clearing the event cache.
Expand Down
Loading
Loading