Document — Product Specification
1. Overview
What is Document?
Document is the organization's collaborative writing and knowledge-management app. Members create, edit, and publish structured documents — policies, proposals, meeting notes, SOPs — inside the same platform they use for everything else. All documents are scoped to a single organization.
Why it exists
Teams write documents in disconnected tools: Word files emailed around, Google Docs scattered across personal accounts, Confluence licenses nobody budgets for. Document puts all of that in one place, connected to the org's RBAC and audit trail, with templates that enforce consistency and approval workflows that ensure nothing ships without sign-off.
Who is it for?
| Persona | What they do in Document |
|---|---|
| Author | Creates and edits documents; submits for approval |
| Reviewer | Reviews and approves or rejects submitted documents |
| Reader | Views published documents; cannot edit |
| Admin | Manages all documents, templates, and approval chains |
2. Goals & Non-Goals
Goals ✅
- Create and edit documents with a rich-text editor (headings, lists, tables, code blocks, embeds)
- Organize documents in a folder/space hierarchy
- Create reusable templates that pre-fill structure
- Version history — view and restore any previous version
- Approval workflow — author submits, reviewer approves or requests changes
- Full-text search across all published documents in the organization
Non-Goals ❌
- Real-time simultaneous co-editing (multiple cursors) — v1 is single-author-at-a-time
- Comments / inline annotations — v2 roadmap
- File attachments inline (use Drive for files)
- Public (unauthenticated) document access
3. User Stories
3.1 Create a document from a template
As an author, I want to create a new document from a template, so that I start with the right structure instead of a blank page.
Acceptance criteria:
- I can browse all templates in the "New Document" dialog
- Templates are grouped by category (e.g. HR, Finance, Engineering)
- Selecting a template creates a new draft pre-filled with the template's content
- I can also create a blank document with no template
- New documents are saved as Draft and visible only to me until submitted
3.2 Edit a document
As an author, I want to edit a document using a rich-text editor, so that I can write professional-looking content without knowing HTML.
Acceptance criteria:
- Editor supports: headings (H1–H3), bold, italic, underline, strikethrough
- Supported blocks: paragraph, bullet list, numbered list, table, code block, horizontal rule
- Auto-save every 30 seconds while editing; manual save via
Ctrl/⌘+S - No data is lost if the browser is closed mid-edit (draft is saved server-side)
- Word count is visible in the editor footer
3.3 View version history
As an author, I want to see all previous versions of a document, so that I can understand what changed and restore an older version if needed.
Acceptance criteria:
- Every save (manual or auto) creates a version entry
- Version list shows: version number, saved at timestamp, saved by user, word count
- I can open any version in a read-only side panel
- I can restore any version — restoring creates a new version (the old one is not overwritten)
- Version history is available for all documents I have access to
3.4 Submit for approval
As an author, I want to submit a document for approval, so that a reviewer can check it before it becomes official.
Acceptance criteria:
- I can submit a draft for review with a "Submit for Approval" button
- On submit, the document status changes from Draft to In Review
- The assigned reviewer(s) receive an in-app notification
- While In Review, the document is read-only to the author
- The author sees the current reviewer and date submitted
3.5 Approve or request changes
As a reviewer, I want to approve or reject a document, so that only complete, correct documents get published.
Acceptance criteria:
- I see a list of all documents In Review assigned to me
- I can approve a document → status changes to Published; author is notified
- I can request changes → status reverts to Draft with a required comment explaining what to fix
- I can view the full document before deciding
- I cannot edit the document — only the author can
3.6 Search documents
As a reader, I want to search for documents by title or content, so that I can quickly find what I need without browsing folders.
Acceptance criteria:
- Search bar is visible on the Document home screen
- Search matches: title (primary), body content (secondary)
- Results show document title, status badge, last updated date, author
- Only Published documents appear in search for readers; authors also see their own Drafts
- Results are scoped to my organization only
4. Business Rules
| Rule | Detail |
|---|---|
| Org isolation | A user can only see documents belonging to their organization |
| Status machine | Draft → In Review → Published; rejected goes back to Draft |
| Read-only while In Review | Author cannot edit a document that is awaiting approval |
| Template ownership | Only admins can create, edit, or delete templates |
| Version immutability | Restoring creates a new version; existing history is never deleted |
| Search scope | Readers see only Published; authors also see their own Drafts |
| Approval assignment | Each document can have one or more designated reviewers set by admin |
| Document limit | Enforced per subscription plan (e.g. Free: 20 docs, Pro: unlimited) |
5. Screens & Navigation
Document
├── Home All spaces and recent documents
│ ├── [Space] Group of related documents (e.g. "HR Policies")
│ │ └── [Document] Individual document — Draft / In Review / Published
│ └── Search results Flat list filtered by query
├── Templates Browse and select templates (admin: manage templates)
└── Approvals (Reviewer) All documents waiting for my approvalScreen: Document editor
| Element | Behaviour |
|---|---|
| Title field | Large, top-of-page; required before submit |
| Rich-text body | Full-width editor area |
| Status badge | Current status (Draft / In Review / Published) |
| Auto-save indicator | "Saved" / "Saving…" in the toolbar |
| Submit button | Visible only in Draft status; triggers approval flow |
| Version history | Side panel opens on "History" button click |
Screen: Approvals queue
| Element | Behaviour |
|---|---|
| Document list | Title, author, submitted date, days waiting |
| Quick preview | Click a row to read the document in a right panel |
| Approve button | Green; changes status to Published |
| Request changes | Orange; requires a reason comment before confirming |
6. Mockups
Screen A — Document Editor (Draft)
- Unused leave can be carried forward for a maximum of 5 days
- Leave encashment is not permitted
- Public holidays are in addition to annual leave
Screen A — Editor: toolbar · rich-text body · Draft status · Submit button · auto-save indicator
Screen B — Version History Panel
Screen B — Version History: timeline panel · version list · Restore button · current version highlighted
Screen C — Approval Queue (Reviewer)
| Document | Author | Space | Submitted | Waiting | |
|---|---|---|---|---|---|
| Leave Policy 2025 | Jane Doe | HR Policies | Mar 15 | 2 days | ApproveChanges |
| API Security Guidelines | Bob Jones | Engineering | Mar 16 | 1 day | ApproveChanges |
| Q1 Budget Summary | Carol Lee | Finance | Mar 17 | Today | ApproveChanges |
Screen C — Approvals queue: documents In Review · waiting time · Approve / Request Changes actions
Screen D — Request Changes Dialog
Screen D — Request Changes dialog: required feedback text · author notified · document returns to Draft
7. Permissions (RBAC)
| Permission | Resource | Action | Who has it by default |
|---|---|---|---|
| View published documents | documents | read | All authenticated users |
| Create & edit documents | documents | write | Author, Admin |
| Submit for approval | documents | submit | Author, Admin |
| Approve / reject documents | documents | approve | Reviewer, Admin |
| Delete documents | documents | delete | Admin only |
| Create / edit templates | templates | manage | Admin only |
| Manage all spaces | spaces | admin | Admin only |
8. Data Model
organizations
│
├── spaces (orgId, name, description)
│ │
│ └── documents (spaceId, orgId, title, status, currentVersionId)
│ │
│ ├── document_versions (documentId, content, savedBy, savedAt, wordCount)
│ │
│ └── approval_requests (documentId, submittedBy, reviewerId, status, comment)
│
└── templates (orgId, name, category, contentTemplate)Table: documents
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
orgId | uuid | Organization scope |
spaceId | uuid | Space (group) this document belongs to |
title | text | Document title |
status | enum | draft, in_review, published |
currentVersionId | uuid | FK to the latest version |
createdBy | uuid | Original author |
createdAt | timestamp | — |
updatedAt | timestamp | Last save |
Table: document_versions
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
documentId | uuid | FK to document |
versionNumber | int | Auto-incrementing per document |
content | jsonb | ProseMirror / TipTap JSON document |
wordCount | int | Computed on save |
savedBy | uuid | User who triggered the save |
savedAt | timestamp | — |
Table: approval_requests
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
documentId | uuid | FK to document |
submittedBy | uuid | Author who submitted |
reviewerId | uuid | Assigned reviewer |
status | enum | pending, approved, changes_requested |
comment | text? | Reviewer feedback when requesting changes |
decidedAt | timestamp? | When the reviewer acted |
Table: templates
| Column | Type | Notes |
|---|---|---|
id | uuid | Primary key |
orgId | uuid | Org scope |
name | text | Template display name |
category | text | e.g. HR, Engineering, Finance |
content | jsonb | Pre-filled document content |
createdBy | uuid | Admin who created it |
9. API Endpoints
Documents
GET /api/documents — list documents
| Query | Type | Default | Description |
|---|---|---|---|
spaceId | uuid? | — | Filter by space |
status | string? | — | draft, in_review, published |
q | string? | — | Full-text search (≥ 2 chars) |
limit | int | 50 | Max results |
offset | int | 0 | Pagination |
POST /api/documents — create a document
- Body:
{ title: string, spaceId: uuid, templateId?: uuid } - Requires:
documents:write - Returns:
{ data: Document }
GET /api/documents/:id — get a document with its current version content
PUT /api/documents/:id — save a new version
- Body:
{ title?: string, content: object }(TipTap JSON) - Requires:
documents:write+ author ownership or admin - Creates a new
document_versionsrow; updatescurrentVersionId - Returns:
{ data: Document }
DELETE /api/documents/:id — delete a document and all versions
- Requires:
documents:delete - Returns:
204 No Content
Versions
GET /api/documents/:id/versions — list all versions
POST /api/documents/:id/versions/:versionId/restore — restore a version
- Creates a new version with the same content as the target
- Returns:
{ data: Document }
Approvals
POST /api/documents/:id/submit — submit for approval
- Requires:
documents:submit; document must be indraftstatus - Changes status to
in_review; createsapproval_requestsrow
POST /api/documents/:id/approve — approve a document
- Requires:
documents:approve; must be the assigned reviewer - Changes status to
published
POST /api/documents/:id/request-changes — request changes
- Body:
{ comment: string } - Requires:
documents:approve - Reverts status to
draft; stores comment inapproval_requests
Templates
GET /api/templates — list all templates for the org
POST /api/templates — create a template (admin only)
PUT /api/templates/:id — update a template (admin only)
DELETE /api/templates/:id — delete a template (admin only)
10. Error Responses
{
"error": {
"code": "DOCUMENT_NOT_IN_DRAFT",
"message": "Only Draft documents can be submitted for approval",
"status": 409
}
}| Code | Status | When |
|---|---|---|
DOCUMENT_NOT_IN_DRAFT | 409 | Submit attempted on non-Draft document |
NOT_YOUR_REVIEW | 403 | Approve/reject by someone other than assigned reviewer |
DOCUMENT_LOCKED | 423 | Edit attempted while document is In Review |
FORBIDDEN | 403 | Missing required permission |
NOT_FOUND | 404 | Document or version not found in this org |
DOCUMENT_LIMIT_REACHED | 402 | Org has reached plan document limit |
11. Non-Functional Requirements
| Requirement | Target |
|---|---|
| Auto-save latency | < 500 ms to acknowledge a save |
| Search response | < 800 ms for orgs with up to 10,000 documents |
| Version storage | Stored as JSON diffs or full snapshots (whichever is smaller) |
| Availability | 99.9% monthly uptime |
| Content storage | PostgreSQL jsonb column (no separate blob store for text) |
12. Out of Scope (v1)
- Real-time multi-cursor collaborative editing
- Inline comments and @mentions
- Emoji reactions on documents
- PDF / DOCX export (v2 roadmap)
- External share links (documents are org-internal)
- Document analytics (views, time-on-page)
13. Open Questions
| # | Question | Owner | Status |
|---|---|---|---|
| 1 | Should spaces have their own RBAC, or inherit org-level roles? | Product | Open |
| 2 | Multi-reviewer approval chains — sequential or any-one-approves? | Product | Open |
| 3 | How long to retain deleted documents before purging? | Engineering | Open |
| 4 | Should we support document locking to prevent concurrent edit conflicts? | Engineering | Open |
| 5 | Do we need document-level analytics (views per doc)? | Product | Open |
Related
- Document developer guide — implementation walkthrough
- RBAC reference — how permissions are enforced
- Drive spec — file storage companion app