Demo content from demo/developer-guide (0c17989)
This commit is contained in:
parent
e7b15ff117
commit
4e32950ceb
12 changed files with 676 additions and 2 deletions
65
principles/index.md
Normal file
65
principles/index.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
id: principles
|
||||
title: Principles
|
||||
description: The four rules that shape f451's design, and why they exist.
|
||||
tags: [architecture, principles]
|
||||
lang: en
|
||||
---
|
||||
|
||||
# Principles
|
||||
|
||||
Four rules recur throughout the codebase. They are not style preferences —
|
||||
each one closes off a class of bugs or design mistakes that the project has
|
||||
already made once.
|
||||
|
||||
## Git is the source of truth, Postgres is only an index
|
||||
|
||||
Every space is a Git repository; every page is a Markdown file with
|
||||
frontmatter. Postgres holds the rendered content, the search vector, the
|
||||
knowledge-graph edges, sessions and encrypted provider tokens — nothing
|
||||
that can be derived from Git is allowed to live *only* in the database.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Losing `pg-data` is recoverable: `POST /admin/reindex` or the drift job
|
||||
> rebuilds the index from Git. Losing `forgejo-data` is not — that is the
|
||||
> one thing backups exist for. If you find yourself adding a column that
|
||||
> holds information not derivable from the Git content, stop and ask
|
||||
> whether it belongs in Git instead.
|
||||
|
||||
## Permissions come from the Git provider
|
||||
|
||||
f451 has no role system of its own. Whether someone can see a space or
|
||||
write to it is decided by their permissions on the underlying repository.
|
||||
Writers always write with **their own** provider token — the API never
|
||||
commits under a service account. Without a linked provider account, every
|
||||
write attempt fails with 403; that is a precondition, not a bug.
|
||||
|
||||
This also shapes how "not found" behaves: a `404` deliberately means
|
||||
*"doesn't exist, or you don't have access"* — never distinguish the two.
|
||||
Doing so would let an unauthorized caller learn that a page exists, which
|
||||
is exactly the kind of existence oracle this design avoids.
|
||||
|
||||
## Writing always goes through the review workflow
|
||||
|
||||
There is no route that writes directly to the published version — not for
|
||||
people, not for agents. The path is always: create a draft (a branch) →
|
||||
write → open a review (a pull request) → approve (merge) → reindex.
|
||||
|
||||
Draft routes carry a SHA contract: whoever writes names the `baseSha` of
|
||||
the version they started from. If the content has changed underneath them,
|
||||
they get a `409` back with the current state instead of a silent
|
||||
overwrite. See [[api]] for the routes that implement this.
|
||||
|
||||
## Diagrams carry their own source
|
||||
|
||||
`.drawio.svg` and `.excalidraw.svg` files under `<page folder>/_media/` are
|
||||
plain SVGs that also carry the diagram's source XML in a `content`
|
||||
attribute. One file is both the picture people see and the thing the
|
||||
diagram editor reopens. The SVG sanitizer keeps that attribute and the
|
||||
wrapping text elements deliberately — stripping either would make the
|
||||
diagram unreadable or unopenable.
|
||||
|
||||
> [!TIP]
|
||||
> These four rules are the first thing to check when a design choice looks
|
||||
> surprising: it is very likely a direct consequence of one of them, not an
|
||||
> arbitrary decision.
|
||||
Loading…
Add table
Add a link
Reference in a new issue