Implement inheritable defaults for collections, books, chapters and questions#221
Merged
janezd merged 1 commit intobiolab:masterfrom Apr 28, 2026
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Implements directory-based inheritable defaults (via a defaults.yml) for collection/book/chapter/question settings, and refactors question attempts/points to come from chapter/book context instead of per-question MDX props.
Changes:
- Add discovery + loading of
defaults.ymlfiles and apply them as inherited frontmatter defaults during ingest. - Extend ingest pipeline to pass inherited question defaults into quiz extraction (attempts/points).
- Move quiz question settings (maxPoints/maxAttempts) to be sourced from
QuizContextrather than MDX props.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| ingest/updatePaths.ts | Loads collected defaults and passes them into book/collection parsing; adjusts inheritable DB insertion behavior. |
| ingest/questions.ts | Applies inherited defaults for attempts/points when extracting questions from MDX. |
| ingest/md-helpers.ts | Introduces defaults typing + defaultsFor() and wires defaults into frontmatter parsing. |
| ingest/inheritables.ts | Registers defaults.yml as an inheritable resource and extends resource typing. |
| ingest/collection.ts | Applies inherited defaults when parsing collections and the book/collection entries they contain. |
| ingest/book.ts | Applies inherited defaults to book/chapter frontmatter and passes question defaults into quiz extraction. |
| context/QuizContextProvider.tsx | Adds maxAttempts to question state and exposes getQuestionSettings() from context. |
| components/Quiz/Quiz.tsx | Reads maxPoints/maxAttempts from quiz context rather than MDX props. |
| components/MdxContent.tsx | Stops passing attempts/points props through to the Question component. |
Comments suppressed due to low confidence (2)
ingest/updatePaths.ts:601
insertResourcePathsnow filters with.filter(({ db }) => db), butgetInheritableResourcescurrently returns entries withoutdb, so this will skip favicon/css entries as well (and insert nothing). Either propagate thedbflag intoresourcePathsand default it to true, or change this filter to only excludedb === false.
await Promise.all(
paths
.filter(({db}) => db)
.map(({path, type}) => {
db.run(`
INSERT INTO inheritables (path, type, lastBuildId)
VALUES (?, ?, ?)
ON CONFLICT DO UPDATE SET lastBuildId = excluded.lastBuildId
`,
[path, type, buildId]);
}));
ingest/inheritables.ts:22
- Repository scanning drops the
dbflag:resourcesdefines{ db: false }for defaults, butgetInheritableResourcesmaps to{ type, path }and never includesdb. This means callers cannot distinguish which inheritable resources should be stored in the DB. Includedbin the returned objects (defaulting to true for favicon/css) soinsertResourcePathscan work as intended.
const resources = [
{type: "favicon", file: "favicon.png"},
{type: "css", file: "style.css"},
{type: "defaults", file: "defaults.yml", db: false},
];
export type InheritableResources = {
type: string,
path: string,
db?: boolean
}[];
export const getInheritableResources = (prefix: string): InheritableResources => [
...resources
.filter(({file}) => pathExists(prefix, file))
.map(({type}) => ({
type,
path: prefix
})),
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1149595 to
6acae6c
Compare
6acae6c to
5a49350
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #201. Fixes #177. Towards implementing also #82.
This PR implements inheritable defaults. Putting a file
defaults.ymlwith content likein some directory sets defaults for all collections, books, chapters and questions within that directory and subdirectories. Chapter and question defaults are based on the path of the book within which they are contained.
The file can include any setting from collection, book and chapter front matter (even the title, though this may not make sense). For questions, it may contain
attempts,points,ungradedandaccept.Implementing this for questions requires a deeper change: questions no longer read
attempts,pointsandacceptdirectly from props (in markdown) but from get them from quiz context (which gets them from chapters, which get them from props or defaults). This change is hygienic anyway.To avoid modifying the db structure (and also avoid having redundant columns) the
answercolumn is repurposed asacceptfor upload questions. (This also makes sense - it defines the correct file type, so it is a "correct answer" in a sense.) This would cause problems in existing questions withacceptattribute, but a quick search doesn't find any outside documentation, which just need to be re-ingested.