Build and Push Docker Image / build-and-push (push) Successful in 7m14s
Sync and data safety - Autosave flushes on leaving a study or the tab; storage-full errors are reported - Unsynced studies, deletes and ink are queued and retried when back online - Deletes propagate across devices (with a "Keep it" undo) and no longer resurrect - Server assigns study versions (no client-clock conflicts); "Combine both" merges a conflicted study chunk by chunk - Reading-plan progress made offline is merged, not overwritten; plans, ink and marks are cleared from the device on sign-out Security - Block SSRF through the ntfy reminder URL; failure-only rate limiting per IP and account; constant-time login; TOTP replay protection; input validation; SESSION_SECRET required in production; admin user delete fixed - Forgot password: one-time code sent to the account's ntfy topic Features - IQ Bible proxy (route allow-list, text-only caching per its terms): more commentaries, lexicons, study aids, daily verse and devotional, plan calendar export, narrations, podcast background - Study templates, reading-plan catch-up, account export, daily database snapshots Tests and tooling - ESLint config; App tests split into src/test; tests for sync queues, library hook, merge, templates, IQ Bible UI and reset form Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
51 lines
3.1 KiB
JavaScript
51 lines
3.1 KiB
JavaScript
// Starting points for a new study. A template changes what the note boxes ask (their prompts) and can
|
|
// pre-fill the "Background / general notes" box of each new chunk with a scaffold to fill in. Choosing
|
|
// "Blank" leaves the default Observe / Interpret / Apply prompts.
|
|
export const STUDY_TEMPLATES = [
|
|
{ id: 'blank', name: 'Blank', description: 'Observe, Interpret, Apply with the standard prompts.' },
|
|
{
|
|
id: 'inductive',
|
|
name: 'Inductive study',
|
|
description: 'Careful, question-led notes: observe the text, interpret it in context, then apply it.',
|
|
prompts: {
|
|
observation: 'Look before you leap.\n• List the people, places, and events.\n• Mark repeated words, contrasts, and connecting words (but, therefore, so that).\n• What is the main verb or command here?\n• What questions does the text raise?',
|
|
interpretation: 'What did it mean then?\n• What is the author\'s main point in this section?\n• How does it fit the paragraph before and after?\n• Which other Scripture sheds light on it?\n• What does it teach about God?',
|
|
application: 'What now?\n• What truth must I believe?\n• What sin to confess, or command to obey?\n• What will I do this week, and who will I tell?',
|
|
},
|
|
starter: 'Context (author, audience, setting):\n\nStructure (how the passage is built):\n\nKey words:\n',
|
|
},
|
|
{
|
|
id: 'sermon',
|
|
name: 'Sermon prep',
|
|
description: 'A big idea, an outline and illustrations for each passage, for teaching or preaching.',
|
|
prompts: {
|
|
observation: 'What does the text say?\n• The flow of thought, verse by verse.\n• Key terms and grammar worth noting.',
|
|
interpretation: 'What does it mean?\n• The main point the author is making.\n• Where it sits in the whole Bible story, and how it points to Christ.',
|
|
application: 'How should it change us?\n• Who is in the room, and what do they need to hear?\n• Specific steps, not just ideas.',
|
|
},
|
|
starter: 'Big idea (one sentence):\n\nOutline:\n1. \n2. \n3. \n\nIllustration:\n\nChrist in this text:\n\nCall to respond:\n',
|
|
},
|
|
{
|
|
id: 'devotional',
|
|
name: 'Devotional',
|
|
description: 'Gentle, personal prompts for reading and praying through a passage.',
|
|
prompts: {
|
|
observation: 'Read it slowly, twice.\n• What word or phrase stands out?\n• What do you notice about God here?',
|
|
interpretation: 'What is God showing you?\n• What does this reveal about who God is?\n• What does it say about who you are?',
|
|
application: 'Respond.\n• What will you thank God for?\n• What will you ask, confess, or obey?\n• A prayer in your own words:',
|
|
},
|
|
starter: '',
|
|
},
|
|
];
|
|
|
|
export const getTemplate = (id) => STUDY_TEMPLATES.find((t) => t.id === id) ?? STUDY_TEMPLATES[0];
|
|
|
|
// The prompt for one note box in a study built from `templateId`, or undefined for the default one.
|
|
export const templatePrompt = (templateId, field) => getTemplate(templateId).prompts?.[field];
|
|
|
|
// Fields a new chunk starts with under this template.
|
|
export const templateStarter = (templateId) => {
|
|
const starter = getTemplate(templateId).starter;
|
|
return starter ? { generalNotes: starter } : {};
|
|
};
|