# Phase 14: Volumes & Environment

**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** fullstack

## Objective
Implement per-project environment variables with per-stage overrides, volume mounts with shared/isolated modes, sensitive env value encryption, and UI for managing both.

## Tasks

- [ ] Task 1: Extend store schema — add `stage_env` table for per-stage env overrides (stage_id, key, value, encrypted bool)
- [ ] Task 2: Extend store schema — add `volumes` table for volume config (project_id, source, target, mode: shared|isolated)
- [ ] Task 3: Implement store CRUD for stage env overrides (Create, GetByStageID, Update, Delete)
- [ ] Task 4: Implement store CRUD for volumes (Create, GetByProjectID, Update, Delete)
- [ ] Task 5: Encrypt sensitive env values (values marked as secret) using crypto.Encrypt before storage
- [ ] Task 6: Merge env vars during deploy — project-level env + stage-level overrides, decrypt secrets
- [ ] Task 7: Compute volume mounts during deploy — shared mode uses path as-is, isolated mode appends `/{stage}-{tag}/` to source
- [ ] Task 8: Pass merged env vars and volume mounts to Docker container creation
- [ ] Task 9: API endpoints — CRUD for stage env vars and project volumes
- [ ] Task 10: Frontend — env var editor in project/stage settings (key/value pairs, secret toggle)
- [ ] Task 11: Frontend — volume editor in project settings (source/target/mode)
- [ ] Task 12: Frontend — per-stage env override UI showing inherited vs overridden values

## Files to Modify/Create
- `internal/store/stage_env.go` — stage env CRUD
- `internal/store/volumes.go` — volume CRUD
- `internal/store/store.go` — add new tables to schema
- `internal/deployer/deployer.go` — merge env vars and compute volume mounts during deploy
- `internal/docker/container.go` — accept volume mounts in ContainerConfig
- `internal/api/stages.go` — add env var endpoints
- `internal/api/projects.go` — add volume endpoints
- `web/src/routes/projects/[id]/env/+page.svelte` — env var editor
- `web/src/routes/projects/[id]/volumes/+page.svelte` — volume editor

## Acceptance Criteria
- Project-level env vars applied to all containers
- Stage-level overrides replace project-level values for matching keys
- Sensitive env values encrypted at rest, decrypted only during deploy
- Shared volumes: all instances mount same host path
- Isolated volumes: each instance gets `{source}/{stage}-{tag}/` subdirectory
- UI allows managing env vars and volumes per project and per stage

## Notes
- Project `env` field already exists as JSON blob in the store — this phase may migrate to a proper table or keep JSON and add stage overrides separately
- Volume `mode` is either "shared" or "isolated"
- Isolated volume subdirectory is created automatically by Docker (bind mount creates parent dirs)
- Sensitive env display: masked in UI, "Change" button pattern (same as credentials page)

## Review Checklist
- [ ] All tasks completed
- [ ] Env merge logic is correct (stage overrides project)
- [ ] Secret values never appear in plaintext in API responses
- [ ] Volume paths are validated (no path traversal)
- [ ] Isolated volume subdirectory naming is deterministic

## Handoff to Next Phase
<!-- Filled in by the implementation agent after completing this phase. -->
