129 lines
3.4 KiB
Python
129 lines
3.4 KiB
Python
"""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
|