Date: 2026-03-23
This repo is a TypeScript/Node/Express API backed by PostgreSQL via TypeORM. The main entrypoint is src/index.ts and the compiled output is dist/.
- Install deps:
npm ci
- Create
.env:
Copy-Item .env.example .env
Minimal .env to boot locally:
NODE_ENV=local_dev
PORT=8002
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=postgres
DATABASE_NAME=fundable_db
# Cairo/StarkNet integration (local mock)
CAIRO_MOCK=true- Ensure DB exists + migrate:
npm run ensure-dbnpm run typeorm -- migration:run
- Build + start:
npm run buildnode --env-file=.env dist/index.js
- Seeding is disabled (no-op) to avoid missing-module startup blockers:
src/config/persistence/seeder.ts. - DB config is validated early and fails fast if required env vars are missing:
src/config/persistence/data-source.ts.
- Health:
GET /→{ success: false, message: ... } - V1 (existing):
/v1/*- Distributions:
GET /v1/distributions,POST /v1/distributions
- Distributions:
- API V1 (new):
/api/v1/*- Campaigns (new):
POST /api/v1/campaigns(JWT required, 5/hour per user)
- Campaigns (new):
Endpoint:
POST /api/v1/campaigns
Body:
{
"campaign_ref": "ABCDE",
"target_amount": "1000",
"donation_token": "0x1"
}Behavior:
- Validates input (5-char ref, positive u256 string, StarkNet address format).
- Enforces uniqueness on
campaign_ref(DB + unique index). - Requires JWT with
suband awalletAddress(oraddress) claim. - Rate limited: max 5 campaign creates per user per hour.
- Persists to DB (
campaignstable) and writes an audit entry (audit_logs). - On-chain integration:
- Local dev:
CAIRO_MOCK=truereturns mock tx hash + campaign id. - Real chain: set
CAIRO_MOCK=falseand provideCAIRO_RPC_URL,CAIRO_ACCOUNT_ADDRESS,CAIRO_PRIVATE_KEY,CAIRO_FACTORY_CONTRACT_ADDRESS.
- Local dev:
npm testrunsnode --testwithc8coverage checks (scoped to the new feature modules viapackage.json).