"""Seed clearly-marked sample articles, cards and lab deep links for demonstration. Every created row is labeled as sample content and links existing bank questions, cards and cited lab references so the linking features are visible end to end. Idempotent: existing sample rows are left untouched. """ import sys from app.database import SessionLocal from app.models.article import Article, QuestionArticleLink from app.models.flashcard import Flashcard, FlashcardDeck, FlashcardArticleLink, FlashcardQuestionLink from app.models.lab_reference import LabReference, LabReferenceCardLink from app.models.question import Question from app.models.user import User SAMPLE_NOTE = "Sample content for demonstration — replace with educator-reviewed material." SECTION_JAUNDICE = "000000000000000000000000000000a1" SECTION_JAUNDICE_BILI = "000000000000000000000000000000a2" SECTION_SEIZURE = "000000000000000000000000000000b1" SECTION_SEIZURE_LABS = "000000000000000000000000000000b2" def main(): db = SessionLocal() try: moderator = db.query(User.id).filter(User.role.in_(["admin", "moderator"])).order_by(User.id).first() moderator = moderator[0] if moderator else None # ── Sample articles ──────────────────────────────────────────── articles = [] for slug, title, summary, content, sections, category_hint in [ ("sample-febrile-seizures", "Febrile seizures — sample", SAMPLE_NOTE, "This **sample article** demonstrates article sections, question links and card links.", [ {"id": SECTION_SEIZURE, "slug": "definition", "title": "Definition and evaluation", "content": "A febrile seizure is a seizure associated with fever in a child 6 months–5 years without CNS infection or metabolic cause.\n\n**Sample text** — verify against your local guidance."}, {"id": SECTION_SEIZURE_LABS, "slug": "reference-values", "title": "Reference values", "content": "Linked laboratory reference values appear in the quiz lab panel and deep-link back to this section.\n\n**Sample text** — verify against your local guidance."}, ], None), ("sample-neonatal-jaundice", "Neonatal jaundice — sample", SAMPLE_NOTE, "This **sample article** demonstrates deep links from lab references into a specific section.", [ {"id": SECTION_JAUNDICE, "slug": "overview", "title": "Overview", "content": "Physiologic jaundice appears after 24 hours of life and peaks at 3–5 days in term infants.\n\n**Sample text** — verify against your local guidance."}, {"id": SECTION_JAUNDICE_BILI, "slug": "bilirubin-reference-values", "title": "Bilirubin reference values", "content": "Total bilirubin reference values used in the lab panel link to this section.\n\n**Sample text** — verify against your local guidance."}, ], None), ]: if not db.query(Article.id).filter(Article.slug == slug).first(): article = Article(slug=slug, title=title, summary=summary, content=content, sections=sections, user_id=moderator, status="published") db.add(article) db.flush() articles.append(article) print(f"Created sample article: {title}") db.commit() # ── Link bank questions ───────────────────────────────────────── from app.services.quiz_builder import shareable_question_predicate bank = db.query(Question.id).filter( shareable_question_predicate(), Question.source_quiz_id.is_(None), ).order_by(Question.id).limit(6).all() bank_ids = [row[0] for row in bank] by_slug = {a.slug: a for a in db.query(Article).filter(Article.slug.in_( ["sample-febrile-seizures", "sample-neonatal-jaundice"])).all()} pairs = [ ("sample-febrile-seizures", None, 0), ("sample-febrile-seizures", SECTION_SEIZURE, 1), ("sample-febrile-seizures", SECTION_SEIZURE_LABS, 2), ("sample-neonatal-jaundice", None, 3), ("sample-neonatal-jaundice", SECTION_JAUNDICE, 4), ("sample-neonatal-jaundice", SECTION_JAUNDICE_BILI, 5), ] for slug, section_id, bank_index in pairs: article = by_slug.get(slug) if not article or not bank_ids: continue question_id = bank_ids[bank_index % len(bank_ids)] if not db.query(QuestionArticleLink.id).filter_by( question_id=question_id, article_id=article.id, section_id=section_id).first(): db.add(QuestionArticleLink(question_id=question_id, article_id=article.id, section_id=section_id, user_id=moderator)) print(f"Linked question {question_id} -> {slug} {section_id or 'whole article'}") db.commit() # Sample question demonstrating key points that smart-link to the sample articles. sample_q = db.query(Question).filter(Question.question_text.like("Sample: febrile seizure definition%")).first() if not sample_q: sample_q = Question( question_text="Sample: febrile seizure definition — which feature defines a SIMPLE febrile seizure?", question_type="mcq", options=["Generalized, lasts under 15 minutes, once in 24 hours", "Focal seizure lasting 25 minutes", "Two seizures within 24 hours", "Seizure with CSF pleocytosis"], correct_answer="Generalized, lasts under 15 minutes, once in 24 hours", explanation="**Sample content — verify clinically.** A simple febrile seizure is generalized, brief (<15 min), " "and does not recur within 24 hours, in a child 6 months–5 years with fever and no CNS infection.", option_explanations={ "Generalized, lasts under 15 minutes, once in 24 hours": "This matches the definition of a simple febrile seizure.", "Focal seizure lasting 25 minutes": "Focal or prolonged seizures are complex febrile seizures.", "Two seizures within 24 hours": "Recurrence within 24 hours makes the seizure complex.", "Seizure with CSF pleocytosis": "CSF pleocytosis suggests CNS infection, not a febrile seizure.", }, user_id=moderator, is_shared=1, ) db.add(sample_q) db.flush() print("Created sample smart-link question") seizure_article = by_slug.get("sample-febrile-seizures") jaundice_article = by_slug.get("sample-neonatal-jaundice") sample_q.key_points = [ {"text": "A febrile seizure is a seizure with fever in a child 6 months–5 years without CNS infection.", "article_id": seizure_article.id if seizure_article else None, "article_section_id": SECTION_SEIZURE}, {"text": "Physiologic jaundice appears after 24 hours and peaks at 3–5 days in term infants.", "article_id": jaundice_article.id if jaundice_article else None, "article_section_id": SECTION_JAUNDICE}, ] db.commit() # ── Sample deck and cards ─────────────────────────────────────── deck = db.query(FlashcardDeck).filter_by(title="Sample cards", user_id=moderator).first() if not deck: deck = FlashcardDeck(title="Sample cards", user_id=moderator, card_count=0, is_shared=1) db.add(deck) db.flush() sample_cards = [ ("Sample: febrile seizure definition", "Seizure with fever in a child 6 months–5 years without CNS infection or metabolic cause. **Sample content** — verify clinically."), ("Sample: jaundice timeline", "Physiologic jaundice appears after 24 h and peaks at 3–5 days in term infants. **Sample content** — verify clinically."), ] created_cards = [] for front, back in sample_cards: card = db.query(Flashcard).filter_by(deck_id=deck.id, front=front).first() if not card: card = Flashcard(deck_id=deck.id, front=front, back=back) db.add(card) db.flush() created_cards.append(card) if created_cards: deck.card_count = db.query(Flashcard).filter(Flashcard.deck_id == deck.id).count() db.commit() print(f"Sample deck cards: {len(created_cards)}") cards = db.query(Flashcard).filter_by(deck_id=deck.id).order_by(Flashcard.id).all() seizure_article = by_slug.get("sample-febrile-seizures") jaundice_article = by_slug.get("sample-neonatal-jaundice") if cards and seizure_article and bank_ids: card = cards[0] if not db.query(FlashcardArticleLink.id).filter_by( flashcard_id=card.id, article_id=seizure_article.id, article_section_id=SECTION_SEIZURE).first(): db.add(FlashcardArticleLink(flashcard_id=card.id, article_id=seizure_article.id, article_section_id=SECTION_SEIZURE)) if not db.query(FlashcardQuestionLink.id).filter_by(flashcard_id=card.id, question_id=bank_ids[0]).first(): db.add(FlashcardQuestionLink(flashcard_id=card.id, question_id=bank_ids[0])) print(f"Card {card.id} linked to question {bank_ids[0]}") if len(cards) > 1 and jaundice_article: card = cards[1] if not db.query(FlashcardArticleLink.id).filter_by( flashcard_id=card.id, article_id=jaundice_article.id, article_section_id=SECTION_JAUNDICE_BILI).first(): db.add(FlashcardArticleLink(flashcard_id=card.id, article_id=jaundice_article.id, article_section_id=SECTION_JAUNDICE_BILI)) if bank_ids and not db.query(FlashcardQuestionLink.id).filter_by( flashcard_id=card.id, question_id=bank_ids[1 % len(bank_ids)]).first(): db.add(FlashcardQuestionLink(flashcard_id=card.id, question_id=bank_ids[1 % len(bank_ids)])) db.commit() # ── Deep-link lab references to the sample sections ───────────── lab_targets = [ ("Bilirubin (total)", SECTION_JAUNDICE_BILI, "sample-neonatal-jaundice"), ("CSF white cell count", SECTION_SEIZURE_LABS, "sample-febrile-seizures"), ("CSF protein", SECTION_SEIZURE_LABS, "sample-febrile-seizures"), ] for name, section_id, slug in lab_targets: article = by_slug.get(slug) if not article: continue for entry in db.query(LabReference).filter(LabReference.name == name).all(): if entry.article_id is None: entry.article_id = article.id entry.article_section_id = section_id print(f"Lab '{name}' deep-links to {slug}#{section_id[:8]}") # Link a sample card to one lab reference. lab = db.query(LabReference).filter(LabReference.name == "CSF white cell count").first() if lab and cards: if not db.query(LabReferenceCardLink.id).filter_by( lab_reference_id=lab.id, flashcard_id=cards[0].id).first(): db.add(LabReferenceCardLink(lab_reference_id=lab.id, flashcard_id=cards[0].id)) print(f"Lab '{lab.name}' linked to sample card") db.commit() print("Sample content ready.") finally: db.close() if __name__ == "__main__": sys.exit(main())