A listing is a view of an entry
The entry resolves; the listing reads
Keeping them apart means the fields a reader sees can be rewritten, reviewed and withdrawn without touching the row that the category tree, the index and the record all point at. It also means a listing can be removed while its entry survives, which is what has to happen when copy is wrong but the listed thing still exists.
Fields the listing owns
| Field | Shape | Written by |
|---|---|---|
| headline | one line, no punctuation that a slug cannot carry | holder |
| body | plain paragraphs, no embedded markup, no links out | holder |
| category path | the path as filed, stored as identifiers not names | holder, confirmed in the queue |
| contact route | one route, inherited from the entry unless overridden | holder |
| review stamp | when a moderator last looked, and which moderator role | the queue |
| state | one of five, moved only by a recorded transition | holder or moderator, per the moves below |
No markup, no links out. Markup in a listing body is a surface nobody specified, and links out of a listing are the first thing a portal gets used for by anyone who is not interested in being listed.
Five states, and every permitted move
- 01Draft — the holder is writing. Visible to the holder alone, not indexed, no address.
- 02Submitted — in a queue. Still not indexed. The holder may pull it back to draft.
- 03Published — it has an address and it is indexed. Only a moderator puts a listing here.
- 04Withdrawn — the holder has taken it down, or a moderator has. The address answers with an explanation, not an error.
- 05Removed — a moderator has ended it against a reason code. The holder cannot resubmit without the code being addressed.
An edit against a published listing creates a submitted revision beside the published copy; the published copy stays exactly as it is until the revision is accepted. Readers therefore never meet a listing mid-rewrite, and a rejected revision costs nobody their live copy.
Removal is not deletion. The row stays, the state says removed, the reason code is on it and the record carries the transition. Deleting it instead would leave an address that answers with nothing and a queue with no account of why.