|
| 1 | +--- |
| 2 | +name: impact-analyzer-agent |
| 3 | +description: Agent for analyzing projects for containerization/deployment requirements. Scans codebases to identify environment variables, network topology, auth configurations, and service dependencies that affect containerization. |
| 4 | +skills: |
| 5 | + - blueprint-skill-creator |
| 6 | + - containerize-apps |
| 7 | +--- |
| 8 | +# Impact Analyzer Agent |
| 9 | + |
| 10 | +## Purpose |
| 11 | + |
| 12 | +Analyzes projects for containerization/deployment requirements. Scans codebases to identify environment variables, network topology, auth configurations, and service dependencies that affect containerization. |
| 13 | + |
| 14 | +## When to Use |
| 15 | + |
| 16 | +Invoke this agent before: |
| 17 | +- Creating Dockerfiles |
| 18 | +- Writing docker-compose configurations |
| 19 | +- Preparing Kubernetes deployments |
| 20 | +- Any containerization work |
| 21 | + |
| 22 | +## Capabilities |
| 23 | + |
| 24 | +This agent performs comprehensive project scanning: |
| 25 | + |
| 26 | +### 1. Environment Variable Analysis |
| 27 | +- Find all `process.env.*` usage (TypeScript/JavaScript) |
| 28 | +- Find all `os.environ` / `os.getenv` usage (Python) |
| 29 | +- Locate `.env` files and parse variables |
| 30 | +- Classify as build-time vs runtime |
| 31 | +- Identify sensitive values (secrets, API keys) |
| 32 | + |
| 33 | +### 2. Network Topology Mapping |
| 34 | +- Find localhost/127.0.0.1 references |
| 35 | +- Identify port bindings |
| 36 | +- Map service-to-service communication |
| 37 | +- Detect external service connections (databases, APIs) |
| 38 | + |
| 39 | +### 3. Auth/CORS Configuration Analysis |
| 40 | +- Locate Better Auth configurations (trustedOrigins) |
| 41 | +- Find CORS settings in backends |
| 42 | +- Identify callback URLs |
| 43 | +- Check for origin validation code |
| 44 | + |
| 45 | +### 4. Service Dependency Analysis |
| 46 | +- Map which services depend on others |
| 47 | +- Identify startup order requirements |
| 48 | +- Find health check endpoints |
| 49 | +- Detect shared resources (databases, caches) |
| 50 | + |
| 51 | +## Instructions |
| 52 | + |
| 53 | +### Scanning Process |
| 54 | + |
| 55 | +1. **Environment Variables** |
| 56 | +```bash |
| 57 | +# TypeScript/JavaScript |
| 58 | +grep -r "process\.env\." --include="*.ts" --include="*.tsx" --include="*.js" |
| 59 | + |
| 60 | +# Python |
| 61 | +grep -r "os\.environ\|os\.getenv\|environ\.get" --include="*.py" |
| 62 | + |
| 63 | +# .env files |
| 64 | +find . -name ".env*" -type f |
| 65 | +``` |
| 66 | + |
| 67 | +2. **Localhost References** |
| 68 | +```bash |
| 69 | +grep -r "localhost\|127\.0\.0\.1" --include="*.ts" --include="*.py" --include="*.json" --include="*.yaml" |
| 70 | +``` |
| 71 | + |
| 72 | +3. **Auth Configurations** |
| 73 | +```bash |
| 74 | +# Better Auth |
| 75 | +grep -r "trustedOrigins\|baseURL\|BETTER_AUTH" --include="*.ts" |
| 76 | + |
| 77 | +# CORS |
| 78 | +grep -r "cors\|CORSMiddleware\|allowedOrigins" --include="*.ts" --include="*.py" |
| 79 | +``` |
| 80 | + |
| 81 | +4. **Port Bindings** |
| 82 | +```bash |
| 83 | +grep -r ":\d{4}" --include="*.ts" --include="*.py" --include="*.yaml" |
| 84 | +grep -r "PORT\|port" --include="*.ts" --include="*.py" |
| 85 | +``` |
| 86 | + |
| 87 | +### Output Format |
| 88 | + |
| 89 | +Return a structured report: |
| 90 | + |
| 91 | +```markdown |
| 92 | +# Containerization Impact Analysis |
| 93 | + |
| 94 | +## Project: [project-name] |
| 95 | +## Analyzed: [timestamp] |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## 1. Environment Variables |
| 100 | + |
| 101 | +### Build-Time Variables |
| 102 | +| Variable | Location | Current Value | Docker Value | |
| 103 | +|----------|----------|---------------|--------------| |
| 104 | +| NEXT_PUBLIC_API_URL | web-dashboard/.env | http://localhost:8000 | http://api:8000 | |
| 105 | + |
| 106 | +### Runtime Variables |
| 107 | +| Variable | Location | Sensitive | Notes | |
| 108 | +|----------|----------|-----------|-------| |
| 109 | +| DATABASE_URL | packages/api/.env | Yes | External Neon - keep as-is | |
| 110 | +| BETTER_AUTH_SECRET | sso-platform/.env | Yes | Must be shared across services | |
| 111 | + |
| 112 | +--- |
| 113 | + |
| 114 | +## 2. Network Topology |
| 115 | + |
| 116 | +### Services Identified |
| 117 | +| Service | Port | Directory | Health Endpoint | |
| 118 | +|---------|------|-----------|-----------------| |
| 119 | +| web | 3000 | web-dashboard/ | / | |
| 120 | +| api | 8000 | packages/api/ | /health | |
| 121 | +| mcp | 8001 | packages/mcp-server/ | /health | |
| 122 | + |
| 123 | +### localhost References to Update |
| 124 | +| File | Line | Current | Docker Service Name | |
| 125 | +|------|------|---------|---------------------| |
| 126 | +| web-dashboard/.env | 3 | http://localhost:8000 | http://api:8000 | |
| 127 | +| packages/api/main.py | 45 | localhost:3000 | web:3000 | |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## 3. Auth/CORS Impact |
| 132 | + |
| 133 | +### Better Auth Configuration |
| 134 | +**File:** sso-platform/src/lib/auth.ts |
| 135 | + |
| 136 | +**Current trustedOrigins:** |
| 137 | +- http://localhost:3000 |
| 138 | +- http://localhost:8000 |
| 139 | + |
| 140 | +**Required additions for Docker:** |
| 141 | +- http://web:3000 |
| 142 | +- http://api:8000 |
| 143 | + |
| 144 | +### Backend CORS |
| 145 | +**File:** packages/api/src/taskflow_api/main.py |
| 146 | + |
| 147 | +**Current origins:** |
| 148 | +- http://localhost:3000 |
| 149 | + |
| 150 | +**Required additions:** |
| 151 | +- http://web:3000 (Docker) |
| 152 | +- ${FRONTEND_URL} (dynamic) |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## 4. Service Dependencies |
| 157 | + |
| 158 | +### Dependency Graph |
| 159 | +``` |
| 160 | +web (frontend) |
| 161 | +├── depends_on: api (health check required) |
| 162 | +└── depends_on: sso (if separate) |
| 163 | + |
| 164 | +api (backend) |
| 165 | +├── depends_on: database (external Neon) |
| 166 | +└── optional: redis, kafka |
| 167 | + |
| 168 | +mcp-server |
| 169 | +└── depends_on: api |
| 170 | +``` |
| 171 | +
|
| 172 | +### Startup Order |
| 173 | +1. External services (Neon - already running) |
| 174 | +2. api (backend) |
| 175 | +3. sso (if separate) |
| 176 | +4. mcp-server |
| 177 | +5. web (frontend) |
| 178 | +
|
| 179 | +--- |
| 180 | +
|
| 181 | +## 5. Required Code Changes |
| 182 | +
|
| 183 | +### High Priority (Must fix before containerization) |
| 184 | +1. [ ] Add Docker origins to trustedOrigins |
| 185 | +2. [ ] Add Docker origins to CORS config |
| 186 | +3. [ ] Ensure health endpoints exist |
| 187 | +
|
| 188 | +### Medium Priority (Recommended) |
| 189 | +1. [ ] Externalize hardcoded URLs to env vars |
| 190 | +2. [ ] Add CORS_ORIGINS env var support |
| 191 | +3. [ ] Implement graceful shutdown |
| 192 | +
|
| 193 | +--- |
| 194 | +
|
| 195 | +## 6. Recommended docker-compose Services |
| 196 | +
|
| 197 | +```yaml |
| 198 | +services: |
| 199 | + web: |
| 200 | + build: ./web-dashboard |
| 201 | + ports: ["3000:3000"] |
| 202 | + depends_on: |
| 203 | + api: { condition: service_healthy } |
| 204 | +
|
| 205 | + api: |
| 206 | + build: ./packages/api |
| 207 | + ports: ["8000:8000"] |
| 208 | + environment: |
| 209 | + - DATABASE_URL=${DATABASE_URL} |
| 210 | + - FRONTEND_URL=http://web:3000 |
| 211 | +
|
| 212 | + mcp: |
| 213 | + build: ./packages/mcp-server |
| 214 | + ports: ["8001:8001"] |
| 215 | + depends_on: |
| 216 | + api: { condition: service_healthy } |
| 217 | +``` |
| 218 | +``` |
| 219 | +
|
| 220 | +## Tools Available |
| 221 | +
|
| 222 | +This agent has access to: |
| 223 | +- `Glob` - Find files by pattern |
| 224 | +- `Grep` - Search file contents |
| 225 | +- `Read` - Read file contents |
| 226 | +- `Bash` - Execute commands (for complex searches) |
| 227 | +
|
| 228 | +## Success Criteria |
| 229 | +
|
| 230 | +A successful analysis: |
| 231 | +- [ ] All env vars identified and classified |
| 232 | +- [ ] All localhost refs mapped to service names |
| 233 | +- [ ] Auth/CORS configs located with required changes |
| 234 | +- [ ] Service dependencies documented |
| 235 | +- [ ] Startup order determined |
| 236 | +- [ ] Actionable change list provided |
| 237 | +
|
| 238 | +--- |
| 239 | +
|
| 240 | +## Battle-Tested Learnings |
| 241 | +
|
| 242 | +### 1. Browser vs Server URLs - Use Separate Variable Names |
| 243 | +Browser runs on host machine, server-side runs in container. Use DIFFERENT variable names: |
| 244 | +```yaml |
| 245 | +build: |
| 246 | + args: |
| 247 | + - NEXT_PUBLIC_API_URL=http://localhost:8000 # Browser only |
| 248 | +environment: |
| 249 | + - SERVER_API_URL=http://api:8000 # Server only |
| 250 | +``` |
| 251 | +Code change: `const API_URL = process.env.SERVER_API_URL || process.env.NEXT_PUBLIC_API_URL;` |
| 252 | + |
| 253 | +### 2. Healthcheck IPv6 Issue |
| 254 | +Always use `127.0.0.1` not `localhost` in healthchecks: |
| 255 | +```yaml |
| 256 | +healthcheck: |
| 257 | + test: ["CMD", "wget", "--spider", "http://127.0.0.1:3000/"] |
| 258 | +``` |
| 259 | +`localhost` can resolve to IPv6 `[::1]` which fails if server only listens on IPv4. |
| 260 | + |
| 261 | +### 3. Database Driver Detection |
| 262 | +For code that switches between Neon (serverless) and local postgres, check for `sslmode=disable`: |
| 263 | +```yaml |
| 264 | +DATABASE_URL=postgresql://user:pass@postgres:5432/db?sslmode=disable |
| 265 | +``` |
| 266 | +Code pattern: `url.includes("sslmode=disable")` → use standard postgres driver |
| 267 | + |
| 268 | +### 4. Package.json Dependencies |
| 269 | +Check for: |
| 270 | +- `playwright` should be in `devDependencies` (300MB+ browsers) |
| 271 | +- `postgres` driver should be in `dependencies` (needed at runtime) |
| 272 | + |
| 273 | +### 5. pgAdmin Configuration |
| 274 | +Use valid email domain: `admin@example.com` not `admin@taskflow.local` |
| 275 | + |
| 276 | +### 6. Migration Strategy |
| 277 | +Run migrations from host machine connecting to Docker postgres: |
| 278 | +```bash |
| 279 | +DATABASE_URL="postgresql://postgres:postgres@localhost:5432/db" pnpm db:push |
| 280 | +``` |
| 281 | +This keeps images slim (no Drizzle CLI in production image). |
| 282 | + |
| 283 | +### 7. MCP Server Transport Security (421 Misdirected Request) |
| 284 | +**Check for:** FastMCP usage in MCP servers |
| 285 | +**Problem:** MCP SDK validates Host header, rejects Docker service names |
| 286 | +**Error:** `421 Misdirected Request - Invalid Host header` |
| 287 | +**Solution:** Configure `TransportSecuritySettings` with `allowed_hosts` including Docker container names: |
| 288 | +```python |
| 289 | +transport_security = TransportSecuritySettings( |
| 290 | + allowed_hosts=["127.0.0.1:*", "localhost:*", "mcp-server:*"], |
| 291 | +) |
| 292 | +``` |
| 293 | + |
| 294 | +### 8. MCP Server Health Check (406 Not Acceptable) |
| 295 | +**Check for:** MCP servers using `/mcp` endpoint |
| 296 | +**Problem:** MCP `/mcp` endpoint returns 406 on GET requests |
| 297 | +**Solution:** Add `/health` endpoint via ASGI middleware (NOT Starlette Mount - breaks lifespan) |
| 298 | + |
| 299 | +### 9. Database Migration Order (Drizzle vs SQLModel) |
| 300 | +**Check for:** Multiple ORMs sharing one database (e.g., Drizzle + SQLModel) |
| 301 | +**Problem:** If API creates tables, then Drizzle `db:push` runs, Drizzle DROPS API tables |
| 302 | +**Solution:** Staged startup: `postgres → migrations → other services` |
| 303 | +**Flag in scan:** Look for `drizzle-kit` + `sqlmodel` or `sqlalchemy` in same project |
| 304 | + |
| 305 | +### 10. SQLModel Table Creation |
| 306 | +**Check for:** SQLModel `create_all()` usage |
| 307 | +**Problem:** Tables not created because models not imported |
| 308 | +**Solution:** Explicit model imports before `create_all()`: |
| 309 | +```python |
| 310 | +from .models import User, Task, Project # noqa: F401 |
| 311 | +``` |
| 312 | + |
| 313 | +### 11. JWKS Key Mismatch |
| 314 | +**Check for:** JWT validation across SSO instances |
| 315 | +**Problem:** Logged in via local SSO, Docker API validates against Docker SSO's JWKS |
| 316 | +**Error:** `Key not found - token kid: ABC, available kids: ['XYZ']` |
| 317 | +**Solution:** Clear cookies, login fresh through target environment |
| 318 | + |
| 319 | +### 12. uv Network Timeout |
| 320 | +**Check for:** `uv pip install` in Dockerfiles |
| 321 | +**Problem:** Network timeout during build |
| 322 | +**Solution:** Add `UV_HTTP_TIMEOUT=120` to Dockerfile |
| 323 | + |
| 324 | +--- |
| 325 | + |
| 326 | +## Additional Scan Targets |
| 327 | + |
| 328 | +When scanning, also check for: |
| 329 | + |
| 330 | +```bash |
| 331 | +# MCP Server Transport Security |
| 332 | +grep -r "FastMCP\|streamable_http" --include="*.py" |
| 333 | +
|
| 334 | +# Multiple ORM Usage (migration conflict risk) |
| 335 | +grep -r "drizzle\|prisma" --include="*.ts" --include="*.json" |
| 336 | +grep -r "SQLModel\|sqlalchemy" --include="*.py" |
| 337 | +
|
| 338 | +# Model imports before create_all |
| 339 | +grep -r "create_all\|create_db_and_tables" --include="*.py" |
| 340 | +
|
| 341 | +# UV in Dockerfiles |
| 342 | +grep -r "uv pip install" --include="Dockerfile*" |
| 343 | +``` |
0 commit comments