Math tracker (/trackers/math): Evan Chen's Napkin, chapter by chapter
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:
2026-10-26 10:55:16 +00:00
parent 23a43049a0
commit d99245e9fc
16 changed files with 45741 additions and 4 deletions

View File

@@ -0,0 +1,33 @@
import { MATH_PRIVATE } from '#lib/math.js';
import { applyFromForm, loadMath } from '#lib/server/math.js';
import { isOwner, requireOwner } from '#lib/server/owner.js';
import { fail } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
// Math tracker: Evan Chen's "An Infinitely Large Napkin". Private by default (MATH_PRIVATE in
// #lib/math): then everyone else gets a 404 for the page and its __data.json, and
// hooks.server.ts 404s the path as a backstop. Edits are always owner-only.
export const load: PageServerLoad = async (event) => {
if (MATH_PRIVATE) requireOwner(event);
const owner = isOwner(event);
if (owner) event.setHeaders({ 'cache-control': 'private, no-store' });
return {
owner,
private: MATH_PRIVATE,
now: Date.now(),
...(await loadMath(owner)),
seo: {
title: 'Math tracker',
description: "Working through Evan Chen's An Infinitely Large Napkin, chapter by chapter.",
index: !MATH_PRIVATE
}
};
};
export const actions: Actions = {
progress: async (event) => {
requireOwner(event);
const r = await applyFromForm(await event.request.formData());
return r.ok ? { ok: true } : fail(400, { message: r.message });
}
};

File diff suppressed because it is too large Load Diff