Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ Thumbs.db
venv/
env/
.venv/

TutorAI/lib/
TutorAI/pyvenv.cfg
TutorAI/bin/
30 changes: 30 additions & 0 deletions app/api/v1/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"programs": {
"AI-BOOTCAMP": {
"default_frequency": "weekly",
"groups": {
"AI-101": {
"frequency": "biweekly",
"start_date": "2025-10-28"
},
"AI-102": {
"frequency": "weekly",
"start_date": "2025-10-21"
}
}
},
"ML-BASICS": {
"default_frequency": "weekly",
"groups": {
"ML-101": {
"frequency": "biweekly",
"start_date": "2025-10-17"
},
"ML-102": {
"frequency": "weekly",
"start_date": "2025-11-01"
}
}
}
}
}
54 changes: 54 additions & 0 deletions app/api/v1/facts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from fastapi import APIRouter, Depends
from app.core.database import get_db
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.models.education import Assignment
from datetime import datetime, timedelta, timezone

import json
from pathlib import Path

MOSCOW_TZ = timezone(timedelta(hours=3))

def get_days_ago_start(days_ago: int):
now_msk = datetime.now(MOSCOW_TZ)
target_date = now_msk - timedelta(days=days_ago)
target_date = target_date.replace(hour=0, minute=0, second=0, microsecond=0)
return target_date

# Получение фактов недели на студента
router = APIRouter(prefix="/students", tags=["students"])

@router.get("/facts")
async def get_weekly_facts(student_id: str = None, period: int = 7, db: AsyncSession = Depends(get_db)):
# period_start = get_days_ago_start(period)
# query = select(Assignment).where(Assignment.submitted_at >= period_start)

# if student_id:
# query = query.where(Assignment.student_id == student_id)

# result = await db.execute(query)
# facts = result.scalars.all()

# return [{
# "id": a.student_id,
# "grade": a.grade,
# "submitted_at": a.submitted_at
# }
# for a in facts]

mock_path = Path("app/api/v1/mock.json")
mock_data = json.loads(mock_path.read_text())

student = next((s for s in mock_data["students"] if s["student_id"] == student_id), None)
if not student:
return {"error": f"Student with id {student_id} not found"}

return [
{
"id": student["student_id"],
"grade": a["grade"],
"submitted_at": a["submitted_at"]
}
for a in student["assignments"]
]
38 changes: 38 additions & 0 deletions app/api/v1/get_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.models.education import Stream
import json
from pathlib import Path

router = APIRouter(prefix="/config", tags=["config"])

@router.get("/")
async def get_group_config(program_id: str = None, group_id: str = None, db: Session = Depends(get_db)):
config_path = Path("app/api/v1/config.json")
config = json.loads(config_path.read_text())

# Загружаем базовую структуру
if not program_id:
return config

program = config["programs"].get(program_id)
if not program:
return {"error": "Program not found"}

if not group_id:
return program

group = program.get("groups", {}).get(group_id)
if not group:
return {"error": "Group not found"}

# Получаем дату начала из базы
stream = db.query(Stream).filter(Stream.name == group_id).first()
start_date = stream.start_date if stream else None

final = program.copy()
if group:
final.update(group)
final["start_date"] = str(start_date) if start_date else None
return final
63 changes: 63 additions & 0 deletions app/api/v1/listeners.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.models.education import Stream

router = APIRouter(prefix="/students", tags=["students"])

@router.get("/")
async def get_students(group_id: str, db: Session = Depends(get_db)):
"""
Возвращает список студентов по названию группы (stream.stream_id = group_id)
"""

if group_id == "AI-102":
return [
{
"student_id": "st_001",
"group_id": group_id
},
{
"student_id": "st_002",
"group_id": group_id
},
{
"student_id": "st_003",
"group_id": group_id
},
{
"student_id": "st_004",
"group_id": group_id
},
{
"student_id": "st_005",
"group_id": group_id
}
]
if group_id == "ML-102":
return [
{
"student_id": "st_101",
"group_id": group_id
},
{
"student_id": "st_102",
"group_id": group_id
},
{
"student_id": "st_103",
"group_id": group_id
},
{
"student_id": "st_104",
"group_id": group_id
},
{
"student_id": "st_105",
"group_id": group_id
}
]
# Ищем поток по имени (названию группы)
# stream = db.query(Stream).filter(Stream.stream_id == group_id).first()

# return [{"student_id": s.student_id} for s in stream.students]
174 changes: 174 additions & 0 deletions app/api/v1/mock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
{
"students": [
{
"student_id": "st_101",
"name": "Alice Johnson",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_001",
"grade": 88,
"submitted_at": "2025-11-03T14:32:00Z"
},
{
"id": "as_002",
"grade": 95,
"submitted_at": "2025-11-07T10:18:00Z"
}
]
},
{
"student_id": "st_102",
"name": "Michael Smith",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_010",
"grade": 76,
"submitted_at": "2025-11-04T09:40:00Z"
},
{
"id": "as_011",
"grade": 82,
"submitted_at": "2025-11-06T15:10:00Z"
},
{
"id": "as_012",
"grade": 79,
"submitted_at": "2025-11-08T11:55:00Z"
}
]
},
{
"student_id": "st_103",
"name": "Sofia Martinez",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_020",
"grade": 90,
"submitted_at": "2025-11-02T13:22:00Z"
},
{
"id": "as_021",
"grade": 93,
"submitted_at": "2025-11-05T08:40:00Z"
}
]
},
{
"student_id": "st_104",
"name": "David Lee",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_030",
"grade": 100,
"submitted_at": "2025-11-01T16:05:00Z"
},
{
"id": "as_031",
"grade": 97,
"submitted_at": "2025-11-06T19:30:00Z"
}
]
},
{
"student_id": "st_105",
"name": "Emma Brown",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_040",
"grade": 65,
"submitted_at": "2025-11-03T12:00:00Z"
}
]
},
{
"student_id": "st_001",
"name": "Alice Johnson",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_001",
"grade": 88,
"submitted_at": "2025-11-03T14:32:00Z"
},
{
"id": "as_002",
"grade": 95,
"submitted_at": "2025-11-07T10:18:00Z"
}
]
},
{
"student_id": "st_002",
"name": "Michael Smith",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_010",
"grade": 76,
"submitted_at": "2025-11-04T09:40:00Z"
},
{
"id": "as_011",
"grade": 82,
"submitted_at": "2025-11-06T15:10:00Z"
},
{
"id": "as_012",
"grade": 79,
"submitted_at": "2025-11-08T11:55:00Z"
}
]
},
{
"student_id": "st_003",
"name": "Sofia Martinez",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_020",
"grade": 90,
"submitted_at": "2025-11-02T13:22:00Z"
},
{
"id": "as_021",
"grade": 93,
"submitted_at": "2025-11-05T08:40:00Z"
}
]
},
{
"student_id": "st_004",
"name": "David Lee",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_030",
"grade": 100,
"submitted_at": "2025-11-01T16:05:00Z"
},
{
"id": "as_031",
"grade": 97,
"submitted_at": "2025-11-06T19:30:00Z"
}
]
},
{
"student_id": "st_005",
"name": "Emma Brown",
"group_id": "group_2025_B",
"assignments": [
{
"id": "as_040",
"grade": 65,
"submitted_at": "2025-11-03T12:00:00Z"
}
]
}
]
}
2 changes: 1 addition & 1 deletion app/api/v1/students.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

@router.get("/")
async def get_students():
return {"message": "Students API - coming soon"}
return {"message": "Students API - coming soon"}
Loading