Drive — Product Specification
1. Overview
What is Drive?
Drive is the organization's centralized file storage app. It lets every member of an organization upload, organize, and share files — with access controlled by their role. All files are scoped to a single organization; members cannot see files from other organizations.
Why it exists
Teams today store files in email attachments, personal cloud drives, and shared folders they lose track of. Drive solves this by putting all company files in one place, under the same login users already have, with clear ownership and permissions.
Who is it for?
| Persona | What they do in Drive |
|---|---|
| Regular member | Uploads and downloads files relevant to their work |
| Team lead | Creates folders, shares files with their team |
| Admin | Manages all files and folders across the org; can delete or reassign ownership |
| Read-only user | Views and downloads files but cannot upload or delete |
2. Goals & Non-Goals
Goals ✅
- Upload, download, organize, and delete files
- Folder hierarchy (folders can be nested)
- Share a file with a secure, expiring link
- Control who can upload, delete, and share per role
- Search files by name within the organization
- Show file size, type, upload date, and who uploaded it
Non-Goals ❌
- Real-time collaborative editing (that is Document's job)
- Video streaming or media preview beyond common image types
- Cross-organization file sharing
- Public (unauthenticated) file access
3. User Stories
3.1 Upload a file
As a member, I want to upload a file to a folder, so that my team can access it.
Acceptance criteria:
- I can drag and drop or click to select a file
- Supported formats: any (no restriction on file type)
- Maximum file size: 100 MB per file
- Upload shows a progress indicator
- After upload, the file appears in the current folder immediately
- If the upload fails, I see a clear error message with a retry option
3.2 Organize with folders
As a team lead, I want to create folders and move files between them, so that files are easy to find.
Acceptance criteria:
- I can create a folder at the root level or inside another folder
- Folder names must be unique within their parent folder (case-insensitive)
- I can rename a folder I created (or any folder if I am admin)
- I can move a file from one folder to another
- Deleting a folder asks for confirmation; it also deletes all files inside it
- Folder path is visible as a breadcrumb (e.g.
Company / HR / 2025)
3.3 Download a file
As a member, I want to download a file, so that I can use it offline.
Acceptance criteria:
- Any member with
files:readpermission can download - Download starts immediately when clicking the download button
- The downloaded filename matches the original uploaded name
- Large files stream — they do not time out
3.4 Share a file with a link
As a member, I want to generate a shareable link for a file, so that I can send it to someone without giving them an account.
Acceptance criteria:
- I can generate a secure link from the file's action menu (requires
files:share) - The link expires after 7 days by default; I can set 1, 3, or 7 days
- The link works without login (public download)
- I can see all active share links for a file and revoke any of them
- After expiry, the link returns a "link expired" error — not a 404
3.5 Delete a file
As a member, I want to delete a file I uploaded, so that outdated files do not clutter the folder.
Acceptance criteria:
- I can delete files I uploaded (
files:delete+ owner) - Admins can delete any file regardless of who uploaded it
- Deletion asks for confirmation before removing
- Deleted files are permanently removed (no recycle bin in v1)
- Deleting a file also revokes all its active share links
3.6 Search files
As a member, I want to search for a file by name, so that I do not have to browse every folder.
Acceptance criteria:
- Search is available in the top bar of the Drive app
- Search matches any part of the filename (case-insensitive)
- Results show the filename, folder path, size, and upload date
- Results are scoped to my organization only
- Minimum 2 characters to trigger search
4. Business Rules
| Rule | Detail |
|---|---|
| Org isolation | A user can only see files belonging to their organization |
| Max file size | 100 MB per file |
| Share link expiry | 1, 3, or 7 days; no permanent links |
| Folder uniqueness | Folder names must be unique within the same parent |
| Delete cascade | Deleting a folder deletes all files inside it |
| Owner delete | A member can only delete their own files; admins can delete any |
| Share permission | Only users with files:share can generate share links |
| Storage quota | Enforced per subscription plan (e.g. Pro: 10 GB, Business: 100 GB) |
5. Screens & Navigation
Drive
├── / (root) All files and folders at the root level
│ ├── [folder] Drill into a folder
│ │ └── [sub-folder] Nested folders
│ └── Search results Flat list filtered by query
└── Shared Links (Admin only) View and revoke all active share linksScreen: File browser
| Element | Behaviour |
|---|---|
| Breadcrumb | Shows current path; each segment is clickable |
| New Folder button | Opens a dialog to enter folder name |
| Upload button | Opens native file picker or accepts drag-and-drop |
| File row | Name, type icon, size, uploaded by, upload date, action menu |
| Action menu | Download · Share · Move · Delete (items shown based on permission) |
| Empty state | "No files yet. Upload the first file." with upload button |
Screen: Share link dialog
| Element | Behaviour |
|---|---|
| Expiry selector | 1 day / 3 days / 7 days |
| Generated link | Read-only text input with Copy button |
| Active links list | Shows all existing links with expiry date and Revoke button |
6. Mockups
Screen A — File Browser
| Name | Size | Uploaded by | Date | Status | ||
|---|---|---|---|---|---|---|
| 📁 | 2025 | — | Jane Doe | Mar 10 | ✏️🗑 | |
| 📄 | Q1-Report.pdf | 2.4 MB | Alice Smith | Mar 15 | Shared | ⬇🔗🗑 |
| 📊 | Headcount-2025.xlsx | 854 KB | Bob Jones | Mar 12 | ⬇🔗🗑 | |
| 🖼 | org-chart-v3.png | 1.1 MB | Jane Doe | Mar 8 | ⬇🔗🗑 | |
| 📝 | Leave-Policy-2025.docx | 340 KB | Carol Lee | Feb 28 | Shared | ⬇🔗🗑 |
Screen A — File Browser: folder tree · breadcrumb · file list · action buttons
Screen B — Upload in Progress
Screen B — Upload: drag-and-drop zone · per-file progress bars · completion state
Screen C — Share Link Dialog
Screen C — Share Link: expiry selector · copy link · active links list · revoke
Screen D — Search Results
| Name | Folder | Size | Date | ||
|---|---|---|---|---|---|
| 📄 | Q1-Report.pdf | Company / HR | 2.4 MB | Mar 15 | ⬇🔗 |
| 📄 | Q4-2024-Report.pdf | Company / Finance | 3.1 MB | Jan 5 | ⬇🔗 |
| 📊 | Sales-Report-Feb.xlsx | Company / Sales | 980 KB | Mar 1 | ⬇🔗 |
| 📝 | Reporting-Guidelines.docx | Company / HR | 210 KB | Feb 10 | ⬇🔗 |
Screen D — Search: keyword highlighted in results · folder path shown · org-scoped
7. Permissions (RBAC)
| Permission | Resource | Action | Who has it by default |
|---|---|---|---|
| View & download files | files | read | All authenticated users |
| Upload files | files | upload | Member, Team Lead, Admin |
| Delete own files | files | delete | Member (own files only), Admin (any) |
| Share files | files | share | Team Lead, Admin |
| Create folders | folders | create | Member, Team Lead, Admin |
| Delete folders | folders | delete | Team Lead (own), Admin (any) |
| Manage all files | files | admin | Admin only |
Configure these in Shell → Admin → Roles → Permissions.
7. Data Model
organizations
│
├── folders (orgId, parentFolderId?, name)
│ │
│ └── files (folderId, orgId, name, size, mimeType, storagePath, uploadedBy)
│ │
│ └── share_links (fileId, token, expiresAt, createdBy, revokedAt?)
│
└── (storage quota tracked at org level)Table: folders
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
orgId | uuid | Organization scope |
parentId | uuid? | null = root folder |
name | text | Unique within parent + org |
createdBy | uuid | User who created it |
createdAt | timestamp | — |
Table: files
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
orgId | uuid | Organization scope |
folderId | uuid? | null = root level |
name | text | Original filename |
size | bigint | Bytes |
mimeType | text | e.g. application/pdf |
storagePath | text | Path on disk or S3 key — never exposed to client |
uploadedBy | uuid | User who uploaded |
createdAt | timestamp | Upload time |
Table: share_links
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
fileId | uuid | File being shared |
token | text | Cryptographically random, URL-safe |
expiresAt | timestamp | Computed from creation + TTL |
createdBy | uuid | Who generated the link |
revokedAt | timestamp? | Set on revoke; link is invalid if not null |
8. API Endpoints
Files
GET /api/files — list files in a folder
| Query | Type | Default | Description |
|---|---|---|---|
folderId | uuid? | root | Folder to list; omit for root |
q | string? | — | Search by filename (≥ 2 chars) |
limit | int | 50 | Max results |
offset | int | 0 | Pagination |
Response: { data: File[], total: number }
POST /api/files/upload — upload a file
- Content-Type:
multipart/form-data - Fields:
file(binary),folderId(uuid, optional) - Requires:
files:upload - Returns:
{ data: File }
GET /api/files/:id/download — download a file
- Requires:
files:read - Streams the file with correct
Content-DispositionandContent-Typeheaders
DELETE /api/files/:id — delete a file
- Requires:
files:delete; non-admin users can only delete own files - Also revokes all active share links for this file
- Returns:
204 No Content
POST /api/files/:id/share — create a share link
- Requires:
files:share - Body:
{ ttlDays: 1 | 3 | 7 } - Returns:
{ data: { url: string, expiresAt: string } }
DELETE /api/files/:id/share/:linkId — revoke a share link
- Requires:
files:share - Sets
revokedAton the link - Returns:
204 No Content
Folders
GET /api/folders — list folders
| Query | Type | Default |
|---|---|---|
parentId | uuid? | root |
POST /api/folders — create a folder
- Body:
{ name: string, parentId?: uuid } - Requires:
folders:create - Returns:
{ data: Folder }
PATCH /api/folders/:id — rename a folder
- Body:
{ name: string } - Requires:
folders:create(own) orfolders:delete(any)
DELETE /api/folders/:id — delete a folder and all contents
- Requires:
folders:delete - Cascades to all files and subfolders inside
- Returns:
204 No Content
Public share link
GET /api/public/files/:token — download via share link
- No authentication required
- Returns
410 Goneif expired or revoked - Streams the file directly
9. Error Responses
All errors follow the platform standard:
{
"error": {
"code": "FILE_TOO_LARGE",
"message": "File exceeds the 100 MB limit",
"status": 413
}
}| Code | Status | When |
|---|---|---|
FILE_TOO_LARGE | 413 | Upload exceeds 100 MB |
FOLDER_NAME_EXISTS | 409 | Folder name already taken in this parent |
SHARE_LINK_EXPIRED | 410 | Share link past expiresAt or revoked |
FORBIDDEN | 403 | Missing required permission |
NOT_FOUND | 404 | File or folder does not exist in this org |
QUOTA_EXCEEDED | 402 | Organization has exceeded storage quota |
10. Non-Functional Requirements
| Requirement | Target |
|---|---|
| Upload throughput | ≥ 10 MB/s on a standard connection |
| Download latency | First byte < 300 ms for files ≤ 10 MB |
| Search response | < 500 ms for org with up to 100,000 files |
| Availability | 99.9% monthly uptime (same SLA as Shell) |
| Storage backend | Local disk (dev/uat), S3-compatible object store (prod) |
| Encryption at rest | AES-256 on S3; filesystem encryption on disk |
11. Out of Scope (v1)
The following are noted for future versions:
- File versioning / revision history
- In-browser preview (PDF, image viewer)
- Recycle bin / soft delete
- Bulk operations (select multiple → delete / move)
- Storage analytics dashboard
- Webhooks on file events
12. Open Questions
| # | Question | Owner | Status |
|---|---|---|---|
| 1 | Should share links be password-protected? | Product | Open |
| 2 | What is the per-org storage quota per plan? | Product | Open |
| 3 | Do we need virus scanning on upload? | Security | Open |
| 4 | S3 bucket per org, or one bucket with key prefixes? | Engineering | Open |
| 5 | Should admins see a storage usage report per user? | Product | Open |
Related
- Drive developer guide — implementation walkthrough
- RBAC reference — how permissions are enforced
- Service Registry — how to register the app