# Deployment Checklist

# Deployment Checklist

> **Project:** Bilko
> **Version:** 0.1
> **Date:** 2026-02-23
> **Author:** Ops Architect
> **Status:** Draft
> **Reviewers:** Tech Lead, Alem Bašić

## Document History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 0.1     | 2026-02-23 | Ops Architect | Initial draft |

---

## INSTRUCTIONS

Use this checklist for every production deployment. Create a copy for each release:
`DEPLOY-CHECKLIST-YYYY-MM-DD-vX.X.X.md` in `docs/releases/`

**Never skip items.** If an item doesn't apply, mark N/A with reason.

---

# Deployment Checklist: Bilko v[VERSION]

**Deploy date:** YYYY-MM-DD
**Deploy time:** HH:MM CET
**Release notes:** [Link to release notes]
**Deployer:** [Name]
**Reviewer:** [Name]

---

## Pre-Deployment (Run 24 Hours Before)

### Code & Tests

- [ ] All CI checks green on main branch (lint, type-check, unit tests, integration tests, build, E2E)
- [ ] Coverage ≥ 80% overall, ≥ 95% financial logic
- [ ] All PRs in this release merged to main
- [ ] No `TODO` or `FIXME` comments referencing this release
- [ ] No skipped tests (`it.skip`, `test.skip`) in financial logic files
- [ ] Release notes prepared and reviewed

### Database

- [ ] New migrations reviewed by Tech Lead
- [ ] Migrations tested on staging environment:
  - Applied successfully: Yes / No
  - Rollback (down migration) tested: Yes / No
  - Migration time on staging (record): ___ seconds
- [ ] Migration is backward-compatible (old API version can still read data): Yes / N/A
- [ ] If schema changes: Prisma Client regenerated and tested

### Security

- [ ] No new secrets committed to git (`git log --all --grep='password\|secret\|key'` — should be clean)
- [ ] All new API endpoints require authentication (no accidental public endpoints)
- [ ] RBAC verified for new endpoints (correct roles enforced)
- [ ] Zod validation applied to all new request bodies
- [ ] No cross-org data leakage in new queries

### Financial Logic (Skip if release has no financial changes)

- [ ] VAT calculations tested for all 3 countries (RS 20%, BA 17%, HR 25%)
- [ ] Double-entry validation enforced for all new transaction creation paths
- [ ] NUMERIC(19,4) used throughout — no JavaScript `number` for monetary values
- [ ] Exchange rate locking verified for multi-currency transactions
- [ ] Invoice total calculation verified: subtotal + VAT - discount = total (exact, no float)

---

## Staging Verification (Run 2 Hours Before)

- [ ] Staging deployment successful (same build that will go to production)
- [ ] Staging health check passing: `curl https://staging-api.bilko.io/health`
- [ ] Manual smoke test on staging:
  - [ ] Login with test account
  - [ ] Create invoice (RSD, 20% VAT) — verify totals correct
  - [ ] Create expense with receipt upload
  - [ ] Generate VAT report
  - [ ] Verify report numbers are consistent with data
- [ ] E2E tests pass on staging
- [ ] No new Sentry errors after staging deploy (check Sentry for 30 min)
- [ ] Database migrations applied to staging: `bilko_staging` DB

---

## Backup (Run 30 Minutes Before)

- [ ] Pre-deploy backup taken:
  ```bash
  railway run pg_dump $DATABASE_URL -f pre_deploy_$(date +%Y%m%d_%H%M).dump
  ```
- [ ] Backup file accessible and non-empty
- [ ] Backup stored in secure location (note location here): _______

---

## Deployment Execution

### Step 1: Apply Database Migrations

- [ ] Migrations applied to production:
  ```bash
  railway run npx prisma migrate deploy
  ```
- [ ] Migration successful: Yes / No
- [ ] Post-migration record count check:
  ```bash
  railway run psql $DATABASE_URL -c "SELECT COUNT(*) FROM invoices, COUNT(*) FROM organizations;"
  ```
  - Invoice count: ___
  - Organization count: ___

### Step 2: Deploy Backend (Railway)

- [ ] Push to main triggers Railway production deploy (automatic via CI)
  OR manual: `railway up --service api --environment production`
- [ ] Railway deployment successful
- [ ] Railway health check green: `curl https://api.bilko.io/health`
- [ ] No restart loops in Railway logs

### Step 3: Deploy Frontend (Vercel)

- [ ] Vercel production deployment successful (automatic via CI)
  OR manual: `cd apps/web && vercel --prod`
- [ ] bilko.io loads correctly in browser
- [ ] No browser console errors on first load

---

## Post-Deployment Verification (Run Immediately After Deploy)

- [ ] API health: `curl https://api.bilko.io/health` → `{"status":"ok","db":"ok"}`
- [ ] Frontend: `curl -I https://bilko.io` → HTTP/2 200
- [ ] Login flow: can log in with test account
- [ ] Invoice creation: create test invoice, verify totals
- [ ] BetterStack: all monitors green
- [ ] Sentry: no new error types in first 15 minutes
- [ ] Railway: CPU < 50%, Memory < 1GB

---

## 15-Minute Monitoring Window

Monitor for 15 minutes after deploy. Record observations:

| Time | API Health | Error Rate | CPU | Memory | Notes |
|------|-----------|-----------|-----|--------|-------|
| +0 min | | | | | |
| +5 min | | | | | |
| +10 min | | | | | |
| +15 min | | | | | |

**Deploy declared successful:** [ ] Yes — at HH:MM by [Name]

---

## Rollback Criteria

**Rollback immediately if:**
- Health check fails for > 3 consecutive minutes
- Error rate > 5% (Sentry)
- Any financial calculation producing incorrect results
- Authentication completely broken

**See rollback procedure:** [rollback-plan.md](./ROLLBACK-PLAN.md)

---

## Post-Deploy Cleanup

- [ ] Rollback plan document created for this release (if major release)
- [ ] Release notes published
- [ ] Team notified in Slack #bilko-deploys: "v[VERSION] deployed successfully"
- [ ] Deploy notes added to GitHub release tag

---

## Approval
| Role | Name | Date | Signature |
|------|------|------|-----------|
| Deployer | | | |
| Reviewer | Alem Bašić | | |