Files
website/docs/plant-tracker.md
Stan Runge e24ee7f95d
All checks were successful
Deploy production / deploy (push) Successful in 1m19s
plant: private Cargill Gouda tracker (/trackers/cargill)
Owner-only tracker for learning the Cargill Bioindustrial plant in Gouda:
schema plant (entries, links with confidence, pending refs), plant.apply_entries
bulk import, overview with clusters and flow diagram, kind tabs, glossary,
questions, detail pages and owner inline editing. Docs in docs/plant-tracker.md.
2026-10-26 13:42:37 +00:00

82 lines
4.1 KiB
Markdown

# Plant tracker (`/trackers/cargill`)
A private (owner-only) knowledge base about the Cargill Bioindustrial plant in Gouda:
departments, products, process steps, equipment, glossary terms, questions, notes and roles
(never colleague names). Logged-out visitors get a 404 on the page, its data and its actions
(`ownerOnlyPrefixes` in `src/lib/server/owner.ts`).
## Schema `plant` (migration `drizzle/20261026133106_plant`)
- `plant.entries`: `kind`, `slug` (unique per kind), `title`, `summary`, `body` (markdown),
`parent_id` (any kind, e.g. a note under a note), `tags`, `sort_order`, `source`,
`confidence` (`confirmed` | `assumed` | `open`), `answered_at` (questions), timestamps.
- `plant.links`: `from_id`, `to_id`, `relation` (`feeds_into`, `made_in`, `uses`, `part_of`,
`related`), optional `label`, `dashed`, `confidence` (default `confirmed`; `assumed` or
`open` links show dashed in the flow and with a "?" badge on entry pages).
- `plant.pending`: parents and links whose target doesn't exist yet. Every `apply_entries` run
retries them, so a later batch that adds the target resolves them. Entry pages list them as
"pending".
Kinds: `department`, `product`, `process_step`, `equipment`, `glossary`, `question`, `note`,
`person_role`.
How tags drive the UI:
- `cluster` (departments): a section in the departments tab and a card in the overview, with
every unit below it (units with `parent: "cluster-ea"`, and their own units, like MP1's).
- `inactive`: dimmed everywhere; the "hide inactive" switch hides them (off by default).
- `overview` (notes): shown at the top of the overview.
## Bulk import: `plant.apply_entries(jsonb)`
Upserts by `(kind, slug)`, then sets parents and links by slug. Run it as the app user or the
owner; for big files pipe SQL through stdin, e.g.
`select plant.apply_entries($doc$ { ... } $doc$::jsonb);`
The argument is either an object `{ "source": ..., "entries": [...], "links": [...],
"delete": [...] }` or a bare array of entries.
```json
{
"source": "Walter White, batch 5 (2026-10-26)",
"entries": [
{
"kind": "department",
"slug": "414-kolom-1",
"title": "414 Kolom 1",
"summary": "Fat splitting column, continuous",
"body": "In and out:\n- In: feed, water and high-pressure steam.\n- Out: fatty acid and glycerine water.",
"parent": "cluster-dim",
"tags": ["splitting", "continuous"],
"confidence": "confirmed",
"links": [{ "to": "splitting", "relation": "uses", "label": "optional" }]
},
{ "kind": "question", "slug": "rndm", "title": "What is RNDM?", "tags": ["answered"] }
]
}
```
- Required: `kind`, plus `slug` or a `title` to slugify; new entries need a `title`.
- Optional: `summary`, `body`, `parent` (alias `parent_slug`; `null` clears it), `tags`,
`confidence` (default `assumed`, `open` for questions), `sort_order`, `source`, `answered`,
`replace_links`, `replace_tags`, `body_mode` (`"append"`), `links` (`to`, `relation`,
`label`, `dashed`, `confidence`, `remove`).
- Updating an existing entry:
- Keys that are left out keep their current value. An empty `summary` or `body` also keeps
the current text. With `"body_mode": "append"` the new body is added below the current
one (skipped when it is already there) instead of replacing it.
- `tags` are merged into the existing tags, unless the entry sets
`"confidence": "confirmed"` or `"replace_tags": true`, which replace them.
- The top-level `source` is only the default for new entries; pass `source` on an entry to
overwrite it.
- A question tagged `answered` (or with `"answered": true`) is marked answered; the tag is
dropped.
- References (`parent`, `to`, `from`) are a slug or `kind:slug`. A bare slug used by several
kinds resolves in this order: process_step, product, department, equipment, note,
question, person_role, glossary (so `splitting` is the process step).
- Unknown references never abort the import: they are listed in `unresolved` and kept in
`plant.pending` until their target exists.
Returns `{ inserted, updated, linked, unlinked, deleted, unresolved: [{from, field, to}],
resolved_pending, pending, entries: [{id, kind, slug, action}] }`.