Governing documents (org-side)
The Documents module is the home for governing documents: constitutions, bylaws, standing rules, policy memos, and other reference material a chapter or organization needs to keep at hand. Org admins author and upload from the org Documents page; chapter officers can edit chapter-scoped documents from the chapter Documents page.
This page describes what org admins can do here — document categories, the three visibility tiers, version history and rollback, full-text search, external-link documents, the approval workflow, and the limits of the current implementation.
The org Documents page
From the org sidebar, open Documents. The page is split into two sections:
- National Documents — documents created without a chapter assignment. These belong to the org as a whole.
- Chapter Documents — documents scoped to a specific chapter, grouped by chapter. Every chapter that has at least one document gets a sub-section.
A search bar and a visibility tier filter sit at the top of the page. The visibility filter defaults to "All Visibility." There is no category filter here — each document's category shows as a badge on its row (see Document categories below), but category isn't yet a filter control on this page.
Document categories
Documents are organized by an org-configurable category — a DocumentCategory record — instead of a fixed type field. Every organization is seeded with 6 default categories when it's created:
| Category | Use for |
|---|---|
| Constitution | Founding document, governance structure, fundamental rules |
| Bylaws | Operational rules, officer responsibilities, meeting procedures |
| Standing Rules | Recurring rules of order, voting thresholds, committee charters |
| Policy | Specific policies — risk management, social events, alcohol, dress code |
| Manual | Operational manuals and handbooks |
| Other | Everything that doesn't fit the categories above |
These are only the starting defaults — categories are fully org-configurable. Manage them from Settings → Document Categories (also reachable directly at /org/document-categories):
- Add Category creates one with a name and an optional description.
- Edit changes a category's name or description.
- Deactivate / Activate hides a category from the picker on new and edited documents without deleting it or touching documents already filed under it — deactivated categories still display normally wherever they're already assigned.
- Delete permanently removes the category. Documents filed under it aren't deleted — their
categoryfield is cleared and they show as uncategorized. - ↑ / ↓ buttons on each row reorder the list (
display_order). There's no drag handle — reordering is up/down-arrow only.
Category is optional on both the create and edit forms — a document with no category shows a "—" badge instead of a name.
Visibility tiers
The most important admin decision per document is the visibility tier. There are three:
| Tier | Who can read |
|---|---|
| Public | All members of the organization, regardless of chapter or role |
| Chapter | Members of the specific chapter the document is scoped to |
| Officers | Chapter officers and chapter presidents of the scoped chapter, plus org admins |
Visibility is enforced on every read. A member browsing the chapter Documents page sees only documents whose visibility includes them — public documents from the org, chapter-tier documents for their chapter, and officer-tier documents if they have an officer or president role in that chapter.
Org admins and regional admins always see everything in scope (org-wide for org admins; their region's chapters for regional admins).
When chapter is required
If you set a document to Chapter visibility, you must pick a chapter. The platform refuses to save without one — the visibility tier wouldn't have anything to scope to.
Public documents can be org-wide or chapter-scoped. A chapter-scoped public document is still visible to all org members (visibility is the dominant control) but is filed under the chapter.
Officers visibility ties the document to a specific chapter — only officers of that chapter can see it. Use for internal financial memos, incident reports, or anything not yet ready for general membership.
Uploading and content
There are two ways to put content into a document:
- Inline content. Type the body directly into the content textarea on the create form. This is the easy path for short policies, standing rules, and anything that's primarily prose.
- File attachment. Upload a PDF, DOCX, or similar file. The platform stores the file and tracks its filename, size, and MIME type. Members open the file from the document detail dialog.
The two are not mutually exclusive — a document can have both inline content (a summary or table of contents) and an attached file (the full document).
File downloads (v0.63.16+)
A Download button now renders on the document detail dialog whenever doc.file is set. It opens /api/documents/<id>/download/ (the existing DocumentFileDownloadView proxy endpoint) which serves the file with its original filename. Both the org-side DocumentDetailDialog and the chapter-side DocumentReadDialog use the same button. Member access is gated by visibility — only members allowed to read the document can download it.
The chapter Documents table also picks up a VisibilityBadge column (Public / Chapter / Officers Only) matching the org-side, so officers can tell at a glance who can see each document.
External link documents (v0.63.41+)
There's a third way to provide a document, alongside inline content and file attachment: an external link. Use this when the document already lives in Google Drive, SharePoint, or anywhere else with a shareable URL, and you don't want to also upload a duplicate copy.
On the create/edit form, an Attachment toggle switches between Upload File and External URL modes — they're mutually exclusive. The platform refuses to save a document with both a file and an external URL set. In External URL mode, paste the link (e.g. https://docs.google.com/...) into the URL field.
A document with an external link renders differently from a file-attached one: instead of a Download button, the detail dialog shows an outlined button with an external-link icon that opens the URL in a new tab. Its label adapts to the destination:
- Open in Drive — if the URL's hostname contains "google"
- Open in SharePoint — if the hostname contains "sharepoint" or "microsoft"
- Open External Link — any other URL
External-link documents can still carry inline content — a summary or notes on what's in the linked file. The external URL only replaces the file attachment slot, not the content textarea.
Search
A dedicated search bar (v0.63.41+) sits at the top of the page next to the visibility filter, placeholder "Search documents…". Typing debounces for 300ms before it fires a search — no need to press Enter — and an X button appears once you've typed something, to clear the query.
This is real full-text search, not a substring filter: it runs against a PostgreSQL tsvector column (title weighted higher than content, via a GIN index) and ranks results with ts_rank. It matches word stems and handles multi-word queries the way a search engine would, not just exact character sequences.
What it indexes: the document's title and inline content field only. Uploaded file bodies (PDF, DOCX, etc.) are not parsed or indexed — a file-only document with no inline content is only findable by title.
Chatbot search — a separate surface
The AI Services chatbot also answers document questions ("what do our bylaws say about quorum?"). This is independent of the search bar above and uses its own lookup path:
- It tries semantic similarity first, if AI embeddings are configured for the org (see AI Services content scope).
- If there's no strong semantic match, it falls back to case-insensitive substring matching on the title and inline content fields.
The same indexing limit applies here too: PDFs and DOCX files attached to documents are NOT searched for content by the chatbot either — only their titles. If you want a document discoverable by search or the chatbot, paste the key text into the inline content field.
Version history
Every document has a versions collection. Saving an edit that changes the title or the inline content snapshots the outgoing content into a new DocumentVersion row, recorded with a version number, the user who made the change, and a change summary ("Edited," or "Approved edit" when the change came through the approval workflow described below).
The current document state is always the "latest" — when you open a document, you see the most recent version inline. Earlier versions are visible via the Versions (N) button on the detail dialog, which expands a list showing each past version's number, date, and editor.
A few facts to know:
- Versions track content and title, not files. Any save that changes the title or the inline content creates a version row (the row itself only stores the content text). Replacing the attached file does not create a version — file history isn't tracked.
- Version numbers monotonically increase. Version 1, 2, 3, and so on — never reused.
- Rollback is real, and one step deep (v0.63.41+, reliably populated since v0.63.53). The same edit that writes a version also records a single "previous revision" snapshot. If one exists, a View previous version button appears next to Versions. It opens a Previous Version dialog showing any title change plus a line-level, color-coded diff of the content (additions in green, removals in red). From there, a Restore previous version button — visible if you can edit the document — reverts the title and content to that snapshot, then clears it. That means you can only roll back the most recent edit this way, not several edits back; to recover something further back, open the Versions list and copy the older content into a fresh edit.
Flat model — no folders
The Documents module is intentionally flat. Documents are organized by:
- Visibility tier (public / chapter / officers)
- Category (Constitution / Bylaws / Standing Rules / Policy / Manual / Other, or a custom category — see Document categories)
- Chapter scope (org-wide or assigned to a specific chapter)
There is no folder hierarchy. You cannot create "Policies → Risk Management → Social Events" as a path; everything is filed at the top level, and the only filter control on the page is by visibility (see Search for finding a document by keyword instead).
For organizations with hundreds of documents, this becomes a navigation challenge. The common workaround is to encode a path in the document title ("Risk Mgmt - Social Events Policy") and rely on the search bar and category badges for discovery. If you find yourself wanting folders, you're hitting a known limit of the current design.
The approval workflow (requires_approval)
requires_approval is a real, working staged-edit workflow, not a placeholder. Turn it on per document with the "Require approval to publish edits" toggle on the create/edit form. Once it's on, every subsequent edit to that document's title or content is staged instead of applying immediately:
- The edit is written to the document's
staged_contentfield (title, content, who proposed it, and when) and a pendingDocumentApprovalrecord is created. The document's visible title and content don't change yet. - A document with a pending edit shows a "Pending approval" badge — next to its title in the document table, and in the detail dialog header.
- The submit button reads "Submit for Approval" instead of "Save Changes" whenever the toggle is on, so it's clear the edit won't go live immediately.
- National admins review pending edits from the Approval Queue — a button in the header of the org Documents page (next to the page title), which links to
/org/document-approvals. The queue lists each pending item's document title, submitter, and submission date, with Approve and Reject buttons per row; acting on either opens a confirmation dialog with an optional notes field.- Approve records the outgoing content as a new version, then publishes the staged title/content and clears the staged edit.
- Reject discards the staged edit and clears it — the document is left untouched.
The Approval Queue button only became reachable from the UI in v0.63.53 — the staging/approve/reject backend existed since v0.63.41, but before v0.63.53 nothing in the product linked to the queue page.
The is_current flag — removed, not just unused
The earlier Is current flag isn't a dormant field anymore — it was removed from the model entirely. It used to be a boolean nothing ever set to False (no archive action existed anywhere in the UI), so it was permanently True and useless; the column itself has since been dropped. There's no is-current toggle, no archived state, and no Current/Archived badge anywhere in the Documents module — every governing document you see is simply the current one.
Deleting
Org admins delete documents via the trash icon on the document row. Deletion is permanent — no recycle bin, and version history is removed alongside the document. The attached file is also removed from storage. Any link to the document from a forum post, bulletin, or chatbot conversation will dead-end.
The safer alternative for outdated content is to edit the document — replace the body with a note that it's been superseded, optionally linking to the replacement. This preserves the history and the URL.
Notification on document publish
Members are not notified when a document is created or edited. The Documents module does not push notifications today. If you publish an important policy update, send a bulletin or in-app announcement to direct members to it.
Related
- AI Services content scope — when documents are indexed for chatbot search
- Module enablement — the Documents module is core and always available
- Chapter documents (officers) — the officer-side perspective on editing chapter-scoped docs
- Permissions matrix
Last verified against v0.65.23 (2026-07-05). Download button + visibility badge shipped v0.63.16; org-configurable categories + full-text search + external links + version rollback shipped v0.63.40/41; the approval queue became reachable and version history started accumulating real rows in v0.63.53.