An open-sourced backend service for Resell.
- Runtime: Node 20, Express (
routing-controllers+ TypeORM 0.2) - Database: Neon PostgreSQL 18 (pooled URL for the app, direct URL for migrations)
- Hosting: Vercel (Fluid Express). Docker Swarm / DigitalOcean are retired.
Semantic similarity (similar posts, request matching, search vectors) uses OpenAI embeddings (text-embedding-3-small) stored as float[], with exact cosine KNN in TypeScript. Set OPENAI_API_KEY in your .env. Without it, embeddings stay null and those features degrade gracefully. No pgvector extension is required.
-
Install Node 20 (
nvm install 20 && nvm use 20). -
From the repo root:
npm install -
Configure Neon for your editor (once per machine):
npx neon@latest init
Select Cursor, VS Code, and Claude CLI (Space to toggle). For Zed:
npx add-mcp https://mcp.neon.tech/mcp -a zed -g
-
Link env vars to the Neon project (writes
DATABASE_URL/DATABASE_URL_UNPOOLEDinto.env):npx neon@latest env pull
Or copy
.env_templateto.envand fill values manually. -
Firebase: set either
FIREBASE_SERVICE_ACCOUNT_JSON(stringified JSON, preferred for Vercel) orFIREBASE_SERVICE_ACCOUNT_PATH(local file path). -
Apply schema:
npm run db:migrate
-
Run locally:
npm run dev
Health check:
GET http://localhost:3000/health
Neon branches used by this project:
| Neon branch | Use |
|---|---|
production |
Vercel Production |
staging |
Vercel Preview / main deploys |
dev |
Local development (optional personal branches later) |
Project context is stored in .neon (safe to commit; no secrets).
npm run db:migrateCI runs migrations via .github/workflows/migrate-neon.yml using GitHub secrets:
DATABASE_URL_UNPOOLED_PRODUCTIONDATABASE_URL_UNPOOLED_STAGINGDATABASE_URL_UNPOOLED_DEV
Push to release migrates production; push to main migrates staging. App deploy is handled by Vercel Git integration (not Docker).
- Import the GitHub repo in Vercel.
- Set env vars for Production / Preview to match Neon branch URLs, plus Firebase JSON,
OPENAI_API_KEY, upload settings,IS_PROD, andCRON_SECRET. - Entry is
src/app.ts(default export for Fluid Express;app.listenonly when not on Vercel). - Cron:
vercel.jsonhitsGET /api/cron/transaction-confirmationswithAuthorization: Bearer ${CRON_SECRET}. The transaction confirmation job body is still disabled until product re-enables it.
npm run db:seedSeeding is skipped when IS_PROD=true.
- Local Homebrew / Docker Postgres install (use Neon
devinstead) - DigitalOcean dump/import scripts (one-time migration only if needed)
Dockerfile/docker-compose.ymland the disabled Swarm workflows under.github/workflows/deploy-*.yml