- Node.js 20+
- npm
npm install
cp .env.example .env
# Fill in .env with your values| Command | What it does |
|---|---|
npm test |
Run the test suite (vitest) |
npm run lint |
Type-check with tsc --noEmit |
npm run build |
Compile TypeScript to dist/ |
npm start |
Run the compiled service (dist/index.js) |
npm run dev |
Watch mode for TypeScript compilation |
The src/ tree is grouped by role so each folder has a single reason to exist.
src/
index.ts Entry point — connects RabbitMQ, subscribes, handles shutdown
clients/ External integrations. Everything that talks to something outside the process.
stack-client.ts Cozy Stack API (token refresh on 401, per-call timeouts)
cloudery-client.ts Cloudery token endpoint (retry with backoff, per-FQDN token cache)
with-timeout.ts Generic Promise-race timeout helper
cozy-stack-client.d.ts Ambient types for the cozy-stack-client library
domain/ What a migration is. No HTTP, no config, no process plumbing.
migration.ts Core logic — iterative directory traversal, file transfers, progress tracking
tracking.ts Tracking document helpers with CouchDB 409 conflict retry + status guards
errors.ts Shared error-message extraction helper
doctypes.ts Cozy doctype identifiers used across the codebase
types.ts Migration command + tracking document schema
runtime/ Process wiring. How domain + clients get started and fed.
consumer.ts Message handler — validation, idempotency, quota check, early ACK
migration-runner.ts Concurrency cap + in-flight tracking for graceful shutdown
http-server.ts Ops HTTP server — /healthz, /readyz, /metrics
metrics.ts Prometheus registry + metric definitions
config.ts Environment variable parsing + Config type
test/
*.test.ts Unit tests for each module (mocked HTTP, no real services needed)
Tests use vitest with mocked fetch — no RabbitMQ or Stack instance required. Each module is tested independently through its public interface.
npm test # single run
npm run test:watch # watch modeindex.tsinitializes the RabbitMQ client and subscribes to the migration queue- Each message goes through
consumer.tswhich validates and ACKs early migration.tsruns in the background, callingstack-client.tsmethods to list/transfer filestracking.tskeeps the CouchDB tracking document in sync with progresscloudery-client.tsprovides tokens, refreshed automatically on 401