---
description: Validate project readiness before deploy — checks specs, contracts, tests, Docker, Neon/PostgreSQL, and Coolify configuration
argument-hint: [feature-name]
allowed-tools: Read, Bash, Glob, Grep
---

# Pre-Flight Check for Deployment

Validates project readiness before deploying to Docker/Coolify + Neon/PostgreSQL.

## Usage

```
/morph-preflight
```

## Purpose

Detect problems **before** deploy that would cause production failures. Saves time and avoids debugging in production.

---

## MORPH-SPEC Validation (run before all other checks)

These checks verify that the morph-spec workflow is complete for the feature being deployed.

```bash
# Verify implementation is complete
morph-spec status {feature}
morph-spec approval-status {feature}
morph-spec validate {feature}
```

| Check | Command | Pass Criteria |
|-------|---------|---------------|
| Phase is implement or later | `status` | phase derived as `implement` or `review` |
| All gates approved | `approval-status` | proposal, plan, review gates all approved |
| Feature validation passes | `validate` | 100% pass rate |
| All tasks complete | `status` → tasks | 0 tasks in `pending` or `in_progress` |
| Recap generated | Read `3-implement/recap.md` | File exists and is non-empty |

**If any MORPH check fails:** Show which check failed and recommend: `Run /morph-apply {feature} to complete implementation before deploying.`

---

## Test Suite (run before infrastructure checks)

```bash
dotnet test --verbosity normal
```

**Pass criteria:** 100% test pass rate. Zero tolerance — any failing test blocks deployment.

---

## Validations Performed

### 1. Package Version Conflicts

**What it checks:**
- No version conflicts (NU1605, NU1608)
- Critical packages with compatible versions

**How to check:**
```bash
dotnet restore --verbosity normal 2>&1 | grep -E "(NU1605|NU1608|warning)"
```

---

### 2. Database Migrations (Neon/PostgreSQL)

**What it checks:**
- Database is reachable
- No pending migrations
- RLS policies defined for all public tables
- Database schema matches expected state

**How to check:**
```bash
# Step 0: Verify database connectivity
psql "$(neonctl connection-string)" -c "SELECT 1" 2>/dev/null && \
  echo "✓ Database reachable" || \
  echo "✗ Database unreachable — skip remaining migration checks"

# Check for pending migrations (skip if connectivity failed)
neonctl branches diff <branch>

# Verify RLS is enabled on all tables
psql "$(neonctl connection-string)" -c "SELECT tablename FROM pg_tables WHERE schemaname='public' AND tablename NOT IN (SELECT tablename FROM pg_policies)"
```

> **Important:** If the database connectivity check fails, skip all migration checks and warn the user. Do not block the preflight — the database may be intentionally scaled to zero.

**Common fix:**
```bash
dotnet ef migrations add <migration-name>
```

---

### 3. Dockerfile Validation

**What it checks:**
- Dockerfile exists for each service (API, Web)
- Multi-stage build configured
- EXPOSE ports correct
- ENTRYPOINT defined
- .dockerignore present

**How to check:**
```bash
# Validate API Dockerfile
docker build --check -f Dockerfile.api .

# Validate Web Dockerfile
docker build --check -f Dockerfile.web .
```

---

### 4. Docker Compose

**What it checks:**
- `docker-compose.yml` exists and is valid
- All services have health checks
- Environment variables reference `.env` (not hardcoded)
- Volumes mapped correctly

**How to check:**
```bash
docker compose config --quiet
```

---

### 5. Environment Variables & Secrets

**What it checks:**
- Connection strings not hardcoded in code
- Secrets in environment variables (not in appsettings)
- `.env.example` exists with all required vars documented
- No credentials in source code

**How to check:**
```bash
# Detect passwords in appsettings
grep -rE "(Password=|Pwd=|Secret=|sk_live|pk_live)" appsettings*.json src/ --include="*.cs" --include="*.json" | grep -v Development

# Verify .env.example exists
test -f .env.example && echo "OK" || echo "MISSING .env.example"
```

---

### 6. Coolify Configuration

**What it checks:**
- Application correctly defined in Coolify (source repo, Dockerfile path, port)
- Health check endpoints exist (`/health` or `/healthz`)
- Port mappings match Dockerfile EXPOSE

**How to check:**
```bash
# Verify health endpoint exists in code
grep -rn "MapGet.*health" src/ --include="*.cs"

# Verify Coolify config placeholders were filled in (local file only)
grep -E "REPLACE_WITH_" coolify.json 2>/dev/null && echo "✗ coolify.json still has unfilled placeholders" || echo "✓ coolify.json configured"
```

> Coolify has no MCP/CLI — its API is only reachable via SSH into the VPS. `morph-preflight` never does this itself; it only checks the project's local files. Live verification against the running instance is a manual step for whoever holds VPS access.

---

## Example Output

```
MORPH Pre-Flight Check: Deployment

  Packages: No version conflicts detected
  Migrations: No pending changes
  Dockerfile: Valid multi-stage build (API + Web)
  Docker Compose: Valid configuration
  Secrets: No hardcoded credentials found
  Coolify: Health endpoint found at /healthz

Summary: 6 passed, 0 failed, 0 warnings

READY TO DEPLOY
```

---

## Usage Workflow

### Before creating PR for production

```bash
/morph-preflight
```

---

*MORPH-SPEC by Polymorphism Tech*
