Remove off-queue.md and add new design documentation files including README.md, defs.md, near-term.md, projects.md, runtime.md, people.md, staffing.md, and schedule.md to outline the structure and agreements for the game's design phases.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Фаза 10. Предметы и мебель
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 5](../02-people/05-people-defs.md)
|
||||
- [Фаза 7](../02-people/07-people-in-school.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Каталог учится описывать предметы, кабинет перестаёт быть таблицей слотов, а должность учителя
|
||||
становится одной на всех. Людей это ещё не двигает: школа собирается как прежде.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [x] `SubjectDef` в `HSchool.Content`: развиваемые навыки с долями, диапазон параллелей;
|
||||
ссылка на неизвестный навык — ошибка загрузки
|
||||
- [x] Ванильные предметы в `core`: начальные классы (1–4, всё понемногу) и предметники по
|
||||
существующим навыкам, включая физкультуру
|
||||
- [x] `PositionDef PETeacher` упраздняется; `Classroom`, `ComputerLab` и `GymHall` больше не
|
||||
открывают учительскую должность
|
||||
- [x] Кабинет-`Homeroom` описывается числом мест, а не таблицей именованных слотов; вместимость
|
||||
по-прежнему считается по мебели
|
||||
- [x] Слоты остаются у столовой, медкабинета, кабинета директора и библиотеки
|
||||
- [x] Редактор карты показывает у кабинета одно поле «мест», у прочих комнат — прежние слоты
|
||||
- [x] Ванильная карта переписана под новую форму, вместимость параллелей не изменилась
|
||||
- [x] `GET /api/catalog` отдаёт предметы — они понадобятся форме назначения
|
||||
- [x] Стартовая дата по умолчанию — суббота 31 марта 2012
|
||||
- [x] Снимок карты и `docs/protocol.md` правятся в том же коммите, если меняется раскладка узла
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Каталог `core` грузится, предметы проходят валидацию, тест на полноту локалей зелёный
|
||||
- Школа на ванильной карте даёт те же одиннадцать классов и ту же вместимость, что и до фазы
|
||||
- Редактор карты не показывает у кабинета ни доски, ни стула учителя
|
||||
- `dotnet test` и клиентские `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не трогать наём. Генератор пока закрывает должности сам — школа опустеет в следующей фазе.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Фаза 11. Пустая школа и пул соискателей
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 10](10-subjects.md)
|
||||
- [Фаза 6](../02-people/06-people-generator.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Школа открывается без единого сотрудника, а рядом появляется пул людей, готовых наняться.
|
||||
Нанимать пока нечем — это фаза про данные.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [x] `RosterGenerator` больше не закрывает должности: новая школа получает учеников, родителей
|
||||
и ноль сотрудников
|
||||
- [x] Пул соискателей в `HSchool.People`: список полноценных `Person`, детерминированный от сида
|
||||
школы и номера недели
|
||||
- [x] Соискателем может стать родитель ученика — тот же человек, без второй сущности
|
||||
- [x] Базовый запрос по зарплате считается из навыков соискателя; шкала — в данных, не в коде
|
||||
- [x] Еженедельное обновление: часть уходит, часть остаётся с теми же именами и запросом,
|
||||
приходят новые. Полная замена запрещена
|
||||
- [x] Пул живёт в `saves/{id}.people.json` рядом с ростером и пишется по тем же правилам —
|
||||
при изменении состава, не по таймеру
|
||||
- [x] Воркер публикует пул вместе со снимком ростера
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [x] Тот же сид и та же неделя — тот же пул
|
||||
- [x] После обновления часть людей та же самая, с теми же навыками и тем же запросом
|
||||
- [x] Пул не пустеет и не растёт бесконечно за пятьдесят недель
|
||||
- [x] Запрос по зарплате у сильного кандидата выше, чем у слабого
|
||||
- [x] Новая школа не имеет ни одного сотрудника, но все ученические места заняты
|
||||
- [x] Соискатель не попадает в ростер школы, пока не нанят
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Создать школу — в списке людей есть ученики и родители, работников нет
|
||||
- Перезапуск сервера поднимает тот же пул
|
||||
- `dotnet test` проходит
|
||||
|
||||
## Стоп
|
||||
|
||||
Ни найма, ни денег, ни назначения предметов. Пул только существует и обновляется.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Фаза 12. Наём, предметы и предел бюджета
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 11](11-applicants.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Игрок нанимает людей и раздаёт предметы, а выделенная сумма ограничивает, сколько он может себе
|
||||
позволить. Экрана ещё нет — всё через API.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [x] Выделяемая на месяц сумма — в `SimulationOptions`, с умолчанием
|
||||
- [x] Фонд оплаты школы: у каждого цена часа × недельная нагрузка, но не меньше одной ставки.
|
||||
Нагрузка берётся из учебного плана и делится между учителями предмета
|
||||
- [x] Наём: соискатель уходит из пула, становится работником, попадает в ростер. Родитель
|
||||
остаётся родителем — новой сущности не заводится
|
||||
- [x] Назначение предмета нанятому и снятие предмета
|
||||
- [x] Предел проверяется **в момент действия**: наём или назначение, выводящее фонд за
|
||||
выделенную сумму, отклоняется с внятным кодом ошибки, а не откладывается до конца месяца
|
||||
- [x] Покрытие предметов: какие предметы преподаются в существующих параллелях и не имеют ни
|
||||
одного учителя
|
||||
- [x] `GET /api/schools/{id}/staffing` — деньги, покрытие, пул и штат; читает опубликованный
|
||||
снимок, воркер не трогает
|
||||
- [x] Наём и назначение идут в воркер через мейлбокс с `TaskCompletionSource`, как create и delete
|
||||
- [x] Состав пишется на диск при изменении, снимок публикуется заново
|
||||
- [x] `docs/protocol.md` пополняется в том же коммите, что и обработчики
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Нанять двоих на 3 000 и 7 000 при выделенных 10 000 — третий наём отклонён
|
||||
- Снять предмет — фонд уменьшился, наём снова возможен
|
||||
- Назначение, не влезающее в предел, отклонено, и в ответе видно почему
|
||||
- Перезапуск сервера поднимает школу с тем же штатом и теми же назначениями
|
||||
- Тесты API: наём, повторный наём того же человека, отклонение по пределу, неизвестная школа,
|
||||
неизвестный соискатель
|
||||
- `dotnet test` проходит
|
||||
|
||||
## Стоп
|
||||
|
||||
Не увольнять. Не платить зарплату по месяцам — предел проверяется, деньги не движутся.
|
||||
Не расписание.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Фаза 13. Раздел «Управление»
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 12](12-hiring-budget.md)
|
||||
- [Фаза 8](../02-people/08-people-browser.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Игрок собирает школу руками: видит деньги, перебирает соискателей, нанимает и раздаёт предметы.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [x] Под часами появляются два верхних раздела: «Обзор» и «Управление». В «Обзоре» — всё, что
|
||||
есть сейчас; часы и дата видны в обоих
|
||||
- [x] Строка денег: выделено, расписано, свободно
|
||||
- [x] Список непокрытых предметов — что школа не может преподавать
|
||||
- [x] Список соискателей: имя, запрашиваемая ставка, сильные навыки; выбор показывает карточку
|
||||
человека справа — ту же, что в «Людях»
|
||||
- [x] Кнопка найма; отказ по пределу показывается текстом, а не молчанием
|
||||
- [x] Список штата: кто нанят, какие предметы ведёт, сколько стоит
|
||||
- [x] Назначение и снятие предмета с карточки нанятого
|
||||
- [x] Строки через `t(...)`, обе локали
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Создать школу, открыть «Управление», нанять учителя, назначить ему математику
|
||||
- Дойти до предела — попытка нанять ещё одного объясняет, что денег нет
|
||||
- Снять предмет и убедиться, что свободных денег стало больше
|
||||
- Перейти в «Обзор» → «Люди» и увидеть нанятого в общем списке с ролью работника
|
||||
- Нанять родителя ученика и увидеть у него обе роли на одной карточке
|
||||
- `dotnet test` и клиентские `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не увольнять из интерфейса. Не показывать расписание и нагрузку по часам — только предметы.
|
||||
@@ -0,0 +1,18 @@
|
||||
Индекс срезов: [`../README.md`](../README.md).
|
||||
|
||||
## Срез 3. Штат
|
||||
|
||||
Дизайн: [`../design/staffing.md`](../../design/03-staffing/staffing.md).
|
||||
|
||||
Первый срез, где игрок принимает решения. Школа открывается пустой: надо нанять людей из пула
|
||||
соискателей, раздать им предметы и уложиться в выделенную на месяц сумму. Уроков по-прежнему нет —
|
||||
предмет это запись в нагрузке, а не событие в кабинете.
|
||||
|
||||
Фазы идут строго по порядку: каждая опирается на данные предыдущей.
|
||||
|
||||
| Фаза | Статус | Зачем |
|
||||
| --- | --- | --- |
|
||||
| [10. Предметы и мебель](10-subjects.md) | ✅ | `SubjectDef`, одна учительская должность, кабинет как число мест |
|
||||
| [11. Пустая школа и пул](11-applicants.md) | ✅ | Школа без сотрудников, соискатели с запросом по зарплате |
|
||||
| [12. Наём и бюджет](12-hiring-budget.md) | ✅ | Наём, назначение предметов, предел фонда оплаты |
|
||||
| [13. Раздел «Управление»](13-management-tab.md) | ✅ | Деньги, соискатели, штат и назначения на экране |
|
||||
@@ -0,0 +1,44 @@
|
||||
# Журнал ревью
|
||||
|
||||
Сводка: [`../reviewed.md`](../reviewed.md). Индекс среза: [`README.md`](README.md).
|
||||
|
||||
## Срез 3. Штат
|
||||
|
||||
- **Фазы:** 10–13
|
||||
- **Проверен на:** `bdb1253`, 2026-08-20
|
||||
- **Пути:** `src/HSchool.People/Staffing.cs`, `src/HSchool.People/ApplicantPool.cs`,
|
||||
`src/HSchool.Content/SubjectDef` и `defs/staffing`, `src/HSchool.Server/Api/SchoolEndpoints.cs`
|
||||
(staffing/hire/subjects), `src/HSchool.Server/mods/core/defs/{subjects,positions,rooms,staffing,traits}`,
|
||||
`src/HSchool.Client/src/ui/managementPanel.ts`, `src/HSchool.Client/src/net/api.ts`,
|
||||
`tests/HSchool.People.Tests/{StaffingTests,ApplicantPoolTests}.cs`,
|
||||
`tests/HSchool.AppHost.Tests/StaffingApiTests.cs`,
|
||||
`src/HSchool.Client/src/ui/managementPanel.test.ts`
|
||||
- **Итог:** обещания фаз 10–13 целы; дописаны 3 теста; `docs/protocol.md` дополнен `?lang=`
|
||||
|
||||
Что подтверждено:
|
||||
|
||||
- `PETeacher` нет; кабинеты без учительской должности; места через `defaultSeats`.
|
||||
Неизвестный навык в предмете роняет каталог. Стартовая дата 31 марта 2012.
|
||||
- Пул: детерминизм по сиду и неделе, частичное обновление, устойчивый размер, «сильный просит
|
||||
больше», пустой штат, соискатель вне ростера до найма. Пул 32.
|
||||
- Фонд оплаты, деление часов, пол ставки, покрытие. `GET /staffing` читает снимок, наём и
|
||||
назначение — `GameCommand` с `TaskCompletionSource`. `MaxWeeklyHours` не запрещает назначение,
|
||||
а оставляет предмет непокрытым. `PrimarySchool` на ванили требует трёх учителей (`teachersShort`).
|
||||
- Экран: деньги, непокрытые, пул, штат, назначение с карточки, отказ по пределу текстом,
|
||||
всё через `t(...)`.
|
||||
- Полностью укомплектованная школа влезает в 100 000 впритык (запас 5–13%). Нанять пул целиком
|
||||
без назначений предела достигает. Раскладка «каждому все предметы» — самая дешёвая, не
|
||||
«укомплектованная школа».
|
||||
|
||||
Дописано:
|
||||
|
||||
- `StaffingApiTests.AssigningPastTheCap_IsRejectedWithTheNumbers` — фаза 12 требовала API-тест
|
||||
на отказ по пределу; единственное место было написано через `if (over.StatusCode == Conflict)`
|
||||
и проходило при любом исходе.
|
||||
- `ApplicantPoolTests.ConfidentTraits_AskForMoreAndQuietOnesForLess`
|
||||
- В `AssignAndUnassign_HonourTheCap_AndReloadKeepsAssignments` — тот же пул с теми же ставками
|
||||
после перезапуска.
|
||||
|
||||
Исправлено:
|
||||
|
||||
- `docs/protocol.md` не упоминал `?lang=` у hire/subjects, хотя клиент его шлёт.
|
||||
Reference in New Issue
Block a user