Choosing what you are studying for has no way past it now but to answer. It decides which questions exist, how relevance is weighted and what readiness measures against, so an account that never answered it was being shown the whole bank by accident rather than by choice. What is guarded instead is asking a question that cannot be answered: if the list of objectives fails to load, or there are none, nothing is shown at all. A modal with no options in it is not a question, it is a locked door. GET /api/public/stats, unauthenticated, so the landing page can state what there is rather than what someone typed into the markup months ago — a number written into a page goes stale the week after and nothing breaks to say so. Counts only, and only of published material: how much there is, never what it is, so there is nothing here to walk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
"""The few facts the site may state about itself before anybody signs in.
|
|
|
|
Counts only, and only of published material. No titles, no ids, nothing that
|
|
could be walked to enumerate the bank — a landing page needs to say how much
|
|
there is, not what it is.
|
|
|
|
Unauthenticated on purpose: it is read by the page a stranger lands on.
|
|
"""
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import func
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.database import get_db
|
|
from app.models.article import Article
|
|
from app.models.exam import Exam
|
|
from app.models.question import Question
|
|
from app.models.question_category import QuestionCategory
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/stats")
|
|
def public_stats(db: Session = Depends(get_db)):
|
|
"""What the landing page says there is, taken from what there is.
|
|
|
|
A number written into the markup is a number that goes stale the week
|
|
after it is written, and nobody notices because nothing breaks.
|
|
"""
|
|
questions = db.query(func.count(Question.id)).filter(
|
|
Question.deleted_at.is_(None)).scalar() or 0
|
|
topics = db.query(func.count(QuestionCategory.id)).scalar() or 0
|
|
systems = db.query(func.count(func.distinct(QuestionCategory.system_id))).filter(
|
|
QuestionCategory.system_id.isnot(None)).scalar() or 0
|
|
articles = db.query(func.count(Article.id)).filter(
|
|
Article.status == "published").scalar() or 0
|
|
exams = db.query(func.count(Exam.id)).filter(Exam.is_active == 1).scalar() or 0
|
|
return {
|
|
"questions": questions,
|
|
"topics": topics,
|
|
"systems": systems,
|
|
"articles": articles,
|
|
"exams": exams,
|
|
}
|