/** * Demo seed script — wipes all existing data and inserts realistic * homeschool demo data for two kids (Emma & Liam). * * Run: node seed.js */ import { db } from './db.js'; /* ── helpers ──────────────────────────────────────────────── */ const today = () => new Date().toISOString().slice(0, 10); const daysAgo = n => { const d = new Date(); d.setDate(d.getDate() - n); return d.toISOString().slice(0, 10); }; const daysAhead = n => { const d = new Date(); d.setDate(d.getDate() + n); return d.toISOString().slice(0, 10); }; const tsAgo = (days, hours = 10) => { const d = new Date(); d.setDate(d.getDate() - days); d.setHours(hours, 0, 0, 0); return d.toISOString(); }; /* ── wipe ─────────────────────────────────────────────────── */ db.exec(` DELETE FROM test_answers; DELETE FROM tests; DELETE FROM submission_history; DELETE FROM submissions; DELETE FROM schedule; DELETE FROM progress; DELETE FROM attempts; DELETE FROM assignments; DELETE FROM card_progress; DELETE FROM cards; DELETE FROM decks; DELETE FROM words; DELETE FROM lists; DELETE FROM quiz_questions; DELETE FROM items; DELETE FROM units; DELETE FROM enrollments; DELETE FROM courses; DELETE FROM students; DELETE FROM messages; `); console.log('Wiped all tables.'); /* ════════════════════════════════════════════════════════════ STUDENTS ═════════════════════════════════════════════════════════════ */ const insertStudent = db.prepare(` INSERT INTO students (id, name, emoji, created_at, theme, streak_count, best_streak, streak_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `); insertStudent.run(1, 'Emma', '🦊', tsAgo(60), 'theme-purple', 5, 12, today()); insertStudent.run(2, 'Liam', '🐻', tsAgo(45), 'theme-teal', 3, 8, today()); console.log('Students created.'); /* ════════════════════════════════════════════════════════════ COURSES ═════════════════════════════════════════════════════════════ */ const insertCourse = db.prepare(` INSERT INTO courses (id, name, subject, color, archived) VALUES (?, ?, ?, ?, 0) `); insertCourse.run(1, 'Language Arts', 'English', '#7c3aed'); insertCourse.run(2, 'Mathematics', 'Math', '#0d9488'); insertCourse.run(3, 'Earth Science', 'Science', '#16a34a'); insertCourse.run(4, 'American History', 'History', '#ea580c'); insertCourse.run(5, 'Bible', 'Bible', '#d97706'); console.log('Courses created.'); /* ── enrollments ──────────────────────────────────────────── */ const enroll = db.prepare('INSERT INTO enrollments (student_id, course_id) VALUES (?, ?)'); // Emma takes all 5; Liam takes 4 (no Bible) [1,2,3,4,5].forEach(c => enroll.run(1, c)); [1,2,3,4].forEach(c => enroll.run(2, c)); /* ════════════════════════════════════════════════════════════ UNITS + ITEMS ═════════════════════════════════════════════════════════════ */ const insertUnit = db.prepare(`INSERT INTO units (id, course_id, name, sort) VALUES (?, ?, ?, ?)`); const insertItem = db.prepare(` INSERT INTO items (id, unit_id, type, title, body, points, ref_id, sort, due_date, allow_retakes, evidence_mode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); const insertQ = db.prepare(` INSERT INTO quiz_questions (id, item_id, type, prompt, choices, correct_answer, points, sort) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `); let unitId = 1, itemId = 1, qId = 1; /* ─── Language Arts ──────────────────────────────────────── Unit 1: Grammar Foundations Unit 2: Creative Writing */ insertUnit.run(unitId, 1, 'Grammar Foundations', 1); const laUnit1 = unitId++; // Lesson: Parts of Speech insertItem.run(itemId, laUnit1, 'lesson', 'Parts of Speech', `

What are Parts of Speech?

Every word in English belongs to a part of speech — a category that describes how the word works in a sentence.

The 8 Parts of Speech

Learning parts of speech helps you understand how sentences are built and makes you a stronger reader and writer.

`, 0, null, 1, daysAgo(14), 0, 'none'); const lessonPos = itemId++; // Quiz: Parts of Speech insertItem.run(itemId, laUnit1, 'quiz', 'Parts of Speech Quiz', '', 20, null, 2, daysAgo(10), 1, 'none'); const quizPos = itemId++; insertQ.run(qId++, quizPos, 'mc', 'Which word is a NOUN?', JSON.stringify(['quickly','beautiful','mountain','runs']), 'mountain', 5, 1); insertQ.run(qId++, quizPos, 'mc', 'Which word is a VERB?', JSON.stringify(['slowly','purple','jump','the']), 'jump', 5, 2); insertQ.run(qId++, quizPos, 'mc', 'Which word is an ADJECTIVE?', JSON.stringify(['gracefully','enormous','laugh','because']), 'enormous', 5, 3); insertQ.run(qId++, quizPos, 'sa', 'Write a sentence using a preposition.', '[]', '', 5, 4); // Lesson: Sentence Structure insertItem.run(itemId, laUnit1, 'lesson', 'Sentence Structure', `

Building Strong Sentences

Every complete sentence needs two things: a subject (who or what the sentence is about) and a predicate (what the subject does or is).

Simple Sentences

A simple sentence has one independent clause: The dog barked.

Compound Sentences

Two independent clauses joined by a conjunction: The dog barked, and the cat hid.

Complex Sentences

One independent clause + one dependent clause: Because it was raining, we stayed inside.

Using a variety of sentence types makes your writing more interesting to read!

`, 0, null, 3, daysAgo(7), 0, 'none'); itemId++; insertUnit.run(unitId, 1, 'Creative Writing', 2); const laUnit2 = unitId++; insertItem.run(itemId, laUnit2, 'lesson', 'The Writing Process', `

Five Steps to Great Writing

  1. Prewrite — Brainstorm ideas. Use a web, list, or outline.
  2. Draft — Write your ideas without worrying about perfection.
  3. Revise — Improve your ideas. Add details, rearrange, clarify.
  4. Edit — Fix spelling, grammar, and punctuation.
  5. Publish — Share your finished work!

Good writers don't write perfectly the first time — they revise and improve!

`, 0, null, 1, daysAgo(4), 0, 'none'); itemId++; insertItem.run(itemId, laUnit2, 'assignment', 'Descriptive Paragraph', ` Write a descriptive paragraph (at least 5 sentences) about your favorite place. Use vivid adjectives and at least two different sentence types (simple, compound, or complex). Remember to: - Start with a topic sentence - Include sensory details (what you see, hear, smell, feel) - End with a concluding sentence `, 25, null, 2, daysAhead(3), 0, 'none'); itemId++; /* ─── Mathematics ────────────────────────────────────────── Unit 1: Fractions Unit 2: Geometry */ insertUnit.run(unitId, 2, 'Fractions & Decimals', 1); const mathUnit1 = unitId++; insertItem.run(itemId, mathUnit1, 'lesson', 'Understanding Fractions', `

What Is a Fraction?

A fraction represents a part of a whole. It has two parts:

Equivalent Fractions

Fractions that name the same amount are called equivalent fractions.

Example: 1/2 = 2/4 = 4/8

Simplifying Fractions

Divide the numerator and denominator by their greatest common factor (GCF).

Example: 8/12 → GCF is 4 → 2/3

`, 0, null, 1, daysAgo(21), 0, 'none'); itemId++; insertItem.run(itemId, mathUnit1, 'quiz', 'Fractions Quiz', '', 30, null, 2, daysAgo(14), 1, 'none'); const quizFrac = itemId++; insertQ.run(qId++, quizFrac, 'mc', 'What is the simplified form of 6/9?', JSON.stringify(['1/3','2/3','3/4','6/9']), '2/3', 10, 1); insertQ.run(qId++, quizFrac, 'mc', 'Which fraction is equivalent to 1/2?', JSON.stringify(['2/3','3/4','4/8','5/9']), '4/8', 10, 2); insertQ.run(qId++, quizFrac, 'sa', 'Write two fractions that are equivalent to 3/4.', '[]', '', 10, 3); insertItem.run(itemId, mathUnit1, 'lesson', 'Adding & Subtracting Fractions', `

Same Denominator

When denominators are the same, just add or subtract the numerators:

3/8 + 2/8 = 5/8

Different Denominators

Find the Least Common Denominator (LCD), convert, then add:

1/3 + 1/4 → LCD = 12 → 4/12 + 3/12 = 7/12

`, 0, null, 3, daysAgo(7), 0, 'none'); itemId++; insertItem.run(itemId, mathUnit1, 'assignment', 'Fractions Worksheet', ` Solve these fraction problems. Show your work! 1. 2/5 + 1/5 = 2. 3/4 - 1/4 = 3. 1/3 + 1/2 = 4. 5/6 - 1/3 = 5. Simplify 10/15 6. Simplify 9/12 7. Are 2/3 and 8/12 equivalent? Explain why. `, 20, null, 4, daysAhead(1), 1, 'none'); itemId++; insertUnit.run(unitId, 2, 'Geometry', 2); const mathUnit2 = unitId++; insertItem.run(itemId, mathUnit2, 'lesson', 'Polygons & Angles', `

What Is a Polygon?

A polygon is a closed shape made of straight line segments.

Common Polygons

Types of Angles

`, 0, null, 1, daysAhead(5), 0, 'none'); itemId++; /* ─── Earth Science ───────────────────────────────────────── Unit 1: The Water Cycle Unit 2: Ecosystems */ insertUnit.run(unitId, 3, 'The Water Cycle', 1); const sciUnit1 = unitId++; insertItem.run(itemId, sciUnit1, 'lesson', 'Water Cycle Overview', `

Earth's Water Is Always Moving

The water cycle (also called the hydrological cycle) describes the continuous movement of water through Earth's systems.

The Four Main Stages

  1. Evaporation — Heat from the sun turns liquid water into water vapor, which rises into the atmosphere.
  2. Condensation — Water vapor cools and forms tiny droplets that make clouds and fog.
  3. Precipitation — Water falls from clouds as rain, snow, sleet, or hail.
  4. Collection — Water gathers in oceans, lakes, rivers, and groundwater, and the cycle begins again.

The sun is the energy source that drives the water cycle!

`, 0, null, 1, daysAgo(18), 0, 'none'); itemId++; insertItem.run(itemId, sciUnit1, 'quiz', 'Water Cycle Quiz', '', 25, null, 2, daysAgo(12), 1, 'none'); const quizWater = itemId++; insertQ.run(qId++, quizWater, 'mc', 'What is the process where liquid water becomes water vapor?', JSON.stringify(['Condensation','Precipitation','Evaporation','Collection']), 'Evaporation', 5, 1); insertQ.run(qId++, quizWater, 'mc', 'What energy source drives the water cycle?', JSON.stringify(['The moon','Wind','The sun','Earth\'s core']), 'The sun', 5, 2); insertQ.run(qId++, quizWater, 'mc', 'What is it called when water falls from clouds?', JSON.stringify(['Evaporation','Condensation','Collection','Precipitation']), 'Precipitation', 5, 3); insertQ.run(qId++, quizWater, 'mc', 'Which of these is NOT a form of precipitation?', JSON.stringify(['Rain','Snow','Fog','Hail']), 'Fog', 5, 4); insertQ.run(qId++, quizWater, 'sa', 'Explain in your own words what condensation is.', '[]', '', 5, 5); insertItem.run(itemId, sciUnit1, 'assignment', 'Water Cycle Diagram', ` Draw and label a diagram of the water cycle. Your diagram must include: - At least 4 labeled stages (evaporation, condensation, precipitation, collection) - Arrows showing the direction of movement - The sun as the energy source - At least one body of water (ocean, lake, or river) Take a photo of your completed diagram and submit it, or describe it in writing. `, 30, null, 3, daysAhead(2), 0, 'photo'); itemId++; insertUnit.run(unitId, 3, 'Ecosystems', 2); const sciUnit2 = unitId++; insertItem.run(itemId, sciUnit2, 'lesson', 'Food Chains & Food Webs', `

Energy in Ecosystems

All living things need energy. In an ecosystem, energy flows from one organism to another through food chains.

Producers

Plants are producers — they make their own food using sunlight (photosynthesis).

Consumers

Decomposers

Fungi and bacteria break down dead organisms and return nutrients to the soil.

`, 0, null, 1, daysAhead(7), 0, 'none'); itemId++; /* ─── American History ───────────────────────────────────── Unit 1: Colonial America Unit 2: American Revolution */ insertUnit.run(unitId, 4, 'Colonial America', 1); const histUnit1 = unitId++; insertItem.run(itemId, histUnit1, 'lesson', 'The 13 Original Colonies', `

Building a New World

Between 1607 and 1733, thirteen English colonies were established along the eastern coast of North America.

Three Regions

New England Colonies

Massachusetts, Connecticut, Rhode Island, New Hampshire — Known for fishing, shipbuilding, and trade.

Middle Colonies

New York, New Jersey, Pennsylvania, Delaware — Known as the "breadbasket" for their grain farms.

Southern Colonies

Virginia, Maryland, North Carolina, South Carolina, Georgia — Known for tobacco, rice, and indigo plantations.

Life in the colonies was shaped by religion, the land, and relationships with Native Americans.

`, 0, null, 1, daysAgo(25), 0, 'none'); itemId++; insertItem.run(itemId, histUnit1, 'quiz', 'Colonial America Quiz', '', 20, null, 2, daysAgo(20), 1, 'none'); const quizColonial = itemId++; insertQ.run(qId++, quizColonial, 'mc', 'Which region was known as the "breadbasket" colonies?', JSON.stringify(['New England','Middle Colonies','Southern Colonies','Western Territories']), 'Middle Colonies', 5, 1); insertQ.run(qId++, quizColonial, 'mc', 'What was the first permanent English settlement in America?', JSON.stringify(['Plymouth','Boston','Jamestown','Philadelphia']), 'Jamestown', 5, 2); insertQ.run(qId++, quizColonial, 'mc', 'How many original colonies were there?', JSON.stringify(['10','12','13','15']), '13', 5, 3); insertQ.run(qId++, quizColonial, 'sa', 'Name two crops grown in the Southern Colonies.', '[]', '', 5, 4); insertItem.run(itemId, histUnit1, 'lesson', 'Daily Life in the Colonies', `

Life in Colonial Times

Colonial children had very different lives from kids today. Most families farmed and made things by hand.

Education

Children in New England attended dame schools taught by women in their homes. They learned to read using the New England Primer. Boys might go on to a Latin grammar school; girls usually stayed home to learn household skills.

Work

Children helped with farm chores, cooking, spinning, and candle-making from a young age.

Religion

Religion was central to colonial life. Many colonists came to America seeking religious freedom.

`, 0, null, 3, daysAgo(15), 0, 'none'); itemId++; insertUnit.run(unitId, 4, 'American Revolution', 2); const histUnit2 = unitId++; insertItem.run(itemId, histUnit2, 'lesson', 'Road to Revolution', `

Growing Tensions

By the 1760s, colonists were frustrated with British rule. Several key events pushed them toward revolution.

Taxation Without Representation

Britain taxed the colonies — the Stamp Act (1765) and Townshend Acts (1767) — without giving them a voice in Parliament. Colonists protested "No taxation without representation!"

Boston Massacre (1770)

British soldiers fired into a crowd of colonists, killing five people. This event inflamed anti-British feelings.

Boston Tea Party (1773)

Colonists dumped 342 chests of British tea into Boston Harbor to protest the Tea Act. Britain responded with the Intolerable Acts.

These events pushed the colonies toward declaring independence.

`, 0, null, 1, daysAhead(4), 0, 'none'); itemId++; /* ─── Bible ──────────────────────────────────────────────── Unit 1: Old Testament Heroes */ insertUnit.run(unitId, 5, 'Old Testament Heroes', 1); const bibleUnit1 = unitId++; insertItem.run(itemId, bibleUnit1, 'lesson', 'Noah and the Ark', `

A Story of Faith and Obedience

The story of Noah is found in Genesis 6–9.

God's Instruction

God saw that the world had become full of wickedness. He chose Noah — a righteous man — and instructed him to build an ark (a large wooden boat) to save his family and two of every kind of animal.

Noah's Obedience

Though it had never rained before (some scholars believe), Noah trusted God and obeyed. He built the ark exactly as God instructed.

The Flood

It rained for 40 days and 40 nights. The floodwaters covered the earth for 150 days before receding.

God's Promise

After the flood, God placed a rainbow in the sky as a sign of His covenant — a promise never to flood the entire earth again.

"I have set my rainbow in the clouds, and it will be the sign of the covenant between me and the earth." — Genesis 9:13
`, 0, null, 1, daysAgo(10), 0, 'none'); itemId++; insertItem.run(itemId, bibleUnit1, 'quiz', 'Noah and the Ark Quiz', '', 15, null, 2, daysAgo(7), 1, 'none'); const quizNoah = itemId++; insertQ.run(qId++, quizNoah, 'mc', 'Where is the story of Noah found in the Bible?', JSON.stringify(['Exodus','Matthew','Genesis','Psalms']), 'Genesis', 5, 1); insertQ.run(qId++, quizNoah, 'mc', 'How many days and nights did it rain?', JSON.stringify(['7','20','40','100']), '40', 5, 2); insertQ.run(qId++, quizNoah, 'sa', 'What did the rainbow represent after the flood?', '[]', '', 5, 3); insertItem.run(itemId, bibleUnit1, 'lesson', 'David and Goliath', `

Courage and Faith

Found in 1 Samuel 17, the story of David and Goliath shows that with God, the smallest person can overcome great challenges.

The Challenge

Goliath was a Philistine warrior over 9 feet tall who taunted the Israelite army. No soldier was brave enough to fight him — except a young shepherd boy named David.

David's Confidence

David told King Saul that God had helped him protect his sheep from lions and bears, so God would help him defeat Goliath too.

The Victory

Armed with only his sling and five smooth stones, David ran toward Goliath, slung a stone, and struck the giant in the forehead. Goliath fell, and the Philistines fled.

`, 0, null, 3, daysAhead(3), 0, 'none'); itemId++; console.log('Courses, units, and items created.'); /* ════════════════════════════════════════════════════════════ SUBMISSIONS (completed work with scores) ═════════════════════════════════════════════════════════════ */ const insertSub = db.prepare(` INSERT INTO submissions (id, student_id, item_id, status, score, points_possible, answers, completed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `); const insertSubHist = db.prepare(` INSERT INTO submission_history (student_id, item_id, score, points_possible, answers, completed_at) VALUES (?, ?, ?, ?, ?, ?) `); let subId = 1; // Emma's completed work // Parts of Speech lesson — done insertSub.run(subId++, 1, lessonPos, 'done', null, 0, null, tsAgo(13)); // Parts of Speech Quiz — 15/20 const posAnswers = JSON.stringify({ 1: 'mountain', 2: 'jump', 3: 'enormous', 4: 'We went to the park in the morning.' }); insertSub.run(subId++, 1, quizPos, 'done', 15, 20, posAnswers, tsAgo(9)); insertSubHist.run(1, quizPos, 15, 20, posAnswers, tsAgo(9)); // Fractions Quiz — 25/30 (Emma) const fracAnswers = JSON.stringify({ 1: '2/3', 2: '4/8', 3: '6/8 and 9/12' }); insertSub.run(subId++, 1, quizFrac, 'done', 25, 30, fracAnswers, tsAgo(13)); insertSubHist.run(1, quizFrac, 25, 30, fracAnswers, tsAgo(13)); // Water Cycle Quiz — 20/25 (Emma) const waterAnswers = JSON.stringify({ 1: 'Evaporation', 2: 'The sun', 3: 'Precipitation', 4: 'Fog', 5: 'Condensation is when water vapor cools and turns back into liquid droplets.' }); insertSub.run(subId++, 1, quizWater, 'done', 20, 25, waterAnswers, tsAgo(11)); insertSubHist.run(1, quizWater, 20, 25, waterAnswers, tsAgo(11)); // Colonial America Quiz — 18/20 (Emma) const colonialAnswers = JSON.stringify({ 1: 'Middle Colonies', 2: 'Jamestown', 3: '13', 4: 'Tobacco and rice' }); insertSub.run(subId++, 1, quizColonial, 'done', 18, 20, colonialAnswers, tsAgo(19)); insertSubHist.run(1, quizColonial, 18, 20, colonialAnswers, tsAgo(19)); // Noah quiz — 12/15 (Emma) const noahAnswers = JSON.stringify({ 1: 'Genesis', 2: '40', 3: "The rainbow was God's promise never to flood the whole earth again." }); insertSub.run(subId++, 1, quizNoah, 'done', 12, 15, noahAnswers, tsAgo(6)); insertSubHist.run(1, quizNoah, 12, 15, noahAnswers, tsAgo(6)); // Liam's completed work // Fractions Quiz — 27/30 (Liam, best score) const fracAnswersLiam2 = JSON.stringify({ 1: '2/3', 2: '4/8', 3: '6/8 and 9/12' }); insertSub.run(subId++, 2, quizFrac, 'done', 27, 30, fracAnswersLiam2, tsAgo(12)); insertSubHist.run(2, quizFrac, 27, 30, fracAnswersLiam2, tsAgo(12)); // Water Cycle — 22/25 (Liam) const waterLiam = JSON.stringify({ 1: 'Evaporation', 2: 'The sun', 3: 'Precipitation', 4: 'Fog', 5: 'When warm air cools it turns into water droplets.' }); insertSub.run(subId++, 2, quizWater, 'done', 22, 25, waterLiam, tsAgo(10)); insertSubHist.run(2, quizWater, 22, 25, waterLiam, tsAgo(10)); // Colonial — 15/20 (Liam) const colonialLiam = JSON.stringify({ 1: 'Middle Colonies', 2: 'Jamestown', 3: '13', 4: 'Tobacco and corn' }); insertSub.run(subId++, 2, quizColonial, 'done', 15, 20, colonialLiam, tsAgo(18)); insertSubHist.run(2, quizColonial, 15, 20, colonialLiam, tsAgo(18)); // Parts of Speech (Liam) — 16/20 const posLiam = JSON.stringify({ 1: 'mountain', 2: 'jump', 3: 'enormous', 4: 'I put the book on the table.' }); insertSub.run(subId++, 2, quizPos, 'done', 16, 20, posLiam, tsAgo(8)); insertSubHist.run(2, quizPos, 16, 20, posLiam, tsAgo(8)); console.log('Submissions created.'); /* ════════════════════════════════════════════════════════════ SPELLING LISTS ═════════════════════════════════════════════════════════════ */ const insertList = db.prepare('INSERT INTO lists (id, name, builtin, group_name) VALUES (?, ?, 0, ?)'); const insertWord = db.prepare('INSERT INTO words (id, list_id, word, sentence, definition) VALUES (?, ?, ?, ?, ?)'); let listId = 1, wordId = 1; // List 1: 4th Grade Week 1 insertList.run(listId, '4th Grade — Week 1', 'Grade 4'); const list1 = listId++; const week1words = [ ['beautiful', 'The sunset was absolutely beautiful.', 'pleasing to the senses or mind'], ['necessary', 'It is necessary to drink water every day.', 'needed; essential'], ['separate', 'Please separate the red and blue blocks.', 'to set apart; to divide'], ['because', 'I stayed inside because it was raining.', 'for the reason that'], ['different', 'Each snowflake is different from every other.','not the same as another'], ['important', 'Exercise is important for staying healthy.', 'having great significance'], ['knowledge', 'Reading books builds your knowledge.', 'facts or skills acquired through learning'], ['surprise', 'The party was a complete surprise.', 'an unexpected event or feeling'], ['through', 'We walked through the park.', 'moving from one side to the other'], ['whether', 'I wasn\'t sure whether to go or stay.', 'expressing a doubt or choice'], ]; week1words.forEach(([w, s, d]) => insertWord.run(wordId++, list1, w, s, d)); // List 2: 4th Grade Week 2 insertList.run(listId, '4th Grade — Week 2', 'Grade 4'); const list2 = listId++; const week2words = [ ['character', 'The main character in the story was brave.', 'a person in a story; a person\'s qualities'], ['complete', 'Did you complete your homework?', 'having all necessary parts; to finish'], ['continue', 'We will continue reading tomorrow.', 'to keep going'], ['difficult', 'The math problem was very difficult.', 'not easy; hard to do'], ['environment', 'We should protect the natural environment.', 'the surroundings in which one lives'], ['frequently', 'She frequently visits her grandparents.', 'often; many times'], ['government', 'The government makes laws for the country.', 'the group that rules a nation'], ['language', 'English is a fascinating language.', 'a system of words used to communicate'], ['position', 'What position does he play on the team?', 'a place where someone or something is located'], ['remember', 'I will always remember that day.', 'to keep in mind; to recall'], ]; week2words.forEach(([w, s, d]) => insertWord.run(wordId++, list2, w, s, d)); // List 3: Science Vocabulary insertList.run(listId, 'Science Vocabulary', 'Science'); const list3 = listId++; const sciWords = [ ['evaporation', 'Evaporation turns liquid water into vapor.', 'process of liquid changing to gas'], ['condensation', 'Condensation forms on a cold glass on a hot day.', 'process of gas changing to liquid'], ['precipitation','Precipitation includes rain, snow, and hail.', 'water falling from clouds'], ['ecosystem', 'A pond is a small ecosystem.', 'a community of living and nonliving things'], ['photosynthesis','Plants use photosynthesis to make food.', 'how plants make food using sunlight'], ['organism', 'Every living thing is an organism.', 'any living thing'], ['hypothesis', 'We formed a hypothesis before the experiment.', 'an educated guess to be tested'], ['atmosphere', 'The atmosphere protects Earth from the sun\'s rays.', 'the layer of gases around a planet'], ]; sciWords.forEach(([w, s, d]) => insertWord.run(wordId++, list3, w, s, d)); // List 4: Bible Memory Words insertList.run(listId, 'Bible Memory Words', 'Bible'); const list4 = listId++; const bibleWords = [ ['covenant', 'God made a covenant with Noah.', 'a serious agreement or promise'], ['righteous', 'Noah was a righteous man.', 'morally right; following God\'s ways'], ['obedient', 'David was obedient to God\'s calling.', 'doing what you are told; compliant'], ['sacrifice', 'Abraham trusted God with the sacrifice.', 'giving something valuable for a purpose'], ['steadfast', 'Be steadfast in your faith.', 'firm and unwavering'], ['gracious', 'God is gracious and full of compassion.', 'showing grace; kind and merciful'], ]; bibleWords.forEach(([w, s, d]) => insertWord.run(wordId++, list4, w, s, d)); console.log('Spelling lists and words created.'); /* ── assignments (one active list per student) ─────────────── */ const insertAssignment = db.prepare('INSERT OR REPLACE INTO assignments (student_id, list_id, assigned_at) VALUES (?, ?, ?)'); insertAssignment.run(1, list2, tsAgo(7)); // Emma → Week 2 (current) insertAssignment.run(2, list1, tsAgo(14)); // Liam → Week 1 (current) /* ── spelling progress (Leitner boxes) ────────────────────── */ const insertProgress = db.prepare(` INSERT INTO progress (student_id, word_id, box, due, attempts, correct) VALUES (?, ?, ?, ?, ?, ?) `); // Emma has practiced all of Week 1 — most words are in boxes 3-5 const emmaWordIds = Array.from({length: 10}, (_, i) => i + 1); // words 1-10 are list1 const boxDist = [5,5,4,4,3,3,3,2,4,5]; emmaWordIds.forEach((wid, i) => { const box = boxDist[i]; const due = box >= 4 ? daysAhead(7) : box === 3 ? daysAhead(2) : today(); insertProgress.run(1, wid, box, due, 4 + box, 3 + box); }); // Emma — Week 2 words partially practiced (boxes 1-3) const week2ids = Array.from({length: 10}, (_, i) => i + 11); week2ids.forEach((wid, i) => { const box = Math.min(3, 1 + Math.floor(i / 4)); insertProgress.run(1, wid, box, i < 5 ? today() : daysAhead(1), 1 + box, box); }); // Liam — Week 1 partially (boxes 1-3) emmaWordIds.forEach((wid, i) => { const box = Math.min(3, 1 + Math.floor(i / 4)); insertProgress.run(2, wid, box, i < 4 ? today() : daysAhead(1), 1 + box, box); }); /* ── spelling tests ───────────────────────────────────────── */ const insertTest = db.prepare('INSERT INTO tests (id, student_id, list_id, score, total, at) VALUES (?, ?, ?, ?, ?, ?)'); const insertTA = db.prepare('INSERT INTO test_answers (test_id, word_id, typed, correct) VALUES (?, ?, ?, ?)'); // Emma — 3 spelling tests insertTest.run(1, 1, list1, 8, 10, tsAgo(12)); // test answers for test 1 emmaWordIds.slice(0, 10).forEach((wid, i) => { const word = week1words[i][0]; const right = i < 8; const typed = right ? word : (i === 8 ? 'thrugh' : 'wether'); insertTA.run(1, wid, typed, right ? 1 : 0); }); insertTest.run(2, 1, list1, 10, 10, tsAgo(5)); emmaWordIds.slice(0, 10).forEach((wid, i) => { insertTA.run(2, wid, week1words[i][0], 1); }); insertTest.run(3, 1, list3, 7, 8, tsAgo(2)); Array.from({length: 8}, (_, i) => i + 21).forEach((wid, i) => { const right = i < 7; insertTA.run(3, wid, right ? sciWords[i][0] : 'atmosfere', right ? 1 : 0); }); // Liam — 2 spelling tests insertTest.run(4, 2, list1, 7, 10, tsAgo(11)); emmaWordIds.slice(0, 10).forEach((wid, i) => { const right = i < 7; const word = week1words[i][0]; insertTA.run(4, wid, right ? word : word.replace(/[aeiou]/, ''), right ? 1 : 0); }); insertTest.run(5, 2, list1, 9, 10, tsAgo(4)); emmaWordIds.slice(0, 10).forEach((wid, i) => { const right = i !== 4; insertTA.run(5, wid, right ? week1words[i][0] : 'diffrent', right ? 1 : 0); }); console.log('Spelling tests created.'); /* ════════════════════════════════════════════════════════════ FLASHCARD DECKS ═════════════════════════════════════════════════════════════ */ const insertDeck = db.prepare('INSERT INTO decks (id, name, builtin, group_name) VALUES (?, ?, 0, ?)'); const insertCard = db.prepare('INSERT INTO cards (id, deck_id, front, back) VALUES (?, ?, ?, ?)'); let deckId = 1, cardId = 1; insertDeck.run(deckId, 'Math Facts — Multiplication', 'Math'); const deck1 = deckId++; const multFacts = [ ['6 × 7', '42'], ['6 × 8', '48'], ['7 × 7', '49'], ['7 × 8', '56'], ['8 × 8', '64'], ['8 × 9', '72'], ['9 × 7', '63'], ['9 × 9', '81'], ['6 × 9', '54'], ['7 × 9', '63'], ['4 × 8', '32'], ['5 × 7', '35'], ]; multFacts.forEach(([f, b]) => insertCard.run(cardId++, deck1, f, b)); insertDeck.run(deckId, 'US States & Capitals', 'Geography'); const deck2 = deckId++; const states = [ ['California', 'Sacramento'], ['Texas', 'Austin'], ['Florida', 'Tallahassee'], ['New York', 'Albany'], ['Pennsylvania', 'Harrisburg'], ['Ohio', 'Columbus'], ['Virginia', 'Richmond'], ['Georgia', 'Atlanta'], ['Michigan', 'Lansing'], ['Massachusetts', 'Boston'], ['Illinois', 'Springfield'], ['Arizona', 'Phoenix'], ]; states.forEach(([f, b]) => insertCard.run(cardId++, deck2, `Capital of ${f}`, b)); insertDeck.run(deckId, 'Science Vocabulary', 'Science'); const deck3 = deckId++; sciWords.forEach(([w, , d]) => insertCard.run(cardId++, deck3, w, d)); insertDeck.run(deckId, 'Grammar Terms', 'English'); const deck4 = deckId++; const grammarCards = [ ['Noun', 'A word that names a person, place, thing, or idea'], ['Verb', 'A word that shows action or state of being'], ['Adjective', 'A word that describes a noun'], ['Adverb', 'A word that describes a verb, adjective, or another adverb'], ['Pronoun', 'A word that takes the place of a noun'], ['Preposition', 'A word that shows relationship (in, on, under, beside)'], ['Conjunction', 'A word that joins words or clauses (and, but, or, because)'], ['Subject', 'Who or what the sentence is about'], ['Predicate', 'What the subject does or is'], ['Independent clause', 'A group of words that can stand alone as a sentence'], ]; grammarCards.forEach(([f, b]) => insertCard.run(cardId++, deck4, f, b)); console.log('Flashcard decks created.'); /* ── card progress (Emma has practiced Math deck) ─────────── */ const insertCardProg = db.prepare(` INSERT INTO card_progress (student_id, card_id, box, due, attempts, correct) VALUES (?, ?, ?, ?, ?, ?) `); const mathCardIds = Array.from({length: 12}, (_, i) => i + 1); const mathBoxes = [5,5,4,4,3,3,5,2,4,3,4,5]; mathCardIds.forEach((cid, i) => { const box = mathBoxes[i]; const due = box >= 4 ? daysAhead(5) : box === 3 ? daysAhead(1) : today(); insertCardProg.run(1, cid, box, due, 3 + box, 2 + box); }); /* ════════════════════════════════════════════════════════════ SCHEDULE (planner entries for this week) ═════════════════════════════════════════════════════════════ */ const insertSchedule = db.prepare(` INSERT INTO schedule (student_id, date, item_id, title, done, sort, status) VALUES (?, ?, ?, ?, ?, ?, 'pending') `); // Get day-of-week offsets so we land Mon–Fri const getWeekday = (offset) => { const d = new Date(); const day = d.getDay(); // 0=Sun const monday = new Date(d); monday.setDate(d.getDate() - (day === 0 ? 6 : day - 1)); monday.setDate(monday.getDate() + offset); return monday.toISOString().slice(0, 10); }; const mon = getWeekday(0), tue = getWeekday(1), wed = getWeekday(2), thu = getWeekday(3), fri = getWeekday(4); // Emma's schedule this week insertSchedule.run(1, mon, null, 'Morning Bible reading — Genesis 7', 1, 1); insertSchedule.run(1, mon, null, 'Spelling practice — Week 2 words', 0, 2); insertSchedule.run(1, tue, null, 'Math: Adding Fractions worksheet', 0, 1); insertSchedule.run(1, tue, null, 'History reading: Road to Revolution', 0, 2); insertSchedule.run(1, wed, null, 'Science: Water Cycle review', 0, 1); insertSchedule.run(1, wed, null, 'Language Arts: Descriptive paragraph draft', 0, 2); insertSchedule.run(1, thu, null, 'Spelling test — Week 2', 0, 1); insertSchedule.run(1, thu, null, 'Math: Geometry lesson', 0, 2); insertSchedule.run(1, fri, null, 'Free reading (30 min)', 0, 1); insertSchedule.run(1, fri, null, 'Review week — all subjects', 0, 2); // Liam's schedule insertSchedule.run(2, mon, null, 'Spelling practice — Week 2 words', 0, 1); insertSchedule.run(2, mon, null, 'Math: Fractions review', 0, 2); insertSchedule.run(2, tue, null, 'Science: Water Cycle notes', 0, 1); insertSchedule.run(2, tue, null, 'Language Arts: Parts of Speech', 0, 2); insertSchedule.run(2, wed, null, 'History: Colonial Life lesson', 0, 1); insertSchedule.run(2, wed, null, 'Math: Geometry intro', 0, 2); insertSchedule.run(2, thu, null, 'Spelling test — Week 2', 0, 1); insertSchedule.run(2, fri, null, 'Free reading (30 min)', 0, 1); console.log('Schedule created.'); /* ════════════════════════════════════════════════════════════ MESSAGES ═════════════════════════════════════════════════════════════ */ const insertMsg = db.prepare(` INSERT INTO messages (student_id, sender, body, sent_at, read_at) VALUES (?, ?, ?, ?, ?) `); insertMsg.run(1, 'parent', 'Great job on your spelling test, Emma! 10/10! 🎉', tsAgo(5), tsAgo(5)); insertMsg.run(1, 'student', 'Thanks! I practiced a lot. Can we do science experiments today?', tsAgo(5), tsAgo(5)); insertMsg.run(1, 'parent', 'I love that idea! Let\'s do the water cycle experiment after lunch.', tsAgo(5), tsAgo(5)); insertMsg.run(2, 'parent', 'Liam, remember to finish your fractions worksheet before dinner.', tsAgo(2), tsAgo(2)); insertMsg.run(2, 'student', 'Ok! I already did problems 1-4, just have 5-7 left.', tsAgo(2), null); console.log('Messages created.'); /* ════════════════════════════════════════════════════════════ SETTINGS ═════════════════════════════════════════════════════════════ */ const upsertSetting = db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)'); upsertSetting.run('school_name', 'Emmert Academy'); upsertSetting.run('timezone', 'America/Chicago'); console.log('\n✅ Demo data seeded successfully!'); console.log(' Students: Emma (🦊) and Liam (🐻)'); console.log(' Courses: Language Arts, Math, Earth Science, American History, Bible'); console.log(' Spelling: 4 lists with 36 words total'); console.log(' Flashcards: 4 decks with', 12 + 12 + 8 + 10, 'cards'); console.log(' Quiz submissions with scores for both students'); console.log(' Weekly planner schedules');