Merge branch 'phase/75-gradebook-ui'

# Conflicts:
#	docs/phases/13-grades/README.md
This commit is contained in:
Leonid Pershin
2026-08-21 14:02:32 +03:00
19 changed files with 801 additions and 21 deletions
+8 -8
View File
@@ -12,18 +12,18 @@
## Задачи
- [ ] Блок/вкладка на карточке ученика: недавние оценки по предметам и явка
- [ ] Короткая сводка класса (средний след / частые отсутствия) в Управлении или у класса —
- [x] Блок/вкладка на карточке ученика: недавние оценки по предметам и явка
- [x] Короткая сводка класса (средний след / частые отсутствия) в Управлении или у класса —
без простыни на год
- [ ] HTTP через мейлбокс; гость читает, не пишет
- [ ] Строки `t(...)`, обе локали
- [ ] Список людей в панели журнал не раздувает
- [x] HTTP через мейлбокс; гость читает, не пишет
- [x] Строки `t(...)`, обе локали
- [x] Список людей в панели журнал не раздувает
## Тесты, без которых фаза не закрыта
- [ ] Карточка отдаёт те же оценки/явку, что в мире
- [ ] Нет права править оценку через API
- [ ] Клиентский тест панели/вкладки (vitest) на пустое и заполненное состояние
- [x] Карточка отдаёт те же оценки/явку, что в мире
- [x] Нет права править оценку через API
- [x] Клиентский тест панели/вкладки (vitest) на пустое и заполненное состояние
## Критерий готовности
+1 -1
View File
@@ -23,7 +23,7 @@
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [75. Журнал на карточке](75-gradebook-ui.md) | 🔄 | HTTP, сводка класса |
| [75. Журнал на карточке](75-gradebook-ui.md) | | HTTP, сводка класса |
**Этап D — связность.**
+36 -2
View File
@@ -373,6 +373,14 @@ order as in the world and in `people.json`. Each row has `kind`, `kindLabel` (mo
and which kinds write live on `BehaviorDef` (`offenseMemoryMax`, `offenseMemoryKinds`), not in
the client. HTTP JSON is additive — no protocol version bump.
`lessonMarks` and `attendance` are the sparse gradebook on the person (stages A/B). Same order as
in the world and in `people.json`. Mark rows carry `subject`, `subjectLabel`, `value` (25),
`time`, `period`. Attendance rows carry `subject`, `subjectLabel`, `status`
(`present` / `late` / `absent`), `statusLabel` (mod locale), `time`, `period`, and optional
`absenceReason` (vanilla `truancy`; illness comes later). Empty is `[]`. Ceilings live on
`BehaviorDef` (`lessonMarkMax`, `attendanceMax`). There is **no** POST/PUT to set marks or
attendance — guests and owners only read. The people list does not include these fields.
```json
{
"id": "f0.c0",
@@ -439,6 +447,26 @@ the client. HTTP JSON is additive — no protocol version bump.
"otherFullName": "Иванов Кирилл Петрович"
}
],
"lessonMarks": [
{
"subject": "Mathematics",
"subjectLabel": "Математика",
"value": 5,
"time": "2012-04-03T10:05:00Z",
"period": 1
}
],
"attendance": [
{
"subject": "Mathematics",
"subjectLabel": "Математика",
"status": "present",
"statusLabel": "был",
"time": "2012-04-03T10:02:00Z",
"period": 1,
"absenceReason": null
}
],
"connections": {
"family": {
"parents": [
@@ -720,14 +748,20 @@ one.
"year": 5,
"letter": "А",
"classTeacherId": "f3.p1",
"classTeacherName": "Иванова Ольга Михайловна"
"classTeacherName": "Иванова Ольга Михайловна",
"averageMark": 3.8,
"absentLessons": 4,
"frequentAbsentees": 1
}
]
}
```
`classes` lists every homeroom with an optional class-teacher slot. `classTeacherId` /
`classTeacherName` are null when the slot is empty. Assign and clear (below) return this same
`classTeacherName` are null when the slot is empty. `averageMark` is the mean of recent lesson
marks across pupils in that class (`null` when none). `absentLessons` counts absent rows in
recent attendance memory; `frequentAbsentees` is how many pupils have at least three such
absences — a short Management summary, not a year sheet. Assign and clear (below) return this same
payload so the Management panel can refresh the slots without a second GET.
Applicants here are the same people as in `saves/{id}.people.json`. A parent keeps the same