empower-reports / modules /database.py
mikaelJ46's picture
Update modules/database.py
8e58acd verified
raw
history blame
8.06 kB
# modules/database.py
from sqlalchemy import create_engine, Column, Integer, String, Float, Text, ForeignKey, DateTime, Boolean, inspect, text
from sqlalchemy.orm import declarative_base, sessionmaker
from datetime import datetime
import hashlib
import os
from pathlib import Path
# Storage setup
IS_SPACES = os.environ.get('SPACE_ID') is not None
if IS_SPACES:
STORAGE_DIR = Path('/data')
STORAGE_DIR.mkdir(exist_ok=True)
DB_PATH = STORAGE_DIR / 'empower.db'
else:
STORAGE_DIR = Path('.')
DB_PATH = Path('empower.db')
# Database setup
ENGINE = create_engine(f'sqlite:///{DB_PATH}', connect_args={'check_same_thread': False})
Base = declarative_base()
Session = sessionmaker(bind=ENGINE)
# Models
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String, unique=True)
role = Column(String)
password_hash = Column(String)
subjects_taught = Column(String)
class_teacher_for = Column(String)
gender = Column(String)
phone_number = Column(String)
class Student(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True)
name = Column(String)
year = Column(Integer)
class_name = Column(String)
registration_number = Column(String)
subjects = Column(String)
subject_history = Column(Text)
gender = Column(String)
enrollment_date = Column(String)
class AcademicTerm(Base):
__tablename__ = 'academic_terms'
id = Column(Integer, primary_key=True)
year = Column(Integer)
term_number = Column(Integer)
term_name = Column(String)
start_date = Column(String)
end_date = Column(String)
next_term_begins = Column(String)
is_active = Column(Boolean, default=False)
class ComponentMark(Base):
__tablename__ = 'component_marks'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
subject = Column(String)
term_id = Column(Integer, ForeignKey('academic_terms.id'))
component_type = Column(String)
component_name = Column(String)
score = Column(Float)
total = Column(Float)
submitted_by = Column(Integer, ForeignKey('users.id'))
submitted_at = Column(String, default=lambda: datetime.now().isoformat())
class Mark(Base):
__tablename__ = 'marks'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
subject = Column(String)
term_id = Column(Integer, ForeignKey('academic_terms.id'))
coursework_score = Column(Float)
coursework_total = Column(Float)
coursework_out_of_20 = Column(Float)
midterm_score = Column(Float)
midterm_total = Column(Float)
midterm_out_of_20 = Column(Float)
endterm_score = Column(Float)
endterm_total = Column(Float)
endterm_out_of_60 = Column(Float)
total = Column(Float)
grade = Column(String)
comment = Column(Text)
submitted_by = Column(Integer, ForeignKey('users.id'))
submitted_at = Column(String, default=lambda: datetime.now().isoformat())
class DisciplineReport(Base):
__tablename__ = 'discipline_reports'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
reported_by = Column(Integer, ForeignKey('users.id'))
incident_date = Column(String)
incident_type = Column(String)
description = Column(Text)
action_taken = Column(Text)
status = Column(String, default="Pending")
admin_notes = Column(Text)
created_at = Column(String, default=lambda: datetime.now().isoformat())
class ReportDesign(Base):
__tablename__ = 'report_design'
id = Column(Integer, primary_key=True)
school_name = Column(String, default="EMPOWER INTERNATIONAL ACADEMY")
school_subtitle = Column(String, default="A Christian Boarding International School")
school_address = Column(String, default="Nswanjere - Off Kampala-Mityana Road")
school_po_box = Column(String, default="P.O BOX 1030, Kampala-Uganda")
school_phone = Column(String, default="")
school_email = Column(String, default="")
school_website = Column(String, default="")
logo_data = Column(Text)
primary_color = Column(String, default="#8B4513")
report_footer = Column(Text, default="")
class AuditLog(Base):
__tablename__ = 'audit_logs'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
action = Column(String)
details = Column(Text)
timestamp = Column(DateTime, default=datetime.utcnow)
class ClassroomBehavior(Base):
__tablename__ = 'classroom_behavior'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
term_id = Column(Integer, ForeignKey('academic_terms.id'))
evaluated_by = Column(Integer, ForeignKey('users.id'))
punctuality = Column(String)
attendance = Column(String)
manners = Column(String)
general_behavior = Column(String)
organisational_skills = Column(String)
adherence_to_uniform = Column(String)
leadership_skills = Column(String)
commitment_to_school = Column(String)
cooperation_with_peers = Column(String)
cooperation_with_staff = Column(String)
participation_in_lessons = Column(String)
completion_of_homework = Column(String)
evaluated_at = Column(String, default=lambda: datetime.now().isoformat())
class StudentDecision(Base):
__tablename__ = 'student_decisions'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
term_id = Column(Integer, ForeignKey('academic_terms.id'))
decision = Column(String)
decision_made_by = Column(Integer, ForeignKey('users.id'))
decision_date = Column(String, default=lambda: datetime.now().isoformat())
notes = Column(Text)
class VisitationDay(Base):
__tablename__ = 'visitation_days'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
term_id = Column(Integer, ForeignKey('academic_terms.id'))
visitation_date = Column(String)
parent_attended = Column(Boolean, default=False)
report_given = Column(Boolean, default=False)
notes = Column(Text)
created_by = Column(Integer, ForeignKey('users.id'))
created_at = Column(String, default=lambda: datetime.now().isoformat())
# Helper functions
def update_database_schema():
"""Update database schema with new tables and columns"""
inspector = inspect(ENGINE)
if 'visitation_days' not in inspector.get_table_names():
VisitationDay.__table__.create(ENGINE)
if 'student_decisions' not in inspector.get_table_names():
StudentDecision.__table__.create(ENGINE)
if 'component_marks' not in inspector.get_table_names():
ComponentMark.__table__.create(ENGINE)
def init_database():
"""Initialize database and create all tables"""
Base.metadata.create_all(ENGINE)
update_database_schema()
def init_admin():
"""Create default admin user if not exists"""
session = Session()
admin = session.query(User).filter_by(email='admin').first()
if not admin:
admin = User(
name='System Admin',
email='admin',
role='admin',
password_hash=hashlib.sha256('admin123'.encode()).hexdigest(),
subjects_taught='',
class_teacher_for='',
gender='',
phone_number=''
)
session.add(admin)
session.commit()
session.close()
def init_report_design():
"""Initialize report design if not exists"""
session = Session()
design = session.query(ReportDesign).first()
if not design:
design = ReportDesign()
session.add(design)
session.commit()
session.close()
def log_audit(session, user_id, action, details=""):
"""Log an audit entry"""
log = AuditLog(user_id=user_id, action=action, details=details)
session.add(log)
session.commit()