4runr-os 2.10.23 → 2.10.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/gateway/README.md +368 -368
- package/apps/gateway/docker-compose.local.yml +44 -44
- package/apps/gateway/package-lock.json +18 -18
- package/dist/boot-orchestrator.d.ts +1 -0
- package/dist/boot-orchestrator.d.ts.map +1 -1
- package/dist/boot-orchestrator.js +62 -77
- package/dist/boot-orchestrator.js.map +1 -1
- package/dist/watchdog.d.ts.map +1 -1
- package/dist/watchdog.js +77 -15
- package/dist/watchdog.js.map +1 -1
- package/package.json +2 -2
package/apps/gateway/README.md
CHANGED
|
@@ -1,368 +1,368 @@
|
|
|
1
|
-
# 4Runr Gateway
|
|
2
|
-
|
|
3
|
-
The 4Runr Gateway is a production-ready HTTP server for AI agent orchestration and execution management.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
### Local Development (with Docker)
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Prerequisites: Docker Desktop (Windows/macOS) or Docker Engine (Linux)
|
|
11
|
-
|
|
12
|
-
# 1. Install dependencies
|
|
13
|
-
npm install
|
|
14
|
-
|
|
15
|
-
# 2. Build Gateway
|
|
16
|
-
cd apps/gateway
|
|
17
|
-
npm run build
|
|
18
|
-
|
|
19
|
-
# 3. Start Gateway (auto-starts Docker containers)
|
|
20
|
-
npm run dev
|
|
21
|
-
# Or from workspace root:
|
|
22
|
-
npm run gateway:dev
|
|
23
|
-
|
|
24
|
-
# Gateway starts on http://localhost:3001
|
|
25
|
-
# Postgres on localhost:5432, Redis on localhost:6379
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Development without Docker (Memory Mode)
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
export GATEWAY_PERSISTENCE=memory
|
|
32
|
-
export AUTH_ENABLED=false
|
|
33
|
-
npm run dev
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Environment Variables
|
|
37
|
-
|
|
38
|
-
### Core Configuration
|
|
39
|
-
|
|
40
|
-
| Variable | Values | Default | Description |
|
|
41
|
-
|----------|--------|---------|-------------|
|
|
42
|
-
| `NODE_ENV` | `development`, `production` | `development` | Environment mode |
|
|
43
|
-
| `PORT` | `1-65535` | `3001` | HTTP server port |
|
|
44
|
-
| `HOST` | IP address | `127.0.0.1` | Server bind address |
|
|
45
|
-
| `LOG_LEVEL` | `error`, `warn`, `info`, `debug` | `info` | Logging verbosity |
|
|
46
|
-
|
|
47
|
-
### Persistence & Database
|
|
48
|
-
|
|
49
|
-
| Variable | Values | Default | Description |
|
|
50
|
-
|----------|--------|---------|-------------|
|
|
51
|
-
| `GATEWAY_PERSISTENCE` | `auto`, `memory`, `file`, `postgres` | `auto` | Persistence mode |
|
|
52
|
-
| `DATABASE_URL` | PostgreSQL connection string | `postgresql://4runr:4runr_dev_pass@localhost:5432/4runr_local` | Database connection |
|
|
53
|
-
| `REDIS_URL` | Redis connection string | `redis://localhost:6379` | Redis connection |
|
|
54
|
-
|
|
55
|
-
**Persistence Modes:**
|
|
56
|
-
- **`auto`** (recommended): Detects Docker and auto-starts Postgres+Redis
|
|
57
|
-
- **`memory`**: In-memory only, no persistence (fast, ephemeral)
|
|
58
|
-
- **`postgres`**: Explicit PostgreSQL mode (production)
|
|
59
|
-
- **`file`**: Reserved for future SQLite support
|
|
60
|
-
|
|
61
|
-
### Authentication & Security
|
|
62
|
-
|
|
63
|
-
| Variable | Values | Default | Description |
|
|
64
|
-
|----------|--------|---------|-------------|
|
|
65
|
-
| `AUTH_ENABLED` | `true`, `false` | `true` | Enable authentication |
|
|
66
|
-
| `AUTH_MODE` | `api_key`, `jwt`, `mixed` | `api_key` | Authentication method |
|
|
67
|
-
| `JWT_SECRET` | String | (required in production) | JWT signing secret |
|
|
68
|
-
| `ENCRYPTION_KEY` | String | (required in production) | Data encryption key |
|
|
69
|
-
| `API_KEYS` | Comma-separated | (none) | Valid API keys |
|
|
70
|
-
|
|
71
|
-
### Rate Limiting
|
|
72
|
-
|
|
73
|
-
| Variable | Values | Default | Description |
|
|
74
|
-
|----------|--------|---------|-------------|
|
|
75
|
-
| `RATE_LIMIT_ENABLED` | `true`, `false` | `true` | Enable rate limiting |
|
|
76
|
-
| `RATE_LIMIT_WINDOW_MS` | Number (ms) | `60000` | Rate limit window (1 min) |
|
|
77
|
-
| `RATE_LIMIT_MAX` | Number | `60` | Max requests per window |
|
|
78
|
-
|
|
79
|
-
### Features
|
|
80
|
-
|
|
81
|
-
| Variable | Values | Default | Description |
|
|
82
|
-
|----------|--------|---------|-------------|
|
|
83
|
-
| `DEVKIT_ENABLED` | `true`, `false` | `false` | Enable DevKit routes |
|
|
84
|
-
| `METRICS_ENABLED` | `true`, `false` | `true` | Enable Prometheus metrics |
|
|
85
|
-
| `METRICS_PORT` | `1-65535` | `9090` | Metrics endpoint port |
|
|
86
|
-
| `CACHE_ENABLED` | `true`, `false` | `false` | Enable response caching |
|
|
87
|
-
| `IDEMPOTENCY_ENABLED` | `true`, `false` | `false` | Enable idempotency |
|
|
88
|
-
|
|
89
|
-
### Sentinel (AI Safety)
|
|
90
|
-
|
|
91
|
-
| Variable | Values | Default | Description |
|
|
92
|
-
|----------|--------|---------|-------------|
|
|
93
|
-
| `SENTINEL_ENABLED` | `true`, `false` | `true` | Enable Sentinel checks |
|
|
94
|
-
| `SENTINEL_MODE` | `live`, `mock` | `live` | Sentinel mode |
|
|
95
|
-
| `SENTINEL_SHIELD_MODE` | `enforce`, `monitor`, `off` | `enforce` | Shield behavior |
|
|
96
|
-
| `SHIELD_TOKEN_CAP` | Number | (optional) | Max tokens per request |
|
|
97
|
-
| `RUN_MAX_TOKENS` | Number | (optional) | Max tokens per run |
|
|
98
|
-
|
|
99
|
-
### CORS & Security Headers
|
|
100
|
-
|
|
101
|
-
| Variable | Values | Default | Description |
|
|
102
|
-
|----------|--------|---------|-------------|
|
|
103
|
-
| `CORS_ENABLED` | `true`, `false` | `false` | Enable CORS |
|
|
104
|
-
| `CORS_ORIGIN` | String | `*` | Allowed origins |
|
|
105
|
-
| `ALLOW_LOCALHOST_ONLY` | `true`, `false` | `true` | Restrict to localhost |
|
|
106
|
-
|
|
107
|
-
## Docker Setup
|
|
108
|
-
|
|
109
|
-
### Auto-Managed (Recommended)
|
|
110
|
-
|
|
111
|
-
Gateway automatically manages Docker containers when `GATEWAY_PERSISTENCE=auto`:
|
|
112
|
-
|
|
113
|
-
**What happens:**
|
|
114
|
-
1. Gateway checks for Docker availability
|
|
115
|
-
2. Looks for existing `4runr-postgres` and `4runr-redis` containers
|
|
116
|
-
3. If not found, runs `docker-compose up -d`
|
|
117
|
-
4. Waits for health checks
|
|
118
|
-
5. Runs database migrations
|
|
119
|
-
6. Connects and starts
|
|
120
|
-
|
|
121
|
-
**Containers created:**
|
|
122
|
-
- `4runr-postgres`: PostgreSQL 15 Alpine (~25MB)
|
|
123
|
-
- `4runr-redis`: Redis 7 Alpine (~15MB)
|
|
124
|
-
|
|
125
|
-
**Data persistence:**
|
|
126
|
-
- `4runr-postgres-data`: Docker volume (survives Gateway restarts and npm updates)
|
|
127
|
-
- `4runr-redis-data`: Docker volume (survives Gateway restarts and npm updates)
|
|
128
|
-
|
|
129
|
-
### Manual Docker Management
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
# Start containers manually (from apps/gateway/)
|
|
133
|
-
docker-compose -f docker-compose.local.yml up -d
|
|
134
|
-
|
|
135
|
-
# Check status
|
|
136
|
-
docker ps --filter "name=4runr"
|
|
137
|
-
|
|
138
|
-
# Check health
|
|
139
|
-
docker inspect 4runr-postgres --format='{{.State.Health.Status}}'
|
|
140
|
-
|
|
141
|
-
# View logs
|
|
142
|
-
docker logs -f 4runr-postgres
|
|
143
|
-
docker logs -f 4runr-redis
|
|
144
|
-
|
|
145
|
-
# Stop containers (data persists)
|
|
146
|
-
docker-compose -f docker-compose.local.yml down
|
|
147
|
-
|
|
148
|
-
# Stop and remove data
|
|
149
|
-
docker-compose -f docker-compose.local.yml down -v
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Docker Compose Configuration
|
|
153
|
-
|
|
154
|
-
Location: `apps/gateway/docker-compose.local.yml`
|
|
155
|
-
|
|
156
|
-
```yaml
|
|
157
|
-
services:
|
|
158
|
-
postgres:
|
|
159
|
-
image: postgres:15-alpine
|
|
160
|
-
container_name: 4runr-postgres
|
|
161
|
-
environment:
|
|
162
|
-
POSTGRES_DB: 4runr_local
|
|
163
|
-
POSTGRES_USER: 4runr
|
|
164
|
-
POSTGRES_PASSWORD: ${DB_PASSWORD:-4runr_dev_pass}
|
|
165
|
-
ports:
|
|
166
|
-
- "5432:5432"
|
|
167
|
-
volumes:
|
|
168
|
-
- 4runr-postgres-data:/var/lib/postgresql/data
|
|
169
|
-
healthcheck:
|
|
170
|
-
test: ["CMD-SHELL", "pg_isready -U 4runr -d 4runr_local"]
|
|
171
|
-
interval: 5s
|
|
172
|
-
timeout: 5s
|
|
173
|
-
retries: 5
|
|
174
|
-
|
|
175
|
-
redis:
|
|
176
|
-
image: redis:7-alpine
|
|
177
|
-
container_name: 4runr-redis
|
|
178
|
-
ports:
|
|
179
|
-
- "6379:6379"
|
|
180
|
-
volumes:
|
|
181
|
-
- 4runr-redis-data:/data
|
|
182
|
-
command: redis-server --appendonly yes
|
|
183
|
-
healthcheck:
|
|
184
|
-
test: ["CMD", "redis-cli", "ping"]
|
|
185
|
-
interval: 5s
|
|
186
|
-
timeout: 3s
|
|
187
|
-
retries: 5
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Database Migrations
|
|
191
|
-
|
|
192
|
-
Migrations run automatically on Gateway startup when Docker mode is active.
|
|
193
|
-
|
|
194
|
-
**Manual migrations:**
|
|
195
|
-
```bash
|
|
196
|
-
# Generate Prisma client
|
|
197
|
-
cd apps/gateway
|
|
198
|
-
npx prisma generate
|
|
199
|
-
|
|
200
|
-
# Create new migration
|
|
201
|
-
npx prisma migrate dev --name migration_name
|
|
202
|
-
|
|
203
|
-
# Deploy migrations (production)
|
|
204
|
-
npx prisma migrate deploy
|
|
205
|
-
|
|
206
|
-
# Reset database (development only, deletes all data)
|
|
207
|
-
npx prisma migrate reset
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
**Schema location:** `prisma/schema.prisma`
|
|
211
|
-
|
|
212
|
-
## API Endpoints
|
|
213
|
-
|
|
214
|
-
### Health & Status
|
|
215
|
-
|
|
216
|
-
- `GET /health` - Health check (always available)
|
|
217
|
-
- `GET /ready` - Readiness check (checks dependencies)
|
|
218
|
-
- `GET /metrics` - Prometheus metrics (port 9090)
|
|
219
|
-
|
|
220
|
-
### Runs API
|
|
221
|
-
|
|
222
|
-
- `POST /api/runs` - Create a new run
|
|
223
|
-
- `POST /api/runs/:id/start` - Start a run
|
|
224
|
-
- `POST /api/runs/:id/cancel` - Cancel a running run
|
|
225
|
-
- `GET /api/runs/:id/status` - Get run status
|
|
226
|
-
- `GET /api/runs/:id/stream` - SSE stream for run events
|
|
227
|
-
|
|
228
|
-
### DevKit API (requires database)
|
|
229
|
-
|
|
230
|
-
- `GET /devkit/api/status` - System status
|
|
231
|
-
- `GET /devkit/api/health` - Detailed health checks
|
|
232
|
-
- `GET /devkit/api/config` - Non-sensitive configuration
|
|
233
|
-
- `GET /devkit/api/runs` - List recent runs
|
|
234
|
-
- `GET /devkit/api/runs/:id` - Get run details
|
|
235
|
-
- `GET /devkit/api/metrics/summary` - Parsed metrics summary
|
|
236
|
-
|
|
237
|
-
**Note:** DevKit routes are automatically disabled in memory mode.
|
|
238
|
-
|
|
239
|
-
## Troubleshooting
|
|
240
|
-
|
|
241
|
-
### "Docker not available"
|
|
242
|
-
|
|
243
|
-
**Symptom:**
|
|
244
|
-
```
|
|
245
|
-
[WARN] ⚠️ Docker not available. Running in memory-only mode.
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Solutions:**
|
|
249
|
-
1. Install Docker Desktop (Windows/macOS) or Docker Engine (Linux)
|
|
250
|
-
2. Start Docker: `docker info` should return server info
|
|
251
|
-
3. Check user permissions (Linux): `sudo usermod -aG docker $USER`
|
|
252
|
-
4. WSL2 (Windows): Enable in Docker Desktop settings
|
|
253
|
-
|
|
254
|
-
### "Port 5432 already allocated"
|
|
255
|
-
|
|
256
|
-
**Symptom:**
|
|
257
|
-
```
|
|
258
|
-
Error: Bind for 0.0.0.0:5432 failed: port is already allocated
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Solutions:**
|
|
262
|
-
1. Find conflicting container: `docker ps --filter "publish=5432"`
|
|
263
|
-
2. Stop it: `docker stop CONTAINER_NAME`
|
|
264
|
-
3. Or change 4Runr port in `docker-compose.local.yml`
|
|
265
|
-
|
|
266
|
-
### "Container did not become healthy"
|
|
267
|
-
|
|
268
|
-
**Symptom:**
|
|
269
|
-
```
|
|
270
|
-
[ERROR] Container 4runr-postgres did not become healthy within 60000ms
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Solutions:**
|
|
274
|
-
1. Pre-pull images: `docker-compose -f docker-compose.local.yml pull`
|
|
275
|
-
2. Start containers manually first: `docker-compose up -d`
|
|
276
|
-
3. Wait for health: `docker ps` shows "(healthy)" status
|
|
277
|
-
|
|
278
|
-
### More Help
|
|
279
|
-
|
|
280
|
-
See [`docs/TROUBLESHOOTING.md`](../../docs/TROUBLESHOOTING.md) for comprehensive troubleshooting guide.
|
|
281
|
-
|
|
282
|
-
## Development Workflow
|
|
283
|
-
|
|
284
|
-
### Building
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
# Build Gateway only
|
|
288
|
-
cd apps/gateway
|
|
289
|
-
npm run build
|
|
290
|
-
|
|
291
|
-
# Build all packages
|
|
292
|
-
cd ../..
|
|
293
|
-
npm run build
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
### Running
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
# Development mode (auto-reload)
|
|
300
|
-
npm run dev
|
|
301
|
-
|
|
302
|
-
# Production mode
|
|
303
|
-
NODE_ENV=production npm start
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Testing
|
|
307
|
-
|
|
308
|
-
```bash
|
|
309
|
-
# Run tests
|
|
310
|
-
npm test
|
|
311
|
-
|
|
312
|
-
# Run with coverage
|
|
313
|
-
npm run test:coverage
|
|
314
|
-
|
|
315
|
-
# Run specific test
|
|
316
|
-
npm test -- --grep "idempotency"
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Linting
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
# Lint
|
|
323
|
-
npm run lint
|
|
324
|
-
|
|
325
|
-
# Lint and fix
|
|
326
|
-
npm run lint:fix
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## Production Deployment
|
|
330
|
-
|
|
331
|
-
See [`docs/GATEWAY-PRODUCTION-READINESS-PLAN.md`](../../docs/GATEWAY-PRODUCTION-READINESS-PLAN.md) for production deployment guide.
|
|
332
|
-
|
|
333
|
-
**Key production requirements:**
|
|
334
|
-
- Set `NODE_ENV=production`
|
|
335
|
-
- Provide `JWT_SECRET` and `ENCRYPTION_KEY`
|
|
336
|
-
- Use external PostgreSQL and Redis
|
|
337
|
-
- Enable TLS/HTTPS
|
|
338
|
-
- Configure monitoring and observability
|
|
339
|
-
- Set up proper rate limiting
|
|
340
|
-
- Review security checklist
|
|
341
|
-
|
|
342
|
-
## Project Structure
|
|
343
|
-
|
|
344
|
-
```
|
|
345
|
-
apps/gateway/
|
|
346
|
-
├── src/
|
|
347
|
-
│ ├── index.ts # Entry point
|
|
348
|
-
│ ├── db/
|
|
349
|
-
│ │ ├── init.ts # Database initialization
|
|
350
|
-
│ │ ├── docker-manager.ts # Docker container management
|
|
351
|
-
│ │ └── memory-db.ts # In-memory fallback
|
|
352
|
-
│ ├── routes/ # API route handlers
|
|
353
|
-
│ ├── middleware/ # Fastify middleware
|
|
354
|
-
│ ├── devkit/ # DevKit routes
|
|
355
|
-
│ └── ai-providers/ # AI provider integrations
|
|
356
|
-
├── prisma/
|
|
357
|
-
│ └── schema.prisma # Database schema
|
|
358
|
-
├── docker-compose.local.yml # Local Docker setup
|
|
359
|
-
└── package.json
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
## Additional Documentation
|
|
363
|
-
|
|
364
|
-
- **Implementation Plan:** [`docs/4RUNR-DB-IMPLEMENTATION-PLAN.md`](../../docs/4RUNR-DB-IMPLEMENTATION-PLAN.md)
|
|
365
|
-
- **Test Results:** [`docs/PHASE-4-TEST-RESULTS.md`](../../docs/PHASE-4-TEST-RESULTS.md)
|
|
366
|
-
- **Troubleshooting:** [`docs/TROUBLESHOOTING.md`](../../docs/TROUBLESHOOTING.md)
|
|
367
|
-
- **Decisions:** [`docs/decisions.md`](../../docs/decisions.md)
|
|
368
|
-
- **Status:** [`docs/status.md`](../../docs/status.md)
|
|
1
|
+
# 4Runr Gateway
|
|
2
|
+
|
|
3
|
+
The 4Runr Gateway is a production-ready HTTP server for AI agent orchestration and execution management.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Local Development (with Docker)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Prerequisites: Docker Desktop (Windows/macOS) or Docker Engine (Linux)
|
|
11
|
+
|
|
12
|
+
# 1. Install dependencies
|
|
13
|
+
npm install
|
|
14
|
+
|
|
15
|
+
# 2. Build Gateway
|
|
16
|
+
cd apps/gateway
|
|
17
|
+
npm run build
|
|
18
|
+
|
|
19
|
+
# 3. Start Gateway (auto-starts Docker containers)
|
|
20
|
+
npm run dev
|
|
21
|
+
# Or from workspace root:
|
|
22
|
+
npm run gateway:dev
|
|
23
|
+
|
|
24
|
+
# Gateway starts on http://localhost:3001
|
|
25
|
+
# Postgres on localhost:5432, Redis on localhost:6379
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Development without Docker (Memory Mode)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
export GATEWAY_PERSISTENCE=memory
|
|
32
|
+
export AUTH_ENABLED=false
|
|
33
|
+
npm run dev
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Environment Variables
|
|
37
|
+
|
|
38
|
+
### Core Configuration
|
|
39
|
+
|
|
40
|
+
| Variable | Values | Default | Description |
|
|
41
|
+
|----------|--------|---------|-------------|
|
|
42
|
+
| `NODE_ENV` | `development`, `production` | `development` | Environment mode |
|
|
43
|
+
| `PORT` | `1-65535` | `3001` | HTTP server port |
|
|
44
|
+
| `HOST` | IP address | `127.0.0.1` | Server bind address |
|
|
45
|
+
| `LOG_LEVEL` | `error`, `warn`, `info`, `debug` | `info` | Logging verbosity |
|
|
46
|
+
|
|
47
|
+
### Persistence & Database
|
|
48
|
+
|
|
49
|
+
| Variable | Values | Default | Description |
|
|
50
|
+
|----------|--------|---------|-------------|
|
|
51
|
+
| `GATEWAY_PERSISTENCE` | `auto`, `memory`, `file`, `postgres` | `auto` | Persistence mode |
|
|
52
|
+
| `DATABASE_URL` | PostgreSQL connection string | `postgresql://4runr:4runr_dev_pass@localhost:5432/4runr_local` | Database connection |
|
|
53
|
+
| `REDIS_URL` | Redis connection string | `redis://localhost:6379` | Redis connection |
|
|
54
|
+
|
|
55
|
+
**Persistence Modes:**
|
|
56
|
+
- **`auto`** (recommended): Detects Docker and auto-starts Postgres+Redis
|
|
57
|
+
- **`memory`**: In-memory only, no persistence (fast, ephemeral)
|
|
58
|
+
- **`postgres`**: Explicit PostgreSQL mode (production)
|
|
59
|
+
- **`file`**: Reserved for future SQLite support
|
|
60
|
+
|
|
61
|
+
### Authentication & Security
|
|
62
|
+
|
|
63
|
+
| Variable | Values | Default | Description |
|
|
64
|
+
|----------|--------|---------|-------------|
|
|
65
|
+
| `AUTH_ENABLED` | `true`, `false` | `true` | Enable authentication |
|
|
66
|
+
| `AUTH_MODE` | `api_key`, `jwt`, `mixed` | `api_key` | Authentication method |
|
|
67
|
+
| `JWT_SECRET` | String | (required in production) | JWT signing secret |
|
|
68
|
+
| `ENCRYPTION_KEY` | String | (required in production) | Data encryption key |
|
|
69
|
+
| `API_KEYS` | Comma-separated | (none) | Valid API keys |
|
|
70
|
+
|
|
71
|
+
### Rate Limiting
|
|
72
|
+
|
|
73
|
+
| Variable | Values | Default | Description |
|
|
74
|
+
|----------|--------|---------|-------------|
|
|
75
|
+
| `RATE_LIMIT_ENABLED` | `true`, `false` | `true` | Enable rate limiting |
|
|
76
|
+
| `RATE_LIMIT_WINDOW_MS` | Number (ms) | `60000` | Rate limit window (1 min) |
|
|
77
|
+
| `RATE_LIMIT_MAX` | Number | `60` | Max requests per window |
|
|
78
|
+
|
|
79
|
+
### Features
|
|
80
|
+
|
|
81
|
+
| Variable | Values | Default | Description |
|
|
82
|
+
|----------|--------|---------|-------------|
|
|
83
|
+
| `DEVKIT_ENABLED` | `true`, `false` | `false` | Enable DevKit routes |
|
|
84
|
+
| `METRICS_ENABLED` | `true`, `false` | `true` | Enable Prometheus metrics |
|
|
85
|
+
| `METRICS_PORT` | `1-65535` | `9090` | Metrics endpoint port |
|
|
86
|
+
| `CACHE_ENABLED` | `true`, `false` | `false` | Enable response caching |
|
|
87
|
+
| `IDEMPOTENCY_ENABLED` | `true`, `false` | `false` | Enable idempotency |
|
|
88
|
+
|
|
89
|
+
### Sentinel (AI Safety)
|
|
90
|
+
|
|
91
|
+
| Variable | Values | Default | Description |
|
|
92
|
+
|----------|--------|---------|-------------|
|
|
93
|
+
| `SENTINEL_ENABLED` | `true`, `false` | `true` | Enable Sentinel checks |
|
|
94
|
+
| `SENTINEL_MODE` | `live`, `mock` | `live` | Sentinel mode |
|
|
95
|
+
| `SENTINEL_SHIELD_MODE` | `enforce`, `monitor`, `off` | `enforce` | Shield behavior |
|
|
96
|
+
| `SHIELD_TOKEN_CAP` | Number | (optional) | Max tokens per request |
|
|
97
|
+
| `RUN_MAX_TOKENS` | Number | (optional) | Max tokens per run |
|
|
98
|
+
|
|
99
|
+
### CORS & Security Headers
|
|
100
|
+
|
|
101
|
+
| Variable | Values | Default | Description |
|
|
102
|
+
|----------|--------|---------|-------------|
|
|
103
|
+
| `CORS_ENABLED` | `true`, `false` | `false` | Enable CORS |
|
|
104
|
+
| `CORS_ORIGIN` | String | `*` | Allowed origins |
|
|
105
|
+
| `ALLOW_LOCALHOST_ONLY` | `true`, `false` | `true` | Restrict to localhost |
|
|
106
|
+
|
|
107
|
+
## Docker Setup
|
|
108
|
+
|
|
109
|
+
### Auto-Managed (Recommended)
|
|
110
|
+
|
|
111
|
+
Gateway automatically manages Docker containers when `GATEWAY_PERSISTENCE=auto`:
|
|
112
|
+
|
|
113
|
+
**What happens:**
|
|
114
|
+
1. Gateway checks for Docker availability
|
|
115
|
+
2. Looks for existing `4runr-postgres` and `4runr-redis` containers
|
|
116
|
+
3. If not found, runs `docker-compose up -d`
|
|
117
|
+
4. Waits for health checks
|
|
118
|
+
5. Runs database migrations
|
|
119
|
+
6. Connects and starts
|
|
120
|
+
|
|
121
|
+
**Containers created:**
|
|
122
|
+
- `4runr-postgres`: PostgreSQL 15 Alpine (~25MB)
|
|
123
|
+
- `4runr-redis`: Redis 7 Alpine (~15MB)
|
|
124
|
+
|
|
125
|
+
**Data persistence:**
|
|
126
|
+
- `4runr-postgres-data`: Docker volume (survives Gateway restarts and npm updates)
|
|
127
|
+
- `4runr-redis-data`: Docker volume (survives Gateway restarts and npm updates)
|
|
128
|
+
|
|
129
|
+
### Manual Docker Management
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Start containers manually (from apps/gateway/)
|
|
133
|
+
docker-compose -f docker-compose.local.yml up -d
|
|
134
|
+
|
|
135
|
+
# Check status
|
|
136
|
+
docker ps --filter "name=4runr"
|
|
137
|
+
|
|
138
|
+
# Check health
|
|
139
|
+
docker inspect 4runr-postgres --format='{{.State.Health.Status}}'
|
|
140
|
+
|
|
141
|
+
# View logs
|
|
142
|
+
docker logs -f 4runr-postgres
|
|
143
|
+
docker logs -f 4runr-redis
|
|
144
|
+
|
|
145
|
+
# Stop containers (data persists)
|
|
146
|
+
docker-compose -f docker-compose.local.yml down
|
|
147
|
+
|
|
148
|
+
# Stop and remove data
|
|
149
|
+
docker-compose -f docker-compose.local.yml down -v
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Docker Compose Configuration
|
|
153
|
+
|
|
154
|
+
Location: `apps/gateway/docker-compose.local.yml`
|
|
155
|
+
|
|
156
|
+
```yaml
|
|
157
|
+
services:
|
|
158
|
+
postgres:
|
|
159
|
+
image: postgres:15-alpine
|
|
160
|
+
container_name: 4runr-postgres
|
|
161
|
+
environment:
|
|
162
|
+
POSTGRES_DB: 4runr_local
|
|
163
|
+
POSTGRES_USER: 4runr
|
|
164
|
+
POSTGRES_PASSWORD: ${DB_PASSWORD:-4runr_dev_pass}
|
|
165
|
+
ports:
|
|
166
|
+
- "5432:5432"
|
|
167
|
+
volumes:
|
|
168
|
+
- 4runr-postgres-data:/var/lib/postgresql/data
|
|
169
|
+
healthcheck:
|
|
170
|
+
test: ["CMD-SHELL", "pg_isready -U 4runr -d 4runr_local"]
|
|
171
|
+
interval: 5s
|
|
172
|
+
timeout: 5s
|
|
173
|
+
retries: 5
|
|
174
|
+
|
|
175
|
+
redis:
|
|
176
|
+
image: redis:7-alpine
|
|
177
|
+
container_name: 4runr-redis
|
|
178
|
+
ports:
|
|
179
|
+
- "6379:6379"
|
|
180
|
+
volumes:
|
|
181
|
+
- 4runr-redis-data:/data
|
|
182
|
+
command: redis-server --appendonly yes
|
|
183
|
+
healthcheck:
|
|
184
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
185
|
+
interval: 5s
|
|
186
|
+
timeout: 3s
|
|
187
|
+
retries: 5
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Database Migrations
|
|
191
|
+
|
|
192
|
+
Migrations run automatically on Gateway startup when Docker mode is active.
|
|
193
|
+
|
|
194
|
+
**Manual migrations:**
|
|
195
|
+
```bash
|
|
196
|
+
# Generate Prisma client
|
|
197
|
+
cd apps/gateway
|
|
198
|
+
npx prisma generate
|
|
199
|
+
|
|
200
|
+
# Create new migration
|
|
201
|
+
npx prisma migrate dev --name migration_name
|
|
202
|
+
|
|
203
|
+
# Deploy migrations (production)
|
|
204
|
+
npx prisma migrate deploy
|
|
205
|
+
|
|
206
|
+
# Reset database (development only, deletes all data)
|
|
207
|
+
npx prisma migrate reset
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Schema location:** `prisma/schema.prisma`
|
|
211
|
+
|
|
212
|
+
## API Endpoints
|
|
213
|
+
|
|
214
|
+
### Health & Status
|
|
215
|
+
|
|
216
|
+
- `GET /health` - Health check (always available)
|
|
217
|
+
- `GET /ready` - Readiness check (checks dependencies)
|
|
218
|
+
- `GET /metrics` - Prometheus metrics (port 9090)
|
|
219
|
+
|
|
220
|
+
### Runs API
|
|
221
|
+
|
|
222
|
+
- `POST /api/runs` - Create a new run
|
|
223
|
+
- `POST /api/runs/:id/start` - Start a run
|
|
224
|
+
- `POST /api/runs/:id/cancel` - Cancel a running run
|
|
225
|
+
- `GET /api/runs/:id/status` - Get run status
|
|
226
|
+
- `GET /api/runs/:id/stream` - SSE stream for run events
|
|
227
|
+
|
|
228
|
+
### DevKit API (requires database)
|
|
229
|
+
|
|
230
|
+
- `GET /devkit/api/status` - System status
|
|
231
|
+
- `GET /devkit/api/health` - Detailed health checks
|
|
232
|
+
- `GET /devkit/api/config` - Non-sensitive configuration
|
|
233
|
+
- `GET /devkit/api/runs` - List recent runs
|
|
234
|
+
- `GET /devkit/api/runs/:id` - Get run details
|
|
235
|
+
- `GET /devkit/api/metrics/summary` - Parsed metrics summary
|
|
236
|
+
|
|
237
|
+
**Note:** DevKit routes are automatically disabled in memory mode.
|
|
238
|
+
|
|
239
|
+
## Troubleshooting
|
|
240
|
+
|
|
241
|
+
### "Docker not available"
|
|
242
|
+
|
|
243
|
+
**Symptom:**
|
|
244
|
+
```
|
|
245
|
+
[WARN] ⚠️ Docker not available. Running in memory-only mode.
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Solutions:**
|
|
249
|
+
1. Install Docker Desktop (Windows/macOS) or Docker Engine (Linux)
|
|
250
|
+
2. Start Docker: `docker info` should return server info
|
|
251
|
+
3. Check user permissions (Linux): `sudo usermod -aG docker $USER`
|
|
252
|
+
4. WSL2 (Windows): Enable in Docker Desktop settings
|
|
253
|
+
|
|
254
|
+
### "Port 5432 already allocated"
|
|
255
|
+
|
|
256
|
+
**Symptom:**
|
|
257
|
+
```
|
|
258
|
+
Error: Bind for 0.0.0.0:5432 failed: port is already allocated
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Solutions:**
|
|
262
|
+
1. Find conflicting container: `docker ps --filter "publish=5432"`
|
|
263
|
+
2. Stop it: `docker stop CONTAINER_NAME`
|
|
264
|
+
3. Or change 4Runr port in `docker-compose.local.yml`
|
|
265
|
+
|
|
266
|
+
### "Container did not become healthy"
|
|
267
|
+
|
|
268
|
+
**Symptom:**
|
|
269
|
+
```
|
|
270
|
+
[ERROR] Container 4runr-postgres did not become healthy within 60000ms
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Solutions:**
|
|
274
|
+
1. Pre-pull images: `docker-compose -f docker-compose.local.yml pull`
|
|
275
|
+
2. Start containers manually first: `docker-compose up -d`
|
|
276
|
+
3. Wait for health: `docker ps` shows "(healthy)" status
|
|
277
|
+
|
|
278
|
+
### More Help
|
|
279
|
+
|
|
280
|
+
See [`docs/TROUBLESHOOTING.md`](../../docs/TROUBLESHOOTING.md) for comprehensive troubleshooting guide.
|
|
281
|
+
|
|
282
|
+
## Development Workflow
|
|
283
|
+
|
|
284
|
+
### Building
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Build Gateway only
|
|
288
|
+
cd apps/gateway
|
|
289
|
+
npm run build
|
|
290
|
+
|
|
291
|
+
# Build all packages
|
|
292
|
+
cd ../..
|
|
293
|
+
npm run build
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Running
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Development mode (auto-reload)
|
|
300
|
+
npm run dev
|
|
301
|
+
|
|
302
|
+
# Production mode
|
|
303
|
+
NODE_ENV=production npm start
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Testing
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Run tests
|
|
310
|
+
npm test
|
|
311
|
+
|
|
312
|
+
# Run with coverage
|
|
313
|
+
npm run test:coverage
|
|
314
|
+
|
|
315
|
+
# Run specific test
|
|
316
|
+
npm test -- --grep "idempotency"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Linting
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Lint
|
|
323
|
+
npm run lint
|
|
324
|
+
|
|
325
|
+
# Lint and fix
|
|
326
|
+
npm run lint:fix
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Production Deployment
|
|
330
|
+
|
|
331
|
+
See [`docs/GATEWAY-PRODUCTION-READINESS-PLAN.md`](../../docs/GATEWAY-PRODUCTION-READINESS-PLAN.md) for production deployment guide.
|
|
332
|
+
|
|
333
|
+
**Key production requirements:**
|
|
334
|
+
- Set `NODE_ENV=production`
|
|
335
|
+
- Provide `JWT_SECRET` and `ENCRYPTION_KEY`
|
|
336
|
+
- Use external PostgreSQL and Redis
|
|
337
|
+
- Enable TLS/HTTPS
|
|
338
|
+
- Configure monitoring and observability
|
|
339
|
+
- Set up proper rate limiting
|
|
340
|
+
- Review security checklist
|
|
341
|
+
|
|
342
|
+
## Project Structure
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
apps/gateway/
|
|
346
|
+
├── src/
|
|
347
|
+
│ ├── index.ts # Entry point
|
|
348
|
+
│ ├── db/
|
|
349
|
+
│ │ ├── init.ts # Database initialization
|
|
350
|
+
│ │ ├── docker-manager.ts # Docker container management
|
|
351
|
+
│ │ └── memory-db.ts # In-memory fallback
|
|
352
|
+
│ ├── routes/ # API route handlers
|
|
353
|
+
│ ├── middleware/ # Fastify middleware
|
|
354
|
+
│ ├── devkit/ # DevKit routes
|
|
355
|
+
│ └── ai-providers/ # AI provider integrations
|
|
356
|
+
├── prisma/
|
|
357
|
+
│ └── schema.prisma # Database schema
|
|
358
|
+
├── docker-compose.local.yml # Local Docker setup
|
|
359
|
+
└── package.json
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Additional Documentation
|
|
363
|
+
|
|
364
|
+
- **Implementation Plan:** [`docs/4RUNR-DB-IMPLEMENTATION-PLAN.md`](../../docs/4RUNR-DB-IMPLEMENTATION-PLAN.md)
|
|
365
|
+
- **Test Results:** [`docs/PHASE-4-TEST-RESULTS.md`](../../docs/PHASE-4-TEST-RESULTS.md)
|
|
366
|
+
- **Troubleshooting:** [`docs/TROUBLESHOOTING.md`](../../docs/TROUBLESHOOTING.md)
|
|
367
|
+
- **Decisions:** [`docs/decisions.md`](../../docs/decisions.md)
|
|
368
|
+
- **Status:** [`docs/status.md`](../../docs/status.md)
|