# Phase 4: Folders, Sharing, Quotas & Document UX - 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-25
**Phase:** 04-folders-sharing-quotas-document-ux
**Areas discussed:** Folder navigation layout, Sharing discovery UX, PDF proxy & PDF.js approach, Audit log event catalog

---

## Folder navigation layout

| Option | Description | Selected |
|--------|-------------|----------|
| Sidebar tree | Collapsible full tree in AppSidebar; always visible; click to navigate | |
| Main area drill-down | Folders as cards in main area; no sidebar tree | |
| Hybrid: top-level in sidebar + breadcrumb in main | Sidebar shows top-level folders only; sub-folder rows + breadcrumbs in main area | ✓ |

**User's choice:** Hybrid — top-level folders in sidebar, breadcrumb + sub-folder rows in main content area

| Option | Description | Selected |
|--------|-------------|----------|
| Unlimited nesting | No API/UI cap; breadcrumbs truncate with ellipsis | ✓ |
| 2 levels max | API enforces depth limit; simpler breadcrumbs | |
| You decide | Defer to planner | |

**User's choice:** Unlimited nesting

| Option | Description | Selected |
|--------|-------------|----------|
| Move docs to root before deleting | Documents survive, lose folder assignment | |
| Cascade delete — docs + folder deleted together | Warning shows count; user confirms | ✓ |
| Block delete if non-empty | 409 response; user must empty manually first | |

**User's choice:** Show warning modal with document count; user confirms → cascade-delete documents and folder
**Notes:** User explicitly said "Let the user accept or decline" — warning with confirm/cancel. Confirmed that delete means permanent removal of documents (not move to root) when clarified.

---

## Sharing discovery UX

| Option | Description | Selected |
|--------|-------------|----------|
| Exact handle input | Type full handle; no suggestions; no search endpoint | ✓ |
| Live autocomplete | Type-to-search dropdown; requires GET /api/users/search | |

**User's choice:** Exact handle input — no autocomplete, no search endpoint

| Option | Description | Selected |
|--------|-------------|----------|
| Inline button on DocumentCard + modal | Share icon on card opens modal with handle input + share list | ✓ |
| Document detail view action | Sharing only from DocumentView, not card | |

**User's choice:** Share button on DocumentCard, opens modal

| Option | Description | Selected |
|--------|-------------|----------|
| Fixed entry in AppSidebar above user folders | Always visible, virtual folder concept | ✓ |
| Separate route / dedicated view | Accessible via /shared; not in main sidebar | |
| Filtered view on main document list | Toggle/tab on HomeView | |

**User's choice:** Fixed "Shared with me" entry in AppSidebar above user folders

---

## PDF proxy & PDF.js approach

| Option | Description | Selected |
|--------|-------------|----------|
| Streaming proxy endpoint | GET /api/documents/{id}/content; StreamingResponse; no presigned URL exposed | ✓ |
| Server-side redirect with signed URL | 302 redirect to short-lived presigned URL | |

**User's choice:** Streaming proxy endpoint

| Option | Description | Selected |
|--------|-------------|----------|
| pdfjs-dist npm package — Vue component | Bundled PDF.js; ~800KB gzip; canvas rendering | |
| PDF.js pre-built viewer via iframe | Static HTML viewer served from backend | |
| Native browser PDF rendering | Content-Disposition: inline; zero dependencies | ✓ |

**User's choice:** Native browser PDF rendering

**Notes:** DOC-02 literally specifies PDF.js. User was informed of the discrepancy and chose to prioritize intent (privacy model) over the literal requirement. Claude flagged this before the user confirmed.

| Option | Description | Selected |
|--------|-------------|----------|
| In-app modal/panel | iframe in modal overlay | |
| New browser tab | window.open() | |
| You decide | Defer to planner | |

**User's choice (follow-up):** Per-user preference setting — users choose whether PDFs open in-app (iframe modal) or in a new browser tab

| Option | Description | Selected |
|--------|-------------|----------|
| localStorage — per-browser | No backend work; simple | |
| DB-backed — synced across devices | users.pdf_open_mode column + PATCH /api/me/preferences | ✓ |

**User's choice:** DB-backed preference (synced across all user devices)

---

## Audit log event catalog

| Option | Description | Selected |
|--------|-------------|----------|
| Auth events | Login, logout, password change, TOTP, backup codes | ✓ |
| Document operations | Upload (no filename), delete, reclassify | ✓ |
| Folder & share operations | Folder create/delete, share grant/revoke | ✓ |
| Admin actions | User create, deactivate, quota change, AI config | ✓ |

**User's choice:** All 4 categories

| Option | Description | Selected |
|--------|-------------|----------|
| Inline in each API handler | Explicit per-handler; shared write_audit_log() helper | ✓ |
| FastAPI middleware | Centralized but hard to add contextual data | |
| Celery background task | Async but adds latency and complexity | |

**User's choice:** Inline in each handler with shared helper

| Option | Description | Selected |
|--------|-------------|----------|
| Filters only — paginated table | Date range, user, action type; paginated | |
| Filters + export (CSV/JSON) | Same + download button | ✓ |
| You decide | Defer to planner | |

**User's choice:** Filters + export + daily automated CSV backup to MinIO `audit-logs` bucket
**Notes:** User requested daily automatic CSV backup in addition to manual export, specifically to manage log file size over time. Backup stored in MinIO (not local filesystem) for persistence.

---

## Claude's Discretion

- Search UX placement (search bar in existing document list vs. dedicated route) — decided inline filter as standard approach per Phase 4 domain
- Breadcrumb truncation threshold — N > 4 segments shows first + "..." + last 2

## Deferred Ideas

- **Per-day document scan quota tiers** — User wants subscription tiers based on daily AI scan count, not just storage. Business model idea: "having a local storage quota might get some subscribers but connecting your google drive defeats the purpose." Recommended as a separate billing/subscription milestone.
- **Share permission levels beyond `view`** — `edit`/`comment` permission deferred.
- **Audit log row archival/TTL policy** — Daily CSV backup provides export; DB row deletion policy deferred.
