pf_app
Every question about a part -- what values exist, what attributes go with one -- was answered by querying the source, and the source is the wrong place to ask. It is a view over a transaction table, so the query is slow (76s for one ILIKE against 6.9M rows), it describes only what was transacted, and it cannot express intent: there is no way to say a part is discontinued, or to name one that has not sold yet. pf.dim_member holds the app's own list: one row per key value per group, siblings in jsonb, keyed on (source_id, dim_group, key_value). Refresh is a merge rather than a replace, so curation survives it -- members absent from the source are marked source_seen = false, not deleted. Triggered from Setup, next to Generate SQL, because it reads the whole source and the answer only changes when the catalogue does. A key can carry several attribute sets across history -- 11,290 parts against 13,662 combinations on osm_skinny -- so the refresh takes the most recent by the source's date column. That also fixes the sibling autofill, which used to run a DISTINCT ... LIMIT 2 against the source and silently fill nothing whenever a part came back ambiguous. A member row is one definition by construction. The client fetches each group's list once per source and does both completion and autofill against it in memory, so neither costs a request. Columns outside a group, or a group never refreshed, still fall back to the version's values endpoint. Run 01_schema.sql to create the table. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| lib | ||
| public | ||
| routes | ||
| setup_sql | ||
| ui | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| install.sh | ||
| package-lock.json | ||
| package.json | ||
| PERSPECTIVE.md | ||
| pf_perspective_options.md | ||
| pf_spec.md | ||
| pf.sh | ||
| server.js | ||