3.7 KiB
3.7 KiB
Carry Your Live - Backend API
REST API for the Carry Your Live task management app with offline-first sync support.
Tech Stack
- Runtime: Node.js 20+ with TypeScript
- Framework: Express.js
- Database: PostgreSQL with Drizzle ORM
- Authentication: JWT (JSON Web Tokens)
- Validation: Zod
Quick Start
Option A — Docker (Postgres + API in containers)
Requires Docker. Runs the database and the Node API together:
docker compose up --build
This starts:
carry-your-live-db— PostgreSQL 16 on port 5432carry-your-live-api— the API in dev mode (tsx watch, hot reload) on port 3000, schema auto-applied on start
Server runs at http://localhost:3000 (health check: GET /health).
For production-style serving of the built app:
# Build and run the slim prod image instead
docker build --target prod -t carry-your-live-api:prod .
docker run --rm -p 3000:3000 --env-file .env carry-your-live-api:prod
Option B — Local Node + Docker Postgres
Prerequisites
- Node.js 20+
- PostgreSQL 16+ (or use Docker)
Setup
-
Start PostgreSQL (using Docker):
docker-compose up -d postgres -
Install dependencies:
npm install -
Configure environment:
cp .env.example .env # Edit .env with your settings -
Run database migrations:
npm run db:push -
Start development server:
npm run dev
Server runs at http://localhost:3000
API Endpoints
Authentication
POST /api/auth/register- Register new userPOST /api/auth/login- LoginGET /api/auth/me- Get current user
Categories
GET /api/categories- List categoriesPOST /api/categories- Create categoryPATCH /api/categories/:id- Update categoryDELETE /api/categories/:id- Delete category
Tasks
GET /api/tasks- List tasks (with filters)GET /api/tasks/:id- Get task with subtasksPOST /api/tasks- Create taskPATCH /api/tasks/:id- Update taskDELETE /api/tasks/:id- Delete taskPOST /api/tasks/batch- Batch operations
Subtasks
GET /api/subtasks/task/:taskId- List subtasks for taskPOST /api/subtasks/task/:taskId- Create subtaskPATCH /api/subtasks/:id- Update subtaskDELETE /api/subtasks/:id- Delete subtask
Users
GET /api/users/me- Get user with settingsPATCH /api/users/me/settings- Update settings
Sync (Offline-first)
GET /api/sync?since=<timestamp>- Pull changes since timestampPOST /api/sync/push- Push local changes
Database Schema
See src/db/schema.ts for Drizzle schema definitions.
Sync Protocol
The sync endpoint uses a cursor-based approach:
- Pull: Client sends
sincetimestamp, server returns all changes since then - Push: Client sends batched changes with
lastPulledAt, server applies with conflict resolution (last-write-wins)
Environment Variables
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Required |
JWT_SECRET |
Secret for JWT signing | Required (32+ chars) |
PORT |
Server port | 3000 |
NODE_ENV |
Environment | development |
FRONTEND_URL |
CORS origin | http://localhost:8081 |
Production Deployment
- Set
NODE_ENV=production - Use strong
JWT_SECRET(32+ random chars) - Configure proper
DATABASE_URL - Run
npm run buildthennpm start - Use process manager (PM2, systemd) or container orchestration
The included Dockerfile has a prod stage that builds TypeScript and serves dist/
with production-only dependencies on a minimal node:20-alpine image.
License
MIT