Add timetable planning and related tests to school simulation
ci / server (push) Failing after 3m33s
ci / client (push) Successful in 13s

- Introduced a new project for timetable planning, dependent on HSchool.Content.
- Updated documentation to reflect the addition of timetable planning and its dependencies.
- Added tests for timetable planning to ensure deterministic behavior with the same staff and map.
- Revised architecture documentation to include the new HSchool.Schedule component and its interactions.
This commit is contained in:
Leonid Pershin
2026-08-19 00:55:02 +03:00
parent 2ebc783585
commit 2011d12b1d
12 changed files with 731 additions and 16 deletions
+5 -2
View File
@@ -34,14 +34,17 @@ there is no UI on the server.
| --- | --- |
| `src/HSchool.Protocol` | Binary wire format. No dependencies, referenced by everything that talks to the socket. |
| `src/HSchool.Content` | JSONC defs, inheritance, patches, locales, map instance and connectivity. No Arch, no ASP.NET. |
| `src/HSchool.People` | Roster generation from catalog, map and seed. No Arch, no ASP.NET. |
| `src/HSchool.Schedule` | Timetable from curriculum, assignments and map. No Arch, no ASP.NET. |
| `src/HSchool.Simulation` | Schools, the game clock, the Arch ECS world. Holds a frozen catalog and map; no HTTP. |
| `src/HSchool.Server` | ASP.NET Core host: the menu API, the WebSocket endpoint, per-school workers, `mods/` and `saves/`. |
| `src/HSchool.ServiceDefaults` | Shared Aspire wiring: OpenTelemetry, health checks, service discovery, resilience. |
| `src/HSchool.AppHost` | Aspire orchestration: which resources run and how they find each other. |
| `src/HSchool.Client` | Vite + TypeScript UI: main menu, creation form, the school screen. |
Dependency direction is one-way: `Protocol ← Server → Simulation → Content`. Nothing in
`Simulation` or `Content` knows about HTTP, and nothing in `Protocol` knows about schools.
Dependency direction is one-way: `Protocol ← Server → Simulation → People → Content`, and
`Schedule → Content`. Nothing in `Simulation` or `Content` knows about HTTP, and nothing in
`Protocol` knows about schools.
## Two channels, on purpose
+3
View File
@@ -9,6 +9,7 @@
Protocol — ни на кого из игровых проектов (только байты)
Content — ни на Protocol, ни на Simulation, ни на ASP.NET
People → Content (defs, карта, склонения; без Arch и хоста)
Schedule → Content (раскладка уроков; без Arch и хоста)
Simulation → People, Content (ростер в World; без HTTP)
Server → Protocol, Simulation, People, Content
Client — своя сторона Protocol (TS) + HTTP
@@ -22,6 +23,7 @@ Client — своя сторона Protocol (TS) + HTTP
| --- | --- | --- |
| **HSchool.Content** | Типы def, JSONC-загрузчик, наследование, патчи, слияние локалей, граф карты, валидация связности | Arch, часы, HTTP, потоки, пути `mods/` с диска хоста |
| **HSchool.People** | Генерация ростера: семьи, классы, тело/навыки/черты из каталога и сида | Arch, ASP.NET, сокеты, `DateTime.Now`, файлы сейва |
| **HSchool.Schedule** | Раскладка учебного плана в таблицу уроков вокруг закреплённых правок | Arch, ASP.NET, сокеты, `DateTime.Now`, файлы сейва |
| **HSchool.Simulation** | `School`, `GameClock`, Arch `World`, тик, применение раскладки к миру | Kestrel, сокеты, `Directory.Enumerate`, сейв-файлы |
| **HSchool.Server** | Хост, супервизор, работник-поток, `mods/` и `saves/` из конфига, HTTP/WS, DTO запросов | Правила «комната должна быть связана», схема Chair |
| **HSchool.Protocol** | Кадры сокета, в том числе снимок карты и locale в Hello | Имена комнат, JSONC |
@@ -49,6 +51,7 @@ Arch и фиксированный тик — про живую школу. Па
- `tests/HSchool.Content.Tests` — фикстуры JSONC, коллизии имён, дырявый граф, двор обязателен.
- `tests/HSchool.People.Tests` — тот же сид даёт тот же ростер; места и должности заполнены.
- `tests/HSchool.Schedule.Tests` — тот же штат и карта дают ту же таблицу; четыре запрета.
- `HSchool.Simulation.Tests` — часы, тик, «школа с таким каталогом живёт».
- `HSchool.AppHost.Tests` — create с картой, рестарт, сейв на диске.
+13 -13
View File
@@ -12,24 +12,24 @@
## Задачи
- [ ] Новый проект рядом с `HSchool.People`: зависит только на `HSchool.Content`, без Arch и
- [x] Новый проект рядом с `HSchool.People`: зависит только на `HSchool.Content`, без Arch и
ASP.NET; отдаёт простую таблицу уроков
- [ ] Раскладка часов учебного плана по слотам недели для каждого класса
- [ ] Кабинет урока: требование предмета, иначе кабинет класса
- [ ] Четыре запрета соблюдаются: учитель, класс и кабинет не заняты дважды, класс влезает в кабинет
- [ ] Непокрытые часы не ставятся, а возвращаются отдельным списком — их покажет «Управление»
- [ ] Закреплённые игроком уроки принимаются на вход и переживают перестроение; остальное
- [x] Раскладка часов учебного плана по слотам недели для каждого класса
- [x] Кабинет урока: требование предмета, иначе кабинет класса
- [x] Четыре запрета соблюдаются: учитель, класс и кабинет не заняты дважды, класс влезает в кабинет
- [x] Непокрытые часы не ставятся, а возвращаются отдельным списком — их покажет «Управление»
- [x] Закреплённые игроком уроки принимаются на вход и переживают перестроение; остальное
раскладывается вокруг них
- [ ] Детерминированность: те же штат, назначения и карта дают ту же таблицу
- [x] Детерминированность: те же штат, назначения и карта дают ту же таблицу
## Тесты, без которых фаза не закрыта
- [ ] Один спортзал на одиннадцать классов — физкультура разъезжается по слотам, а не дублируется
- [ ] Учитель с двумя предметами не стоит в двух местах в одном слоте
- [ ] Класс на 16 не попадает в кабинет на 12
- [ ] Предмет без учителя даёт дыру и запись в непокрытых
- [ ] Закреплённый урок остаётся на месте после найма ещё одного учителя
- [ ] Те же входы — та же таблица
- [x] Один спортзал на одиннадцать классов — физкультура разъезжается по слотам, а не дублируется
- [x] Учитель с двумя предметами не стоит в двух местах в одном слоте
- [x] Класс на 16 не попадает в кабинет на 12
- [x] Предмет без учителя даёт дыру и запись в непокрытых
- [x] Закреплённый урок остаётся на месте после найма ещё одного учителя
- [x] Те же входы — та же таблица
## Критерий готовности
+1 -1
View File
@@ -65,6 +65,6 @@
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [14. Каркас дня и каникулы](14-school-calendar.md) | ✅ | Звонки, длина недели, каникулы |
| [15. Планировщик](15-timetable-planner.md) | | Раскладка часов по слотам, четыре запрета |
| [15. Планировщик](15-timetable-planner.md) | | Раскладка часов по слотам, четыре запрета |
| [16. Расписание в школе](16-timetable-in-school.md) | ⬜ | Сейв, снимок, «кто где сейчас» |
| [17. Расписание на экране](17-timetable-screen.md) | ⬜ | Скобки в дереве, сетка класса, расписание учителя |