docs(04): capture phase context
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user