Files

254 lines
10 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Create tables and seed the DEVTeacher placeholder content on first run.
Idempotent: if an admin already exists, nothing is seeded. The default admin is
username ``DEVTeacher`` / password ``DEVTeacher`` (the teacher changes it).
"""
from __future__ import annotations
from datetime import date
from sqlalchemy import inspect, text
from sqlalchemy.orm import Session
from app.db import Base, SessionLocal, engine
from app.models import (
AdminUser,
Attendance,
Course,
DayMark,
Enquiry,
FeePlan,
Profile,
Review,
ScheduleSlot,
SiteSettings,
Student,
Subject,
Testimonial,
)
from app.security import hash_password
DEFAULT_ADMIN_USER = "DEVTeacher"
DEFAULT_ADMIN_PASS = "DEVTeacher"
def _seed(db: Session) -> None:
db.add(AdminUser(username=DEFAULT_ADMIN_USER, password_hash=hash_password(DEFAULT_ADMIN_PASS)))
db.add(
Profile(
name="Swati Yadav",
tagline="Making learning joyful, clear and exam-ready",
bio=(
"Hello! I'm Swati Yadav, a passionate tuition teacher with years of experience "
"helping students build strong fundamentals and real confidence. I focus on "
"concept clarity, regular practice and personal attention so every student can "
"reach their full potential — whether the goal is topping the class, cracking "
"board exams, or simply falling in love with a subject."
),
photo_url="",
qualifications="M.Sc. Mathematics · B.Ed. · Certified Online Educator",
experience_years=10,
students_taught=500,
achievements=(
"95% of students improved by 2+ grades\n"
"Mentored 50+ board-exam toppers\n"
"Personalised study plans for every learner"
),
hero_cta="Book a free demo class",
)
)
subjects = [
("Mathematics", "Class 6–12", "Algebra, geometry, calculus and problem-solving made simple with step-by-step methods.", "📐", 1),
("Physics", "Class 9–12", "Concept-first physics with real-life examples, numericals and exam techniques.", "🔬", 2),
("Chemistry", "Class 9–12", "Organic, inorganic and physical chemistry taught with clarity and easy recall tricks.", "⚗️", 3),
("English", "Class 6–10", "Grammar, comprehension, writing skills and confident communication.", "📖", 4),
]
for name, level, desc, icon, order in subjects:
db.add(Subject(name=name, level=level, description=desc, mode="Online & Offline", icon=icon, sort_order=order))
courses = [
(
"Board Exam Crash Course",
"Mathematics & Science",
"An intensive revision programme covering the complete syllabus with mock tests, doubt-clearing and previous-year papers.",
"3 months",
"Practice tests every week\nPersonal doubt sessions\nComplete syllabus revision",
1,
),
(
"Foundation Builder",
"All Subjects",
"A steady long-term course for younger students that builds strong basics and study habits from the ground up.",
"Full academic year",
"Concept-first teaching\nRegular homework & feedback\nMonthly progress reports",
2,
),
(
"One-on-One Personal Tuition",
"Chosen Subject",
"Fully personalised private tuition tailored to a single student's pace, goals and weak areas.",
"Flexible",
"Completely customised plan\nFlexible timings\nDedicated attention",
3,
),
]
for title, subject, desc, duration, highlights, order in courses:
db.add(
Course(
title=title,
subject=subject,
description=desc,
duration=duration,
mode="Online & Offline",
highlights=highlights,
sort_order=order,
)
)
fees = [
("Group Batch", "₹1,500", "per month", "Small batches (max 8)\n3 classes a week\nWeekly tests\nStudy material included", False, 1),
("Premium Batch", "₹2,500", "per month", "Mini batches (max 4)\n5 classes a week\nWeekly tests + doubt sessions\nMonthly progress report", True, 2),
("1-on-1 Private", "₹4,000", "per month", "Fully personal tuition\nFlexible timings\nCustom study plan\nUnlimited doubt support", False, 3),
]
for name, price, period, features, highlighted, order in fees:
db.add(FeePlan(name=name, price=price, period=period, features=features, highlighted=highlighted, sort_order=order))
testimonials = [
("Aarav Sharma", "Student", "Swati ma'am made maths so easy to understand. My marks jumped from 62 to 91 in just one year!", 5, 1),
("Meena Gupta", "Parent", "My daughter actually looks forward to her classes now. The personal attention is wonderful.", 5, 2),
("Rohan Verma", "Student", "The best teacher I've ever had. She explains every concept until it truly clicks.", 5, 3),
("Kavita Nair", "Parent", "Very disciplined, caring and result-oriented. Highly recommend to every parent.", 5, 4),
]
for author, relation, quote, rating, order in testimonials:
db.add(Testimonial(author_name=author, relation=relation, quote=quote, rating=rating, sort_order=order))
db.add(
SiteSettings(
address="123 Vidya Nagar, Near City Library, Your City, 000000",
phone="+91 90000 00000",
email="hello@swatiyadav.com",
hours="Mon–Sat, 9:00 AM – 8:00 PM",
whatsapp="https://wa.me/919000000000",
instagram="https://instagram.com/",
youtube="https://youtube.com/",
facebook="https://facebook.com/",
footer_text="Empowering students with knowledge, confidence and care.",
)
)
db.add(
Enquiry(
name="Sample Parent",
email="parent@example.com",
phone="+91 98765 43210",
subject_interest="Mathematics",
message="Hi, I'd like to know the timings for the Class 10 maths batch. Thank you!",
is_read=False,
)
)
reviews = [
("Priya Deshmukh", "Parent", 5, "The weekly progress updates keep me informed and my son is far more confident now.", True),
("Ananya Rao", "Student", 5, "Doubts are always cleared patiently. Highly recommend her classes!", False),
]
for author, relation, rating, message, approved in reviews:
db.add(Review(author_name=author, relation=relation, rating=rating, message=message, is_approved=approved))
db.commit()
_seed_students(db)
def _seed_students(db: Session) -> None:
"""Sample students, schedules and a little attendance for this month."""
students_data = [
# name, phone, parent_name, parent_phone, address, subject, fee, slots
(
"Aarav Sharma", "+91 98111 22233", "Rakesh Sharma", "+91 98111 00011",
"12 Green Park, Your City", "Mathematics · Class 10", 1500,
[(0, "16:00", "17:00"), (2, "16:00", "17:00"), (4, "16:00", "17:00")],
),
(
"Isha Verma", "+91 98222 33344", "Sunita Verma", "+91 98222 00022",
"45 Lake View, Your City", "Physics · Class 12", 2500,
[(1, "17:30", "18:30"), (3, "17:30", "18:30")],
),
(
"Rohan Gupta", "+91 98333 44455", "Manoj Gupta", "+91 98333 00033",
"78 Rose Villa, Your City", "Chemistry · Class 11", 2500,
[(0, "18:00", "19:00"), (3, "18:00", "19:00"), (5, "10:00", "11:00")],
),
(
"Ananya Nair", "+91 98444 55566", "Kavita Nair", "+91 98444 00044",
"9 Sunrise Apartments, Your City", "English · Class 8", 1500,
[(1, "16:00", "17:00"), (4, "16:00", "17:00")],
),
]
student_objs: list[Student] = []
for name, phone, pname, pphone, addr, subj, fee, slots in students_data:
s = Student(
name=name, phone=phone, parent_name=pname, parent_phone=pphone,
address=addr, subject=subj, monthly_fee=fee, start_date=date.today(),
is_active=True, notes="",
)
db.add(s)
db.flush()
for weekday, start, end in slots:
db.add(ScheduleSlot(student_id=s.id, weekday=weekday, start_time=start, end_time=end))
student_objs.append(s)
# A little attendance for the first few days of the current month.
today = date.today()
statuses = ["present", "present", "absent", "present", "off"]
for day in range(1, 6):
try:
d = date(today.year, today.month, day)
except ValueError:
continue
if d > today:
break
for i, s in enumerate(student_objs):
db.add(Attendance(student_id=s.id, date=d, status=statuses[(day + i) % len(statuses)]))
# A sample holiday on the 1st (kept only if not in the future).
try:
first = date(today.year, today.month, 1)
db.add(DayMark(date=first, kind="holiday", note="Month start holiday"))
except ValueError:
pass
db.commit()
def _ensure_columns() -> None:
"""Add columns introduced after a table was first created.
``create_all`` never alters existing tables, so on databases that already
have the ``attendance`` table we add the newer ``note`` column by hand.
"""
inspector = inspect(engine)
if "attendance" not in inspector.get_table_names():
return
cols = {c["name"] for c in inspector.get_columns("attendance")}
if "note" not in cols:
default = "''" if engine.dialect.name != "sqlite" else "''"
with engine.begin() as conn:
conn.execute(
text(f"ALTER TABLE attendance ADD COLUMN note TEXT NOT NULL DEFAULT {default}")
)
def init_db() -> None:
Base.metadata.create_all(bind=engine)
_ensure_columns()
db = SessionLocal()
try:
if db.query(AdminUser).count() == 0:
_seed(db)
finally:
db.close()