Skip to content

Implement inheritable defaults for collections, books, chapters and questions#221

Merged
janezd merged 1 commit intobiolab:masterfrom
janezd:inheritable-defaults
Apr 28, 2026
Merged

Implement inheritable defaults for collections, books, chapters and questions#221
janezd merged 1 commit intobiolab:masterfrom
janezd:inheritable-defaults

Conversation

@janezd
Copy link
Copy Markdown
Contributor

@janezd janezd commented Apr 27, 2026

Fixes #201. Fixes #177. Towards implementing also #82.

This PR implements inheritable defaults. Putting a file defaults.yml with content like

chapter:
  omitAsChapter: true
book:
  language: sl
  tocInHeader: true
question:
  attempts: 0
  ungraded: true

in 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, ungraded and accept.

Implementing this for questions requires a deeper change: questions no longer read attempts, points and accept directly 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 answer column is repurposed as accept for 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 with accept attribute, but a quick search doesn't find any outside documentation, which just need to be re-ingested.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.yml files 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 QuizContext rather 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

  • insertResourcePaths now filters with .filter(({ db }) => db), but getInheritableResources currently returns entries without db, so this will skip favicon/css entries as well (and insert nothing). Either propagate the db flag into resourcePaths and default it to true, or change this filter to only exclude db === 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 db flag: resources defines { db: false } for defaults, but getInheritableResources maps to { type, path } and never includes db. This means callers cannot distinguish which inheritable resources should be stored in the DB. Include db in the returned objects (defaulting to true for favicon/css) so insertResourcePaths can 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.

Comment thread ingest/updatePaths.ts Outdated
Comment thread ingest/updatePaths.ts Outdated
Comment thread ingest/inheritables.ts
Comment thread ingest/md-helpers.ts Outdated
Comment thread ingest/updatePaths.ts
Comment thread ingest/md-helpers.ts Outdated
Comment thread context/QuizContextProvider.tsx Outdated
@janezd janezd force-pushed the inheritable-defaults branch 2 times, most recently from 1149595 to 6acae6c Compare April 28, 2026 08:07
@janezd janezd requested a review from Copilot April 28, 2026 08:11
@janezd janezd force-pushed the inheritable-defaults branch from 6acae6c to 5a49350 Compare April 28, 2026 08:46
@janezd janezd merged commit 801a760 into biolab:master Apr 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Additional book property: omitChapterLabels Consider allowing additional uploads when answering upload-type questions

2 participants