"""Public content endpoints — read the site, submit an enquiry. These are all unauthenticated (the public site consumes them). """ from __future__ import annotations from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.db import get_db from app.models import ( Course, Enquiry, FeePlan, Profile, Review, SiteSettings, Subject, Testimonial, ) from app.schemas import ( CourseOut, EnquiryIn, EnquiryOut, FeePlanOut, ProfileOut, ReviewIn, ReviewOut, SiteSettingsOut, SubjectOut, TestimonialOut, ) router = APIRouter() def _get_or_create_profile(db: Session) -> Profile: obj = db.query(Profile).first() if not obj: obj = Profile() db.add(obj) db.commit() db.refresh(obj) return obj def _get_or_create_settings(db: Session) -> SiteSettings: obj = db.query(SiteSettings).first() if not obj: obj = SiteSettings() db.add(obj) db.commit() db.refresh(obj) return obj @router.get("/profile", response_model=ProfileOut) def get_profile(db: Session = Depends(get_db)) -> Profile: return _get_or_create_profile(db) @router.get("/subjects", response_model=list[SubjectOut]) def list_subjects(db: Session = Depends(get_db)) -> list[Subject]: return db.query(Subject).order_by(Subject.sort_order, Subject.id).all() @router.get("/courses", response_model=list[CourseOut]) def list_courses(db: Session = Depends(get_db)) -> list[Course]: return db.query(Course).order_by(Course.sort_order, Course.id).all() @router.get("/fees", response_model=list[FeePlanOut]) def list_fees(db: Session = Depends(get_db)) -> list[FeePlan]: return db.query(FeePlan).order_by(FeePlan.sort_order, FeePlan.id).all() @router.get("/testimonials", response_model=list[TestimonialOut]) def list_testimonials(db: Session = Depends(get_db)) -> list[Testimonial]: return db.query(Testimonial).order_by(Testimonial.sort_order, Testimonial.id).all() @router.get("/settings", response_model=SiteSettingsOut) def get_settings(db: Session = Depends(get_db)) -> SiteSettings: return _get_or_create_settings(db) @router.get("/reviews", response_model=list[ReviewOut]) def list_public_reviews(db: Session = Depends(get_db)) -> list[Review]: """Only approved reviews are shown on the public site.""" return ( db.query(Review) .filter(Review.is_approved.is_(True)) .order_by(Review.created_at.desc(), Review.id.desc()) .all() ) @router.post("/reviews", response_model=ReviewOut, status_code=201) def create_review(body: ReviewIn, db: Session = Depends(get_db)) -> Review: """Public submission — stored unapproved until the teacher approves it.""" rating = max(1, min(5, body.rating)) obj = Review( author_name=body.author_name.strip() or "Anonymous", relation=body.relation, rating=rating, message=body.message, is_approved=False, ) db.add(obj) db.commit() db.refresh(obj) return obj @router.post("/enquiries", response_model=EnquiryOut, status_code=201) def create_enquiry(body: EnquiryIn, db: Session = Depends(get_db)) -> Enquiry: obj = Enquiry( name=body.name, email=body.email, phone=body.phone, subject_interest=body.subject_interest, message=body.message, ) db.add(obj) db.commit() db.refresh(obj) return obj