Documents + Inline Editing

The fortieth firewall takes as long as the first.

Documents are built from doc types: an ordered set of typed fields. Values are keyed by field id, never by label, so a label can change without touching a single document. And when the template is missing something, you add it from where you are standing.

The hierarchy

Company → Location → Document.

A doc type's scope decides where its documents live. A Domain or a Microsoft 365 tenant belongs to the company; a firewall, a circuit, or a printer belongs to a location. The company page lists its locations and its documents grouped by type, and the sidebar is nothing but your documentation.

Fields that name something shared across clients, a registrar, an internet provider, a firewall vendor, are dropdowns on an instance-wide list. Fields that name that client's own record, which circuit a firewall sits on, are links to the document. Lists are editable inline with the +, and what you add is there for every company afterwards.

Field types
text / url / ip

Plain strings. IPs are validated; URLs open in a new tab from view mode.

markdown

TipTap editor, stored as markdown source, rendered on read. VLAN tables, backup notes, the long tail.

richtext

Stored as HTML, sanitized server-side on every write.

number / date / boolean

Typed, formatted in the reader's locale, never a free-text date.

dropdown / multi_dropdown

Draws from a shared option list. The + beside the select adds an option for every company after.

doc_link

Points at a document of a named type. Written to document_links, so the target shows backlinks.

secret_ref

A reference into your vault plus cached non-secret metadata. The value is fetched live on reveal.

Inline editing

Never leave the document to fix the template.

This is the whole point of the project. A tech documenting a switch finds the template has no field for the PoE budget. Adding one is a button in the document, not a trip to admin, and promoting it to the template is the next button.

  1. 1

    Edit mode shows every field of the document: template fields first, then local fields, in the order you set.

  2. 2

    "Add field" in edit mode creates a local field on that document. Nobody has to open admin.

  3. 3

    Each local field has "Add to template". Promoting asks once: confirm the label, type, and option list. One UPDATE; every existing document of that type gets the new empty field.

  4. 4

    Dropdowns show a + next to the select. Adding an option writes to the shared list and selects it.

  5. 5

    A drag handle on every field. Reordering a template field asks: this document only, or update the template.

  6. 6

    Archiving a field hides it everywhere; values stay in JSONB so old revisions still render. Nothing is hard-deleted.

  7. 7

    Every save writes a revision and an audit entry, and queues webhooks.

Edit mode on a Switch document, adding a local field named PoE Budget
Add a local field from edit mode. Promote it to the template when the third switch needs it too.
A dropdown with the add-option control open, typing a new firewall vendor
The + beside a dropdown writes to the shared list and selects the new option.
Links and backlinks

The ISP knows which firewall sits on it.

A doc_link field points at a document of a named type. The firewall's WAN links to the ISP document; the printer's supplies vendor links to the Vendor document. Every link is written to a links table, so the target shows what points at it, and a search for the circuit id finds the firewall too.

Global search is a Postgres tsvector over every document, scoped to the companies the reader may see. No Elasticsearch, no Meilisearch, no second service to back up.

Starter doc types

Set SEED_ON_START=true and the first boot loads a pack with the option lists it needs. Edit them, archive them, or start from nothing.

VendorISPFirewallSwitchWi-FiPrinterServerRackDomain/DNSM365/Google Tenant
# Firewall (location scope)
Make dropdown: Firewall Vendors
Model text
Serial text
Firmware text
LAN IP ip
WAN doc_link → ISP
Admin URL url
Credentials secret_ref
Notes markdown

Revisions on every save

A revisions page per document. Archived fields keep their values in the JSONB, so a revision from before the archive still renders whole.

Review schedules

A date that arrives once, or a job that comes round, each with a lead time. Marking a recurring job done rolls forward from the date that was due, so lateness never compounds.

Per-company export

JSON and Markdown from the company page or the API, for reading and handover. A client leaving takes their documentation with them, in a form they can read.

Ready to document something?

One compose file, no required services beyond Postgres. Read the docs, or take the next feature for a spin.