Math tracker (/trackers/math): Evan Chen's Napkin, chapter by chapter
Some checks failed
Deploy production / deploy (push) Failing after 9s
Some checks failed
Deploy production / deploy (push) Failing after 9s
Schema math (parts, chapters, sections, activity), seeded with all 100 chapters (Ch 0-94, appendix A-E), 647 sections, PDF pages, exercise counts and approximate prereqs. Triggers stamp started_at/completed_at and log status/exercise/note/section changes; math.apply_progress(jsonb) applies the JSON format bots send. Private by default via MATH_PRIVATE in #lib/math (owner-only prefix + lock in every tracker list). Overall + per-part progress, current chapter, prereq hints, quick status buttons, exercises stepper, notes, optional section ticks, activity log, dependency chart. Deploy preflight checks the math schema (4 tables, 100 chapters).
This commit is contained in:
@@ -287,6 +287,33 @@ try {
|
||||
notes.public_usage
|
||||
)
|
||||
throw new Error(`notes schema tables/grants are wrong: ${JSON.stringify(notes)}`);
|
||||
// Math (the Napkin tracker, private by default): app role read/write, personal_ro none.
|
||||
// 4 = parts, chapters, sections, activity; the migration seeds all 100 chapters.
|
||||
const MATH_TABLES = 4;
|
||||
const [math] = 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', 'math', 'usage') as public_usage
|
||||
from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
||||
where n.nspname = 'math' and c.relkind = 'r'
|
||||
`;
|
||||
if (
|
||||
Number(math.tables) !== MATH_TABLES ||
|
||||
Number(math.app_rw) !== MATH_TABLES ||
|
||||
Number(math.ro_read) !== 0 ||
|
||||
math.public_usage
|
||||
)
|
||||
throw new Error(`math schema tables/grants are wrong: ${JSON.stringify(math)}`);
|
||||
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`);
|
||||
// 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
|
||||
@@ -296,7 +323,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, 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), 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