docs: add domain research (4 dimensions + synthesis)

This commit is contained in:
curo1305
2026-05-21 20:42:16 +02:00
parent 2a298a4276
commit daa7e0f289
5 changed files with 2406 additions and 0 deletions
+449
View File
@@ -0,0 +1,449 @@
# Feature Research
**Domain:** SaaS Document Management Platform (multi-user, quota-enforced, privacy-first)
**Researched:** 2026-05-21
**Confidence:** MEDIUM (web fetch/search unavailable; based on training knowledge of Google Drive, OneDrive, Dropbox, Box, Notion, Paperless-ngx, DocuWare through Aug 2025 — all mature platforms with stable, well-documented feature sets)
---
## Research Scope
Platforms surveyed: Google Drive, Microsoft OneDrive, Dropbox, Notion, Box, Paperless-ngx (self-hosted), DocuWare (enterprise DMS).
Eight areas analyzed per the brief:
1. Auth & access control
2. Storage & quota UX
3. Folder/organization UX
4. Sharing model
5. Cloud storage integration UX
6. Admin panel
7. Audit / compliance
8. Document viewer features
---
## Feature Landscape
### Table Stakes (Users Expect These)
Features users assume exist. Missing these = product feels incomplete or broken.
#### 1. Auth & Access Control
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Email + password registration with validation | Every SaaS has this | LOW | Strength rules (length, complexity) expected; breach-check (HaveIBeenPwned API) is a notable addition |
| Persistent sessions with "remember me" | Users hate logging in every visit | LOW | JWT with refresh token; sliding expiry. Pure stateless JWT without refresh feels cheap. |
| Password reset via email | Users forget passwords constantly | LOW | Time-limited signed token; mandatory |
| TOTP 2FA (authenticator app) | Expected at any security-conscious SaaS | MEDIUM | PyOTP / HOTP RFC 6238. Users expect QR code setup + backup codes. Missing backup codes = major UX gap. |
| Forced logout / session revocation | Power users and security-conscious users expect this | MEDIUM | "Sign out all devices" is table stakes at Box and Google. Requires server-side session tracking (defeats pure JWT — use a token revocation list or short-lived JWTs + refresh token table). |
| Per-user isolated data space | Every cloud storage product does this | LOW | Violated = catastrophic trust failure. MinIO prefix isolation per user ID. |
| Account deletion with data wipe | GDPR + user trust | MEDIUM | Must cascade: documents, quotas, shares, cloud credentials, audit entries scoped to user. |
#### 2. Storage & Quota UX
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Visible quota indicator (used / total) | Google Drive, Dropbox, OneDrive all show this prominently | LOW | Progress bar + "X MB of Y MB used" in sidebar or settings. Missing = users feel blind. |
| Quota check at upload time with clear error | Every platform rejects over-quota uploads | LOW | Error must say "You've used X of Y MB — free up space or upgrade." Not a generic 500. |
| Per-file size shown in file list | Dropbox, Drive show sizes in list view | LOW | Users make quota decisions based on file size visibility. |
| Sort/filter by size | Users cleaning up quota expect to find large files | LOW | "Largest files first" sort is a common quota-management action. |
| Quota warning at 80% and 95% | Drive warns at 80%; Dropbox emails at 90% | LOW | In-app banner + optionally email. Users are surprised when they hit the wall without warning. |
| Storage usage breakdown by folder/category | Drive shows breakdown by file type | MEDIUM | "X MB in Documents, Y MB in Images" helps users understand what to delete. Folder-level usage is lower priority but expected by power users. |
| Delete confirmation that shows freed space | Minor but Dropbox/Drive do this | LOW | "Deleting this file will free 24 MB." Reinforces value of the action. |
#### 3. Folder / Organization UX
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Create folder | Universal | LOW | Standard. |
| Rename folder | Universal | LOW | Inline rename (click-to-edit) is expected; modal is acceptable. |
| Delete folder (with contents confirmation) | Universal | LOW | Must warn if non-empty: "This will delete N documents." Soft-delete preferred; hard-delete on confirm. |
| Move document to folder (drag-and-drop or context menu) | Drive, Dropbox have both | MEDIUM | Drag-and-drop is a strong UX expectation in desktop-class web apps. Context menu "Move to..." is the fallback minimum. |
| Move folder into another folder (nesting) | Drive, OneDrive support arbitrary depth | MEDIUM | Users expect arbitrary depth. Cap at 58 levels deep to avoid pathological nesting; unlimited is fine for v1. |
| Breadcrumb navigation | Universal in file managers | LOW | Clickable breadcrumb showing full path: Root > Invoices > 2025. Without this users get lost in nested folders. |
| Sort documents within folder (name, date, size, type) | All platforms have this | LOW | Default: date descending (newest first). |
| "Recent" / "Last accessed" virtual folder | Drive, OneDrive surface this prominently | LOW | Not a real folder — a filtered view. Users navigating back to recent work expect it. |
| Search across all documents | Every platform has global search | MEDIUM | Full-text or metadata search. For DocuVault, text is already extracted — expose it in search. Missing = product feels like a filing cabinet with no index. |
| Multi-select for batch operations | Drive, Dropbox support shift-click + checkbox | MEDIUM | Batch delete, batch move. Without this, managing many files is tedious. |
| "Shared with me" virtual folder | Drive has this; Box has it; Dropbox has it | LOW | Auto-populated when another user shares a document. Already in PROJECT.md. |
#### 4. Sharing Model
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Share with named user (by handle or email) | Drive, Box, Dropbox all do this | MEDIUM | Core sharing primitive. Must show: who has access, their permission level, revoke button. |
| View-only vs. edit permission distinction | Box, Drive, Dropbox all distinguish view/edit | LOW | For DocuVault, edit means "re-upload / annotate" — since no in-app editing, view-only is the primary mode. Still must distinguish the concept for future extensibility. |
| Revoke share immediately | All platforms do this | LOW | No delay. If the user is currently viewing the document, their next request should 403. |
| Share notification to recipient | Drive/Dropbox send email; Box shows in-app | LOW | At minimum: in-app notification. Email is table stakes for platforms where users may not be logged in. |
| See list of "what I've shared" | Drive, Box surface this | LOW | Users need to audit their own shares. A "Shared by me" list per document + a global shares list in settings. |
| Accept / decline incoming share | Box requires acceptance; Drive shows silently | MEDIUM | DocuVault's "Shared with me" folder appearing is implicit acceptance. An explicit accept/decline adds trust. Drive skips it; Box requires it for external shares. Given privacy-first positioning, explicit accept is the better default. |
| Share expiry date | Box supports this; Drive (with Workspace) does; Dropbox Business does | MEDIUM | Not universal at consumer tier but expected in security-conscious / business contexts. |
#### 5. Cloud Storage Integration UX
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| OAuth2 connect flow for Google Drive / OneDrive | Standard for these integrations | HIGH | Redirect-based OAuth2 PKCE. Users expect "Connect" → browser popup → granted → back to app. No credential entry. |
| Connection status indicator (connected / disconnected / error) | Any integration page shows this | LOW | Green dot = connected, red = error with message. Dropbox Business sync indicators are the model. |
| Disconnect / re-authenticate option | Users rotate tokens; credentials expire | LOW | "Disconnect" button. Re-auth if token expires (silent token refresh where possible). |
| Default storage selector | Users need to know where new uploads go | LOW | Clear radio/dropdown: "Local storage" vs "Google Drive" vs "OneDrive." Show current default prominently. |
| Upload routing confirmation | When cloud is default, users want to see it confirmed | LOW | "Stored in Google Drive" in upload success message. |
| Error state when cloud storage unreachable | Cloud services go down; credentials expire | MEDIUM | Graceful: queue locally, show warning, retry. Hard fail (lose document) = catastrophic. Minimum: "Storage unavailable — document saved locally." |
| Basic usage from cloud backend | Show how much cloud storage is used vs available | MEDIUM | Google Drive has 15 GB free; OneDrive 5 GB. Surfacing "You've used 3 GB of your 15 GB Google Drive" alongside local quota gives users a full picture. |
#### 6. Admin Panel
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| User list with search and pagination | Every admin panel has this | LOW | Show: username, email, registration date, last login, quota used/total, active/inactive status. |
| Create user account | Admin needs to onboard users manually (invite flow) | LOW | Form: email, temp password (force reset on first login), quota assignment. |
| Deactivate / reactivate user | Admin must be able to remove access without deleting data | LOW | Soft disable: user cannot log in; data preserved. Separate from delete. |
| Force password reset | Standard admin action | LOW | Invalidates current sessions; user gets reset email. |
| Quota adjustment per user | Already in PROJECT.md | LOW | Input: new quota in MB. Show current usage. Prevent setting quota below current usage (warn, not block). |
| System-wide default quota setting | Admins want to change the free tier baseline | LOW | Global default that new users inherit. Existing users keep their individually-set quota. |
| AI provider/model assignment per user | Already in PROJECT.md | MEDIUM | Dropdown of configured providers + models. Show "using system default" until overridden. |
| System-wide AI provider default | Already in PROJECT.md | LOW | Global fallback when no user override exists. |
| Audit log viewer | All enterprise DMS products have this | MEDIUM | See Audit section below. |
| Platform health indicators | Admins need to know if things are broken | MEDIUM | Storage backend connectivity, database connection, queue depth. A simple status page at /admin/health. |
#### 7. Audit / Compliance
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Audit log of security events | GDPR, SOC2 baseline, enterprise buyers expect this | MEDIUM | Mandatory events: login, failed login, password reset, 2FA enable/disable, session revoke. |
| Audit log of data events | Same compliance baseline | MEDIUM | Mandatory events: document upload, document delete, document move/rename, share create, share revoke, quota change. |
| Metadata-only audit (no content) | Privacy requirement — DocuVault's stated constraint | LOW | Log: actor_user_id, action, target_resource_id, timestamp, IP address. Never log document content or filenames in the log (filename is sensitive metadata). |
| Admin-viewable audit log with filters | Already in PROJECT.md | MEDIUM | Filter by: user, action type, date range. Export to CSV is expected by compliance-oriented admins. |
| Immutable audit log | Audit logs lose their value if they can be edited | MEDIUM | Append-only table. No UPDATE/DELETE on audit rows. Admin UI shows only read operations. |
| IP address logging | Standard for login events; expected by security teams | LOW | Log IP on all auth events. GDPR note: IP is PII — include in retention policy. |
| Log retention policy | GDPR requires defined retention | LOW | Configurable in admin settings. Default: 1 year. Automated purge of older entries. |
| GDPR data export (user's own data) | GDPR Article 20 right to portability | HIGH | User can request export of all their data: document list + metadata (not necessarily content), account info, audit log of their own actions. Full content export is optional but the metadata export is required. |
#### 8. Document Viewer Features
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| In-browser PDF preview | Drive, Dropbox, Box all have this | MEDIUM | Use browser's native PDF viewer or PDF.js. Without preview, users must download to read — major friction. |
| Document metadata panel | All DMS platforms show this | LOW | Show: upload date, file size, MIME type, AI-assigned topics, uploader, storage backend. |
| AI topics display | Core DocuVault feature | LOW | Show assigned topics with confidence if available. Allow manual topic override from document detail. |
| Download original file | Universal | LOW | Always available. Even if preview fails, download must work. |
| Document rename | Drive, Dropbox allow rename from detail view | LOW | Inline rename in detail view or list view. |
| Delete from detail view | Universal | LOW | With confirmation. Returns to parent folder. |
| "Shared with" indicator on document | Drive shows a "people" icon on shared items | LOW | Visual indicator in list view that document is shared. Click to see who. |
| Basic image preview (JPG, PNG) | All platforms preview images natively | LOW | Browser <img> tag is sufficient. |
| Text file preview | Drive, Dropbox show .txt inline | LOW | Simple <pre> render of extracted text is adequate. |
---
### Differentiators (Competitive Advantage)
Features that align with DocuVault's core value (privacy-first, self-hosted, AI-classified).
| Feature | Value Proposition | Complexity | Notes |
|---------|-------------------|------------|-------|
| Privacy-first admin model (admin cannot read documents) | Unique trust proposition vs Google Drive/OneDrive where the operator can read everything | HIGH | Encryption-at-rest with user-scoped keys; admin queries explicitly exclude content. No other mainstream cloud platform offers this by default. Strong differentiator for privacy-conscious users. |
| Bring-your-own cloud storage backend | Users keep their existing cloud storage; DocuVault is the intelligent layer on top | HIGH | Google Drive/OneDrive are the storage, DocuVault is the classifier/organizer. Removes the "I have to trust another cloud with my docs" objection. |
| AI topic classification on upload (automatic) | No other mainstream DMS auto-classifies by topic on upload | MEDIUM | Paperless-ngx has auto-tagging; DocuWare has rules-based classification. AI-driven flexible topics is differentiated for non-enterprise users. |
| Multiple AI provider support (local/private inference) | Users who want fully on-premises AI (Ollama) get privacy guarantee no cloud DMS offers | MEDIUM | Ollama / LMStudio means documents never leave the user's infrastructure. Strong appeal to privacy-first and regulated-industry users. |
| Per-user topic customization on top of system defaults | Users get personalized classification without admin overhead | MEDIUM | System topics + per-user overrides. No mainstream cloud DMS supports per-user AI taxonomy customization. |
| Share expiry with automatic revocation | Goes beyond basic sharing; prevents forgotten shares | MEDIUM | Dropbox Business and Box have this at paid tiers. Including it at v1 is differentiating for a free-tier self-hosted platform. |
| Explicit share accept/decline | Recipient has control; aligns with privacy-first positioning | LOW | Box has this; Drive doesn't require it. Gives recipients agency. |
| Storage backend per-document routing | Some documents go to Drive, others to local — user decides per-upload | HIGH | No mainstream platform does this. Users with mixed sensitivity needs can route sensitive docs to local and bulk docs to Drive. Complex to implement but uniquely valuable. |
| In-app audit log visible to the user (not just admin) | Users can see their own activity history | LOW | GDPR-aligned; builds trust. Google Activity Dashboard is the model. Most self-hosted DMS don't surface this to users. |
---
### Anti-Features (Deliberately Excluded)
Features that seem good but would create problems for this project.
| Feature | Why Requested | Why Problematic | Alternative |
|---------|---------------|-----------------|-------------|
| Public link sharing (unauthenticated) | Users want to share with people not on the platform | Creates a public attack surface; quota abuse; legal exposure if abused; hard to revoke at scale | Out of scope for v1 per PROJECT.md. Named-user sharing with accept/decline serves legitimate use cases. |
| In-app document editing | Users want a full office suite | Massive scope expansion (collaborative editing = CRDT, OT, conflict resolution); not core to document management; every vendor locks you into their editor | "View and organize" is the value; editing stays in the originating app. |
| Real-time collaborative editing (Google Docs model) | Feels modern | Requires WebSocket infrastructure, OT/CRDT algorithms, presence indicators — easily 3x the codebase complexity of everything else combined | Explicit non-goal; DocuVault stores files, not live documents. |
| Mobile app (iOS/Android) | Users want mobile access | React Native or Flutter doubles the implementation surface; mobile OAuth2 and background sync are non-trivial | Responsive web app is the minimum. PWA capabilities (offline-capable via service worker) are a future v2 differentiator. |
| SSO / SAML / OAuth enterprise federation | Enterprise buyers ask for it | Premature: adds Keycloak or similar dependency, requires session model changes, needs testing against multiple IdPs | TOTP 2FA first; SSO when subscription billing lands. Schema already designed for extension. |
| Subscription billing in-platform | Users want self-service upgrades | Payment processing is a separate product (Stripe integration, dunning, invoicing, tax). Doing it half-way creates billing bugs that destroy trust | Quota model is billing-ready (limit_bytes column); add Stripe when subscription tier is validated. |
| Soft-delete / Trash with restore | Users accidentally delete things | Reasonable feature, but complicates quota accounting (does trash count against quota?), storage lifecycle, and purge timing. Drive's 30-day trash has caused user confusion about "why is my quota still full?" | Clear confirmation dialog before hard delete is the v1 approach. Trash can be added in v1.x. |
| Document version history | Users want to see old versions | Correct for collaborative tools; for a personal document store where users own their files, versioning explodes storage use. Paperless-ngx doesn't have it. DocuWare does but it's enterprise | Hash-based deduplication (don't store the same file twice) is a better v1 primitive. Version history in v2 for users who need it. |
| AI-generated document summaries | Seems valuable given AI integration | Every summary requires an AI call → cost scales with uploads; summaries become stale when topics change; storing summaries consumes quota | AI is used for classification only. Summary generation can be a user-triggered on-demand action later. |
| Admin impersonation / "log in as user" | Admins want to debug user issues | Directly contradicts the privacy-first core value. If admin can impersonate, admin can access user documents. Trust collapses. | Structured audit logs give admins enough to diagnose issues without impersonation. Document this as an explicit architectural decision. |
---
## Feature Dependencies
```
[User Registration + Auth]
└──requires──> [Email verification] (optional at v1, needed for password reset)
└──requires──> [JWT session management]
└──requires──> [Token revocation list] (for forced logout)
[TOTP 2FA]
└──requires──> [Backup codes] (users get locked out without these)
└──requires──> [User Auth base]
[Document Upload]
└──requires──> [User Auth]
└──requires──> [Quota enforcement]
└──requires──> [Quota tracking (DB)]
[Folder Structure]
└──requires──> [Document Upload]
└──enhances──> [Search] (search within folder scope)
[Document Sharing]
└──requires──> [User accounts] (both sender and recipient)
└──requires──> [Folder Structure] ("Shared with me" virtual folder)
└──requires──> [Permission model in DB]
[Share expiry]
└──requires──> [Document Sharing base]
└──requires──> [Background job / cron] (to revoke expired shares)
[Cloud Storage Integration]
└──requires──> [User Auth] (OAuth2 tokens stored per user)
└──requires──> [Credential encryption] (Fernet / pgcrypto)
└──requires──> [StorageBackend adapter interface] (already planned)
└──enhances──> [Quota tracking] (cloud quota shown separately)
[Per-document storage routing]
└──requires──> [Cloud Storage Integration]
└──requires──> [Multiple backends connected]
[Admin Panel]
└──requires──> [User accounts]
└──requires──> [Quota DB model]
└──requires──> [Audit log]
[Audit Log]
└──requires──> [User Auth] (actor_user_id)
└──requires──> [All logged operations exist]
└──conflicts──> [Admin impersonation] (impersonation breaks log integrity)
[GDPR data export]
└──requires──> [Audit log]
└──requires──> [Document metadata model]
└──requires──> [Background export job] (large exports are async)
[AI classification]
└──requires──> [Document upload + text extraction] (already exists)
└──requires──> [Topic model] (already exists)
└──enhances──> [Search] (topic-filtered search)
[In-browser PDF preview]
└──requires──> [Document stored accessibly] (MinIO presigned URL or proxy endpoint)
└──independent of──> [Cloud storage] (preview proxied through app, not direct cloud URL)
```
### Dependency Notes
- **TOTP requires backup codes:** Without backup codes, users who lose their phone lose their account permanently. This is a support nightmare and a documented UX failure in many 2FA implementations.
- **Forced logout requires server-side token tracking:** Pure stateless JWT cannot support "sign out all devices." A revocation list (Redis or DB table) or short-lived JWTs (15 min) + refresh token table is required. This is a non-trivial architecture decision that must be resolved before auth is implemented.
- **Share expiry requires a background job:** Expiry cannot be purely DB-enforced. A cron job or Celery task must scan and revoke expired shares, or each share-check must evaluate expiry at access time (lazy revocation — simpler, acceptable for v1).
- **Per-document storage routing is independent of the default storage selector:** Default storage is "which backend do new uploads go to by default?" Routing is "for this specific upload, override the default." Routing is a differentiator; default selector is table stakes.
- **Admin impersonation conflicts with privacy-first model:** These two features are architecturally incompatible. Document this as an explicit decision in PROJECT.md.
- **GDPR export is async:** Exporting all user data (documents + metadata) can take minutes for large accounts. Must be a background job with "email me when ready" — not a synchronous HTTP download.
---
## MVP Definition (This Milestone)
This is a subsequent milestone — the core document + AI system exists. MVP for this milestone is everything in PROJECT.md Active section, implemented in a way that doesn't create rework.
### Must Ship (v1 — this milestone)
- [ ] Email + password registration with strength validation — table stakes, nothing works without it
- [ ] JWT sessions with refresh tokens + forced logout capability — security baseline
- [ ] TOTP 2FA with backup codes — PROJECT.md requires it; backup codes prevent lockouts
- [ ] Password reset via email — users will forget passwords
- [ ] Per-user isolated storage (MinIO prefix per user ID) — without this, multi-user is unsafe
- [ ] Quota tracking (DB) + enforcement at upload + visible indicator — table stakes for any quota system
- [ ] Quota warnings at 80% and 95% — prevents users hitting the wall blindly
- [ ] Create / rename / delete folders with breadcrumb navigation — table stakes file management
- [ ] Move document to folder (context menu minimum; drag-drop in v1.x) — without this folder structure is useless
- [ ] Sort by name/date/size — basic list management
- [ ] Global search (metadata + extracted text) — without this the product is a dumb file cabinet
- [ ] Share document with named user by handle (view-only default) — core sharing primitive
- [ ] Revoke share with immediate effect — security; users must be able to undo shares
- [ ] "Shared with me" virtual folder — PROJECT.md requires it
- [ ] Cloud storage connect flow (Google Drive + OneDrive OAuth2) — PROJECT.md requires it
- [ ] Connection status indicator + error state with local fallback — users need to know if cloud is broken
- [ ] Default storage backend selector — users need to control where uploads go
- [ ] Credential encryption (Fernet + env key) — PROJECT.md hard requirement
- [ ] Admin: user list, create, deactivate, quota adjustment — PROJECT.md requires it
- [ ] Admin: AI provider/model assignment per user + system default — PROJECT.md requires it
- [ ] Audit log (append-only): auth events + data events — PROJECT.md requires it
- [ ] Admin audit log viewer with date/user/action filters — PROJECT.md requires it
- [ ] In-browser PDF preview (PDF.js or native) — without preview, users must download to read
- [ ] Document metadata panel (size, date, topics, storage backend) — contextual information users expect
### Add After Core Validated (v1.x)
- [ ] Share expiry date — valuable for security-conscious users; requires background job
- [ ] Explicit share accept/decline — adds trust; low complexity
- [ ] "What I've shared" global list in settings — users need to audit their shares
- [ ] In-app share notification — without email infrastructure, in-app is the fallback
- [ ] Storage usage breakdown by folder — power user feature; quota bar is sufficient at v1
- [ ] CSV export of audit log — compliance teams want this; not day-one critical
- [ ] Log retention policy configuration — needed for GDPR compliance; default 1yr is fine for v1
- [ ] Drag-and-drop document move — UX polish; context menu is the functional minimum
- [ ] "Recent documents" virtual view — convenience; not blocking
### Future (v2+)
- [ ] GDPR data export (Article 20) — required eventually; complex (async job); defer until user base exists
- [ ] Per-document storage routing (override default per upload) — strong differentiator but complex; v2
- [ ] User-facing activity log (own audit trail) — GDPR-aligned trust feature; v2
- [ ] Soft-delete / Trash with restore — adds quota accounting complexity; solve properly in v2
- [ ] Document version history — storage-intensive; needs a clear retention policy first
- [ ] SSO / SAML — per PROJECT.md, after subscription billing
- [ ] Public link sharing — per PROJECT.md, explicitly out of scope for v1
- [ ] Platform health dashboard at /admin/health — operational convenience; Docker healthchecks handle v1
---
## Feature Prioritization Matrix
| Feature | User Value | Implementation Cost | Priority |
|---------|------------|---------------------|----------|
| Per-user auth (registration, login, JWT) | HIGH | LOW | P1 |
| TOTP 2FA + backup codes | HIGH | MEDIUM | P1 |
| Password reset | HIGH | LOW | P1 |
| Quota tracking + enforcement + indicator | HIGH | LOW | P1 |
| Quota warnings (80%, 95%) | HIGH | LOW | P1 |
| Folder CRUD + breadcrumb | HIGH | LOW | P1 |
| Move document to folder | HIGH | LOW | P1 |
| Global search | HIGH | MEDIUM | P1 |
| Share with named user (view-only) | HIGH | MEDIUM | P1 |
| Revoke share | HIGH | LOW | P1 |
| "Shared with me" folder | HIGH | LOW | P1 |
| Cloud connect flow (OAuth2) | HIGH | HIGH | P1 |
| Connection status + error state + local fallback | HIGH | MEDIUM | P1 |
| Default storage selector | HIGH | LOW | P1 |
| Credential encryption | HIGH | MEDIUM | P1 |
| Admin user management (list/create/deactivate/quota) | HIGH | LOW | P1 |
| Admin AI config | MEDIUM | LOW | P1 |
| Audit log (append-only) | HIGH | MEDIUM | P1 |
| Admin audit log viewer | MEDIUM | MEDIUM | P1 |
| In-browser PDF preview | HIGH | MEDIUM | P1 |
| Document metadata panel | MEDIUM | LOW | P1 |
| Forced logout / session revocation | MEDIUM | MEDIUM | P2 |
| Share expiry date | MEDIUM | MEDIUM | P2 |
| Explicit share accept/decline | MEDIUM | LOW | P2 |
| "What I've shared" list | MEDIUM | LOW | P2 |
| Storage usage breakdown by folder | MEDIUM | MEDIUM | P2 |
| CSV export of audit log | MEDIUM | LOW | P2 |
| Log retention policy | MEDIUM | LOW | P2 |
| Drag-and-drop move | MEDIUM | MEDIUM | P2 |
| Recent documents view | LOW | LOW | P2 |
| Per-document storage routing | HIGH | HIGH | P3 |
| GDPR data export | MEDIUM | HIGH | P3 |
| Soft-delete / Trash | MEDIUM | HIGH | P3 |
| User-facing activity log | MEDIUM | LOW | P3 |
| Document version history | LOW | HIGH | P3 |
| Platform health dashboard | LOW | MEDIUM | P3 |
---
## Competitor Feature Analysis
| Feature | Google Drive | Dropbox | Box | Paperless-ngx | DocuVault Plan |
|---------|--------------|---------|-----|----------------|----------------|
| Share by named user | Yes (email) | Yes (email) | Yes (email + internal) | No (single-user) | Yes (by handle) |
| Share permission levels | View / Comment / Edit | View / Edit | View / Edit / Co-owner | N/A | View-only v1; edit later |
| Share expiry | Google Workspace only | Business+ only | Business+ free tier | N/A | Include in v1.x — differentiator at free tier |
| Public link sharing | Yes | Yes | Yes | No | Explicitly excluded v1 |
| Quota indicator | Yes (prominent) | Yes | Yes | N/A (local disk) | Yes — progress bar + text |
| Quota warnings | Yes (email at 80%) | Yes (email at 90%) | Yes | N/A | In-app banner at 80%, 95% |
| Folder organization | Yes (arbitrary depth) | Yes | Yes | Yes | Yes (arbitrary depth) |
| Drag-and-drop move | Yes | Yes | Yes | Yes | v1.x (context menu at v1) |
| Global search | Yes (full-text) | Yes (full-text) | Yes (full-text) | Yes (extracted text) | Yes (extracted text — already extracted) |
| AI classification | No (manual labels) | No | No | Basic rules-based | Yes — core differentiator |
| Audit log (admin) | Google Workspace | Business+ | All tiers | No | Yes — all tiers |
| TOTP 2FA | Yes | Yes | Yes | Yes | Yes |
| Backup codes | Yes | Yes | Yes | Yes | Yes — required with TOTP |
| Bring-your-own storage | No | No | No | Partially (local FS) | Yes — core differentiator |
| Privacy-first admin model | No (Google can read) | No | No | N/A (self-hosted) | Yes — core differentiator |
| In-browser PDF preview | Yes | Yes | Yes | Yes | Yes (PDF.js) |
| Document version history | Yes | Yes (30 days free) | Yes (30 days free) | No | v2 |
| GDPR data export | Yes (Google Takeout) | Yes | Yes | N/A | v2 |
---
## Critical UX Patterns to Follow
### Quota UX (from Drive / Dropbox study)
**Sidebar quota bar pattern** (Drive): Always-visible storage indicator at the bottom of the left sidebar. Shows "X.X MB of Y MB used" with a color-coded bar (green → yellow → red as quota fills). This is the pattern users are conditioned to expect.
**Upload rejection UX**: Never show a generic error. Show: current usage, quota limit, how much the rejected file would have added, and a direct link to storage settings. Dropbox does this well; many self-hosted tools fail here.
**Quota warning banner**: Non-modal, dismissable, but persistent. Appears at 80% — amber. At 95% — red. At 100% — blocks upload with inline error (not just a banner).
### Folder UX (from Drive / Explorer pattern)
**Breadcrumb is mandatory**: Any folder deeper than one level without a breadcrumb creates navigation confusion. Users instinctively hit "back" in their browser and are surprised to leave the app.
**Empty folder state**: Show a clear empty state ("This folder has no documents yet. Upload one to get started.") — not a blank white space.
**Delete folder confirmation must list contents**: "Are you sure? This will permanently delete 47 documents." — not just a generic "are you sure?"
### Sharing UX (from Box / Drive)
**Share dialog anti-pattern to avoid**: Auto-sending share notifications without preview. Drive's "A notification will be sent" with an optional message is the correct pattern — user controls whether to notify.
**Shared document visual indicator**: An icon overlay (people icon) in list view on shared items. Without this, users lose track of what they've shared. Drive and Box both do this.
**Revoke is immediate and feedback is given**: "Access revoked for user@handle" toast. Not silent.
### Cloud Integration UX (from Dropbox Business / Google Drive)
**Connection health must be persistent**: Don't only show errors at connect time. Show ongoing status in storage settings. A disconnected cloud backend that silently fails uploads is a data-loss scenario.
**Token expiry is silent without handling**: OAuth2 tokens expire. If the app doesn't handle refresh silently (or at least alert the user clearly), users will think their uploads succeeded when they didn't. **This is a critical pitfall.**
---
## What We Might Miss (Gap Analysis)
Items that competitors have which aren't in PROJECT.md Active requirements and are easy to overlook:
1. **Backup codes for TOTP** — PROJECT.md mentions TOTP but not backup codes. Without backup codes, a lost phone = permanently locked-out account. Every 2FA implementation must include these. HIGH severity omission.
2. **Quota warning thresholds** — PROJECT.md says "quota enforced; uploads rejected." It doesn't mention pre-emptive warnings at 80%/95%. Users who hit the wall without warning give negative reviews. Easy to implement; easy to forget.
3. **Session revocation / forced logout** — Not in PROJECT.md. JWT-based auth has no built-in revocation. If a user believes their account is compromised, they need "sign out everywhere." Requires either short-lived JWTs + refresh token table, or a server-side revocation list.
4. **Breadcrumb navigation** — Easy to forget in folder implementation. The folder CRUD is in PROJECT.md but the navigation UX isn't. Without breadcrumbs, nested folders become unusable.
5. **"What I've shared" list** — PROJECT.md covers sharing mechanics but doesn't cover share auditability from the sharer's perspective. Users who've shared many documents need a way to manage them all.
6. **Upload error when cloud backend is unreachable** — PROJECT.md says "documents stored in cloud backend accessed via app." What happens if the cloud backend is down at upload time? Needs explicit handling: local fallback with a flag, or queue with retry, or reject with explanation. Silence = data loss.
7. **MinIO presigned URL vs proxy for document access** — Not a feature gap but an architecture gap that affects features: if documents in cloud backends are accessed via presigned URLs, the URL leaks the storage path. If proxied through the app, privacy is preserved but adds load to the backend. For a privacy-first platform, proxy is the correct choice — but it must be a conscious decision before the cloud integration is built.
8. **Empty folder state and confirmation dialogs** — Micro-UX that competitors all get right. Easy to skip in implementation. Users notice.
9. **Shared document icon in list view** — Small visual indicator but prevents users from losing track of what they've shared. Three lines of CSS; easy to miss in sprint planning.
10. **Admin cannot set quota below current usage without warning** — Obvious in hindsight but easy to leave as a silent truncation. Must warn and require explicit confirmation.
---
## Sources
- Google Drive feature set: training knowledge through Aug 2025 (stable, well-documented product)
- Microsoft OneDrive feature set: training knowledge through Aug 2025
- Dropbox feature set: training knowledge through Aug 2025
- Box feature set: training knowledge through Aug 2025 (enterprise DMS reference)
- Notion: training knowledge through Aug 2025 (organization patterns)
- Paperless-ngx: training knowledge through Aug 2025 (self-hosted DMS reference — open source, well-documented)
- DocuWare: training knowledge through Aug 2025 (enterprise DMS reference)
- Web fetch and web search unavailable during this research session; confidence reduced to MEDIUM for specific UI detail claims; HIGH for feature existence claims (these are all mature, stable platforms)
---
*Feature research for: DocuVault — SaaS Document Management Platform*
*Researched: 2026-05-21*