Fix UI bugs, admin bulk upload limits, test ingestion bugs, and reset demo users
This commit is contained in:
1832
backend/jee_advanced_full_90q.json
Normal file
1832
backend/jee_advanced_full_90q.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -236,9 +236,13 @@ async def bulk_register_students(file: UploadFile = File(...), session: Session
|
||||
decoded = content.decode('utf-8-sig')
|
||||
csv_reader = csv.DictReader(io.StringIO(decoded))
|
||||
|
||||
rows = list(csv_reader)
|
||||
if len(rows) > 500:
|
||||
raise HTTPException(status_code=400, detail="Maximum limit of 500 users per bulk registration exceeded.")
|
||||
|
||||
results = []
|
||||
|
||||
for row in csv_reader:
|
||||
for row in rows:
|
||||
email = row.get("email", "").strip()
|
||||
name = row.get("name", "").strip()
|
||||
phone = row.get("phone", "").strip()
|
||||
@@ -436,7 +440,7 @@ def login(payload: LoginPayload, session: Session = Depends(get_session)):
|
||||
# --- CBT ENGINE ---
|
||||
|
||||
@app.get("/api/tests", response_model=List[models.Test], tags=["CBT Engine"])
|
||||
def list_active_tests(exam_pattern: Optional[str] = None, type: Optional[str] = None, session: Session = Depends(get_session), current_user: models.User = Depends(require_tier([models.TierEnum.PRO, models.TierEnum.AI_COACH]))):
|
||||
def list_active_tests(exam_pattern: Optional[str] = None, type: Optional[str] = None, session: Session = Depends(get_session), current_user: models.User = Depends(get_current_user)):
|
||||
query = select(models.Test).where(models.Test.is_active == True)
|
||||
if exam_pattern:
|
||||
if exam_pattern == 'JEE_NEET':
|
||||
@@ -450,14 +454,14 @@ def list_active_tests(exam_pattern: Optional[str] = None, type: Optional[str] =
|
||||
return session.exec(query).all()
|
||||
|
||||
@app.get("/api/tests/{test_id}", response_model=models.Test, tags=["CBT Engine"])
|
||||
def get_test_by_id(test_id: UUID, user_id: Optional[UUID] = None, session: Session = Depends(get_session), current_user: models.User = Depends(require_tier([models.TierEnum.PRO, models.TierEnum.AI_COACH]))):
|
||||
def get_test_by_id(test_id: UUID, user_id: Optional[UUID] = None, session: Session = Depends(get_session), current_user: models.User = Depends(get_current_user)):
|
||||
test = session.get(models.Test, test_id)
|
||||
if not test:
|
||||
raise HTTPException(status_code=404, detail="Requested examination structure not found.")
|
||||
return test
|
||||
|
||||
@app.get("/api/tests/{test_id}/questions", response_model=List[models.Question], tags=["CBT Engine"])
|
||||
def get_questions_by_test_id(test_id: UUID, session: Session = Depends(get_session), current_user: models.User = Depends(require_tier([models.TierEnum.PRO, models.TierEnum.AI_COACH]))):
|
||||
def get_questions_by_test_id(test_id: UUID, session: Session = Depends(get_session), current_user: models.User = Depends(get_current_user)):
|
||||
test = session.get(models.Test, test_id)
|
||||
if not test:
|
||||
raise HTTPException(status_code=404, detail="Requested examination structure not found.")
|
||||
@@ -498,7 +502,7 @@ def get_question_by_id(question_id: UUID, session: Session = Depends(get_session
|
||||
return question
|
||||
|
||||
@app.post("/api/attempts/submit", response_model=models.Attempt, tags=["CBT Engine"])
|
||||
def submit_test_attempt(payload: Dict[str, Any], session: Session = Depends(get_session), current_user: models.User = Depends(require_tier([models.TierEnum.PRO, models.TierEnum.AI_COACH]))):
|
||||
def submit_test_attempt(payload: Dict[str, Any], session: Session = Depends(get_session), current_user: models.User = Depends(get_current_user)):
|
||||
user_id = payload.get("user_id")
|
||||
source_type_raw = payload.get("source_type", "Test")
|
||||
source_id = payload.get("source_id")
|
||||
|
||||
3782
backend/neet_180_questions.json
Normal file
3782
backend/neet_180_questions.json
Normal file
File diff suppressed because it is too large
Load Diff
30
backend/reset_demo_users.py
Normal file
30
backend/reset_demo_users.py
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
from uuid import UUID
|
||||
from sqlmodel import Session
|
||||
from database import engine
|
||||
import models
|
||||
from main import ensure_demo_user
|
||||
|
||||
demo_ids = [
|
||||
UUID("11111111-1111-1111-1111-111111111111"),
|
||||
UUID("22222222-2222-2222-2222-222222222222"),
|
||||
UUID("33333333-3333-3333-3333-333333333333"),
|
||||
UUID("44444444-4444-4444-4444-444444444444")
|
||||
]
|
||||
|
||||
with Session(engine) as session:
|
||||
for uid in demo_ids:
|
||||
existing = session.get(models.User, uid)
|
||||
if existing:
|
||||
print(f"Deleting {existing.name}...")
|
||||
session.exec(models.Subscription.__table__.delete().where(models.Subscription.user_id == uid))
|
||||
session.exec(models.Mistake.__table__.delete().where(models.Mistake.user_id == uid))
|
||||
session.exec(models.Attempt.__table__.delete().where(models.Attempt.user_id == uid))
|
||||
session.exec(models.StudyPlan.__table__.delete().where(models.StudyPlan.user_id == uid))
|
||||
session.exec(models.Transaction.__table__.delete().where(models.Transaction.user_id == uid))
|
||||
session.delete(existing)
|
||||
session.commit()
|
||||
|
||||
user = ensure_demo_user(uid, session)
|
||||
print(f"Recreated: {user.name}")
|
||||
|
||||
64
backend/upload_test.py
Normal file
64
backend/upload_test.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import sys
|
||||
sys.path.append('.')
|
||||
from sqlmodel import Session, select
|
||||
from database import engine
|
||||
from models import User, Test, Question, QuestionTypeEnum, ExamEnum
|
||||
|
||||
def upload_json():
|
||||
import json
|
||||
|
||||
with open('neet_180_questions.json', 'r', encoding='utf-8') as f:
|
||||
questions = json.load(f)
|
||||
|
||||
with Session(engine) as session:
|
||||
admin = session.exec(select(User).where(User.tier == 'AI Coach')).first()
|
||||
if not admin:
|
||||
print('No admin found')
|
||||
return
|
||||
|
||||
payload = {
|
||||
'title': 'Test NEET Mock Upload',
|
||||
'type': 'Mock',
|
||||
'exam_pattern': 'NEET',
|
||||
'time_limit': 180,
|
||||
'admin_id': str(admin.id),
|
||||
'questions_json': questions
|
||||
}
|
||||
|
||||
test_obj = Test(
|
||||
title=payload['title'],
|
||||
type=payload['type'],
|
||||
exam_pattern=ExamEnum.NEET,
|
||||
sections={},
|
||||
total_time=payload['time_limit'],
|
||||
difficulty='Hard',
|
||||
is_active=True,
|
||||
created_by=admin.id
|
||||
)
|
||||
session.add(test_obj)
|
||||
session.flush()
|
||||
|
||||
for q in questions:
|
||||
q_obj = Question(
|
||||
subject=q.get('subject'),
|
||||
topic=q.get('topic', 'General'),
|
||||
subtopic=q.get('subtopic', ''),
|
||||
difficulty=q.get('difficulty', 'Medium'),
|
||||
type=QuestionTypeEnum(q.get('type', 'SCQ')),
|
||||
question_text=q.get('question_text', ''),
|
||||
options_json=q.get('options', []),
|
||||
correct_answer=q.get('correct_answer', ''),
|
||||
solution_text=q.get('explanation', ''), language='English',
|
||||
test_id=test_obj.id, created_by=admin.id,
|
||||
section_name=q.get('subject')
|
||||
)
|
||||
session.add(q_obj)
|
||||
|
||||
session.commit()
|
||||
print('Successfully added test with ID:', test_obj.id)
|
||||
|
||||
upload_json()
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user