# Phase 1: Infrastructure Foundation - Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-05-21
**Phase:** 1-Infrastructure Foundation
**Areas discussed:** Schema scope, App wiring, Background worker, Env / secrets strategy

---

## Schema Scope

| Option | Description | Selected |
|--------|-------------|----------|
| Full v1 skeleton | All tables upfront: users, refresh_tokens, quotas, documents, topics, folders, shares, audit_log, cloud_connections | ✓ |
| Phase 1 minimum | Only documents + topics tables; users and auth added in Phase 2 | |
| You decide | Leave scope to planner | |

**User's choice:** Full v1 skeleton
**Notes:** —

---

| Option | Description | Selected |
|--------|-------------|----------|
| Yes, seed the groups table | Empty table, correct columns and FKs; avoids schema change when v2 Group admin lands | ✓ |
| No, v1 tables only | Keep Phase 1 strictly to v1 requirements | |

**User's choice:** Yes, seed the groups table
**Notes:** PROJECT.md explicitly notes groups table will be seeded in schema.

---

| Option | Description | Selected |
|--------|-------------|----------|
| Leave existing data on filesystem; schema empty at Phase 1 end | Phase 3 runs migration script | |
| Seed a system / placeholder user | Sentinel user_id for Phase 1 uploads | |

**User's choice:** (Free text) "The current documents and files are just test data and can be deleted. Please switch uploads to PostgreSQL and MinIO."
**Notes:** Existing flat-file data is expendable test data. This changed the Phase 1 scope significantly: the storage service layer is rewritten in Phase 1, not Phase 3. Phase 3's data migration scope is removed.

---

## App Wiring

| Option | Description | Selected |
|--------|-------------|----------|
| Filesystem stays active; new infra sits ready | Phase 1 only wires infra; Phase 3 switches service layer | |
| Phase 1 switches uploads to PostgreSQL + MinIO | services/storage.py rewritten in Phase 1 | ✓ |

**User's choice:** Phase 1 switches uploads to PostgreSQL + MinIO
**Notes:** User clarified existing data is test data and can be deleted.

---

| Option | Description | Selected |
|--------|-------------|----------|
| Seed a default/admin user in Phase 1 migration | All Phase 1 uploads attributed to placeholder user | |
| Make user_id nullable for Phase 1, enforce NOT NULL in Phase 2 | Avoids phantom user; Phase 2 adds constraint | ✓ |

**User's choice:** user_id nullable in Phase 1
**Notes:** —

---

| Option | Description | Selected |
|--------|-------------|----------|
| Leave data/ directory in place | Stop writing to it; clean up manually or in Phase 3 | |
| Delete data/ contents in Phase 1 | Clean break; no ambiguity about active storage | ✓ |

**User's choice:** Delete data/ contents in Phase 1
**Notes:** Old data is test data only.

---

| Option | Description | Selected |
|--------|-------------|----------|
| Single bucket 'docuvault' with user prefix paths | Standard S3 pattern; matches STORE-02 key schema | ✓ |
| Per-user buckets | Stronger isolation but bucket count issues and operational complexity | |

**User's choice:** Single bucket 'docuvault'
**Notes:** —

---

## Background Worker

| Option | Description | Selected |
|--------|-------------|----------|
| pgqueuer | Postgres-native; no Redis; simpler Compose | |
| Celery + Redis | Battle-tested; adds Redis service | ✓ |

**User's choice:** Celery + Redis
**Notes:** —

---

| Option | Description | Selected |
|--------|-------------|----------|
| Phase 1 — add it now with the other infra | All services wired together in one shot | ✓ |
| Phase 3 — add when horizontal scaling needed | STORE-08 is a Phase 3 requirement | |

**User's choice:** Phase 1 — add Redis + Celery now
**Notes:** Redis also serves as the rate-limiting store for Phase 2 auth endpoints.

---

## Env / Secrets Strategy

**User asked for best practice guidance** before answering — wanted to understand production VPS implications (root server / VPS deployment, database admin password handling). Claude explained:
- App should never use PostgreSQL superuser; restricted users per principle of least privilege
- Secrets stored outside project directory at `/etc/docuvault/env`; `chmod 600`, service user owned
- Two DB DSNs: runtime (restricted) + migration (DDL privileges)

| Option | Description | Selected |
|--------|-------------|----------|
| .env gitignored + .env.example committed | Docker Compose native; self-hosters copy .env.example → .env | ✓ |
| Hardcoded dev defaults in docker-compose.yml | Simpler but secrets committed to git | |
| docker-compose.override.yml for secrets | Flexible but extra indirection layer | |

**User's choice:** .env gitignored + .env.example committed; production at `/etc/docuvault/env`

---

| Env var group | Selected |
|---|---|
| DATABASE_URL + DATABASE_MIGRATE_URL | ✓ |
| MINIO_ENDPOINT / MINIO_ROOT_USER / MINIO_ROOT_PASSWORD / MINIO_BUCKET | ✓ |
| REDIS_URL | ✓ |
| SECRET_KEY | ✓ |

**Notes:** All four groups introduced in Phase 1. SECRET_KEY documented now for Phase 2+ use (JWT + HKDF) even though Phase 1 doesn't read it.

---

| Option | Description | Selected |
|--------|-------------|----------|
| Yes — provision restricted users in Phase 1 | init script creates docuvault_app + docuvault_migrate | ✓ |
| No — use superuser for now, split in Phase 2 | Simpler but not least-privilege | |

**User's choice:** Yes — provision restricted users in Phase 1
**Notes:** —

---

## Claude's Discretion

None — user made explicit choices for all areas.

## Deferred Ideas

None — discussion stayed within phase scope.
