- TypeScript 96.5%
- Bru 2.3%
- Ruby 1.2%
|
|
||
|---|---|---|
| .claude | ||
| .forgejo/workflows | ||
| bruno/recipe-backend | ||
| docs | ||
| scripts | ||
| src | ||
| .gitignore | ||
| CLAUDE.md | ||
| contract.ref | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
| vitest.integration.config.ts | ||
Recipe Backend
Backend for a personal recipe management application. Users can create and browse recipes, organize them into weekly meal plans, share plans with other users, and import recipes from photos via AI. Authentication supports both password login and passkeys (WebAuthn).
Tech stack: Node.js · Express · TypeScript · TypeORM · PostgreSQL · Vitest
For architecture details, layer model, data model, and design decisions see docs/architecture.md.
Quick start
# Install dependencies
npm install
# Create and fill in the environment file (see Environment setup below)
cp .env.development.example .env.development
# Apply database migrations
npm run migration
# Start in watch mode (TypeScript compiler + nodemon in parallel)
npm run start:dev
The server starts on the host and port configured in .env.development (default localhost:4000).
Environment setup
Create .env.development in the project root. Required variables:
| Variable | Example | Notes |
|---|---|---|
DB_HOST |
localhost |
|
DB_PORT |
5432 |
|
DB_USERNAME |
recipe-backend |
|
DB_PASSWORD |
… |
|
DB_DATABASE |
recipe-backend-dev |
|
JWT_SECRET |
long random string | Generate with openssl rand -base64 64 |
ALLOWED_ORIGINS |
http://localhost:5173 |
Comma-separated frontend origins |
PORT |
4000 |
|
HOST |
localhost |
Use 0.0.0.0 to bind on all interfaces |
IMAGES_DIR |
/srv/recipe-backend/images |
Absolute path; must exist and be writable |
ANTHROPIC_API_KEY |
sk-ant-… |
Required for AI recipe import; feature disabled if absent |
ANTHROPIC_MODEL |
claude-sonnet-4-6 |
|
WEBAUTHN_RP_ID |
localhost |
Frontend hostname — no protocol or port |
WEBAUTHN_RP_NAME |
Recipe App |
Shown in browser passkey prompts |
WEBAUTHN_ORIGIN |
http://localhost:5173 |
Full frontend origin as the browser sees it |
.env.development is gitignored and must never be committed. For stage and production values see docs/deployment.md.
Cheat sheet
Dev server
npm run start:dev # Compile TypeScript (watch) + nodemon in parallel — the main dev command
npm run watch # TypeScript watch only (no server)
npm run build # Compile once
npm run start:prod # Run compiled output (production)
Tests
npm test # Run once
npm run test:watch # Watch mode — re-runs on file changes
npm run test:coverage # Coverage report (output in coverage/)
Database migrations
# Apply all pending migrations
npm run migration
# Generate a new migration from entity changes (replace MyMigrationName)
npm run typeorm -- migration:generate src/migrations/MyMigrationName -d ./src/data-source.ts
# Create a blank migration file to fill in manually
npm run typeorm -- migration:create src/migrations/MyMigrationName
Migrations are TypeScript source files in src/migrations/ compiled to build/migrations/. Never use synchronize: true.
Environment file
# Restore .env.development if accidentally deleted
git show c200dc1^:.env.development > .env.development
API testing (Bruno)
Bruno request files live in bruno/recipe-backend/. Open that folder in Bruno, select an environment from environments/ (gitignored), and fire requests against the running dev server.
Documentation
docs/architecture.md— layer model, entities, auth, design decisionsdocs/deployment.md— pipeline, Puppet, full environment variable referencedocs/adr/— Architecture Decision Records