plant: private Cargill Gouda tracker (/trackers/cargill)
All checks were successful
Deploy production / deploy (push) Successful in 1m19s
All checks were successful
Deploy production / deploy (push) Successful in 1m19s
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.
This commit is contained in:
@@ -314,6 +314,34 @@ try {
|
||||
const [{ n: mathChapters }] = await client`select count(*)::int as n from math.chapters`;
|
||||
if (mathChapters !== 100)
|
||||
throw new Error(`math.chapters has ${mathChapters} rows, expected the 100 Napkin chapters`);
|
||||
// Cargill plant tracker (owner-only): app role read/write, personal_ro none, and the app can run
|
||||
// plant.apply_entries (the bulk import). 2 = entries, links; the migration seeds the factory guide.
|
||||
const PLANT_TABLES = 3;
|
||||
const [plant] = await client`
|
||||
select
|
||||
count(*) filter (where has_table_privilege(c.oid, 'select, insert, update, delete')) as app_rw,
|
||||
count(*) filter (
|
||||
where exists (
|
||||
select 1 from aclexplode(c.relacl) a join pg_roles r on r.oid = a.grantee
|
||||
where r.rolname = 'personal_ro'
|
||||
)
|
||||
) as ro_read,
|
||||
count(*) as tables,
|
||||
has_schema_privilege('public', 'plant', 'usage') as public_usage,
|
||||
has_function_privilege('plant.apply_entries(jsonb)', 'execute') as can_apply
|
||||
from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
||||
where n.nspname = 'plant' and c.relkind = 'r'
|
||||
`;
|
||||
if (
|
||||
Number(plant.tables) !== PLANT_TABLES ||
|
||||
Number(plant.app_rw) !== PLANT_TABLES ||
|
||||
Number(plant.ro_read) !== 0 ||
|
||||
plant.public_usage ||
|
||||
!plant.can_apply
|
||||
)
|
||||
throw new Error(`plant schema tables/grants are wrong: ${JSON.stringify(plant)}`);
|
||||
const [{ n: plantEntries }] = await client`select count(*)::int as n from plant.entries`;
|
||||
if (!plantEntries) throw new Error('plant.entries is empty, expected the seeded factory guide');
|
||||
// Energy tracker reads the ned-collector tables (SELECT only).
|
||||
const [energy] = await client`
|
||||
select count(*) as hours, max(valid_from) as latest from energy.ned_utilization
|
||||
@@ -323,7 +351,7 @@ try {
|
||||
if (!Number(energy.hours))
|
||||
console.warn('Warning: energy.ned_utilization has no hourly data from the last 7 days');
|
||||
console.log(
|
||||
`health: ${health.tables} tables, tasks: ${tasks.tables} tables, groceries: ${groceries.tables} tables, stats: ${stats.tables} tables, ai: ${ai.tables} tables, movies: ${movies.tables} tables, worldtodo: ${worldtodo.tables} tables (${worldtodoTasks} tasks), notes: ${notes.tables} tables, math: ${math.tables} tables (${mathChapters} chapters), app read/write, personal_ro none; energy: ${energy.hours} hourly rows, latest ${energy.latest ? new Date(energy.latest).toISOString() : 'none'}`
|
||||
`health: ${health.tables} tables, tasks: ${tasks.tables} tables, groceries: ${groceries.tables} tables, stats: ${stats.tables} tables, ai: ${ai.tables} tables, movies: ${movies.tables} tables, worldtodo: ${worldtodo.tables} tables (${worldtodoTasks} tasks), notes: ${notes.tables} tables, math: ${math.tables} tables (${mathChapters} chapters), plant: ${plant.tables} tables (${plantEntries} entries), app read/write, personal_ro none; energy: ${energy.hours} hourly rows, latest ${energy.latest ? new Date(energy.latest).toISOString() : 'none'}`
|
||||
);
|
||||
const [catalog] = await client`
|
||||
select
|
||||
|
||||
Reference in New Issue
Block a user