Update design documentation for inventory and climate phases, clarify staffing test results, and add new presence test for hiring and assigning a teacher during lessons.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# Фаза 29. Страна
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 5](05-people-defs.md)
|
||||
- [Фаза 26](26-school-seed.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Create выбирает страну, а не набор имён. Имена и климатические пресеты перестают быть двумя
|
||||
несвязанными пикерами.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] `CountryDef` и `ClimatePresetDef` в `HSchool.Content`: страна вкладывает нынешние поля
|
||||
набора имён в `names`, ссылается на пресеты списками id
|
||||
- [ ] Набор имён больше не выбираемый вид; папка `namesets/` в `core` уезжает в страну
|
||||
- [ ] Ваниль: одна страна `Russia` с нынешним славянским набором и хотя бы одним пресетом
|
||||
(числа погоды можно заглушить — живая улица в фазе 32)
|
||||
- [ ] `GET /api/catalog` отдаёт `countries` (`defName`, подпись, `nativeLanguages`,
|
||||
`climatePresets`) вместо `nameSets`
|
||||
- [ ] `POST /api/schools` принимает `countryId`; неизвестный — `400` `unknown-country`.
|
||||
`nameSetId` не принимается
|
||||
- [ ] Пресет климата записывается на школу: случайный из списка страны, от сида. Живой школе
|
||||
его не сменить
|
||||
- [ ] Форма создания: подпись «Страна»; язык — если у страны их несколько
|
||||
- [ ] Старый сейв с `nameSetId: Slavic` поднимается как `Russia` + первый пресет; формат
|
||||
новее без `countryId` — как с прочими полями сейва, школа не стартует
|
||||
- [ ] `docs/protocol.md` и `AGENTS.md` (ориентир create / каталог) в том же коммите
|
||||
- [ ] Золотой отпечаток ростера обновляется, если вход генератора сменил имя поля
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Каталог `core` грузится; страна без имён или с неизвестным пресетом — ошибка загрузки
|
||||
- [ ] Create с `countryId: Russia` и без языка даёт тот же родной язык, что прежний сид без
|
||||
`nativeLanguage`
|
||||
- [ ] Create с неизвестной страной — `400` `unknown-country`
|
||||
- [ ] Два create с одним сидом получают один и тот же пресет
|
||||
- [ ] Старый сейв без страны поднимается
|
||||
- [ ] Диалог создания показывает страны, не наборы имён; смена страны обновляет список языков
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Создать школу, выбрав страну; люди и язык как раньше на том же сиде
|
||||
- `dotnet test` и `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не считать живую погоду. Не одевать людей. Не менять кадр часов.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Фаза 30. Слои и палитра
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 3](03-defs-map.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Каталог умеет описать одежду и ношу, не путая их с партой. Никто ещё ничего не носит.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] Поля `ThingDef`: `layers`, `portable`, `mass`, `insulation`, `formality`, `age`, `sex`,
|
||||
`colors`, `skirtLength`, `pe`. Пустые `layers` — прежняя мебель, карта не ломается
|
||||
- [ ] Слои — известный набор в коде (`Underwear` … `Accessory`), как роли. Неизвестный слой —
|
||||
ошибка загрузки
|
||||
- [ ] `ColorDef`: id и теги (`neutral`, `bright`, `school`). Ссылка вещи на неизвестный цвет —
|
||||
ошибка
|
||||
- [ ] Вещь с несколькими `layers` допустима (платье). Пересечение слоёв у двух надетых сразу
|
||||
валидатор не проверяет — это состояние человека, не каталога
|
||||
- [ ] Ваниль по [`../design/inventory.md`](../design/inventory.md): бельё, носки, низы, верх,
|
||||
свитер, куртка/пальто/шуба, обувь, шапка, аксессуары, платье, форма физкультуры,
|
||||
портфель, учебник, телефон, бутылка
|
||||
- [ ] Палитра цветов и локали ru/en на все новые def
|
||||
- [ ] Учебник — один `ThingDef` без зашитого предмета; предмет живёт на экземпляре в фазе 31
|
||||
- [ ] Мебель на карте по-прежнему без `layers`; редактор не предлагает надеть стул
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] `Chair` без новых полей грузится как раньше
|
||||
- [ ] Платье с `layers: ["Bottom", "Top"]` проходит; неизвестный слой — ошибка
|
||||
- [ ] Футболка ссылается на `Red`; отсутствие `Red` в палитре — ошибка
|
||||
- [ ] Тест полноты локалей зелёный на новый набор
|
||||
- [ ] Ванильная карта и каталог предметов (мебель) не изменились по вместимости
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Каталог `core` грузится, школы создаются, люди голые
|
||||
- `dotnet test` проходит
|
||||
|
||||
## Стоп
|
||||
|
||||
Не генерировать экземпляры. Не трогать карточку и create сверх того, что уже есть.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Фаза 31. Генератор одевает
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 29](29-country.md)
|
||||
- [Фаза 30](30-apparel-defs.md)
|
||||
- [Фаза 6](06-people-generator.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Люди рождаются одетыми. Гардероб детерминирован и лежит на человеке в `people.json`.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] Экземпляр вещи на человеке: `def`, `color`, `condition` (1), место (`worn` / `bag` /
|
||||
`locker` / `home`), для учебника — `subject`
|
||||
- [ ] Генератор одевает учеников, сотрудников, родителей и соискателей от семейного сида:
|
||||
слои без пересечения, пол, возраст, дефолтные правила (обычная форма, без яркого на теле)
|
||||
- [ ] Учебники — по одному на предмет параллели ученика; в сумке пока могут лежать все, разнос
|
||||
«сегодняшние vs шкафчик» — в фазе 33/35
|
||||
- [ ] Портфель, телефон, бутылка — с возрастом и шансом из данных, не из константы в генераторе
|
||||
- [ ] Навык `Hauling` (`always`); предел массы в дефе правил; на карточке несёшь/можешь.
|
||||
Перегруз ходьбу не трогает; в сумку сверх предела генератор не кладёт
|
||||
- [ ] `GET .../people/{id}` отдаёт надетое и ношу; список людей — нет
|
||||
- [ ] Карточка пока без вкладок: секции «Одежда» и «Ноша» в том же свитке
|
||||
- [ ] `people.json` пишется при создании и наборе; золотой отпечаток обновляется в этом коммите
|
||||
с объяснением, что изменилось
|
||||
- [ ] Строки через `t(...)` / локали каталога
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Тот же сид, страна, карта и язык → те же id вещей, цвета и места
|
||||
- [ ] На одном слое не две вещи; платье занимает низ и верх сразу
|
||||
- [ ] Юбка не выдаётся мужчинам на тело; яркий верх не выдаётся на тело при дефолтных правилах
|
||||
- [ ] Ученик параллели с математикой имеет учебник этого предмета
|
||||
- [ ] Родитель и соискатель одеты
|
||||
- [ ] Масса в сумке ≤ предела
|
||||
- [ ] Старый `people.json` без инвентаря поднимается: генератор одевает при загрузке и пишет
|
||||
файл (как пул соискателей в фазе 11)
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Открыть карточку ученицы: слои заполнены, цвет виден, ноша с числом
|
||||
- Повтор create с сидом даёт ту же рубашку
|
||||
- `dotnet test` и `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не считать погоду. Не изнашивать. Не переодевать по ситуации. Не заводить вкладки карточки.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Фаза 32. Погода и тепло
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 29](29-country.md)
|
||||
- [Фаза 20](20-needs-actions.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
На улице есть температура и осадки. Человек может мёрзнуть. Часы это показывают.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] `ClimatePresetDef` получает рабочие числа: нормы по месяцам, разброс дня, осадки
|
||||
- [ ] Школа считает улицу из пресета + сида + даты/часа; не каждый тик, а когда меняется
|
||||
надпись или это сдвинет тепло
|
||||
- [ ] В здании теплее улицы за счёт стен, без техника ещё не комфорт (комфорт — фаза 33)
|
||||
- [ ] Двор и крыльцо — улица
|
||||
- [ ] Нужда `Warmth`: декей от разницы «утепление одежды vs температура места»; вне школы
|
||||
восстанавливается, как сон
|
||||
- [ ] Черты теплолюбивый / холодолюбивый: поле смещения комфорта на `TraitDef`, взаимно
|
||||
несовместимы
|
||||
- [ ] Кадр часов: температура (десятые доли °C, `i16`) и осадки (`u8`). Версия протокола +1.
|
||||
`ProtocolCodec.cs`, `protocol.ts`, `docs/protocol.md` в одном коммите
|
||||
- [ ] Клиент рисует погоду у даты; не считает её из месяца
|
||||
- [ ] Пропуск пустого времени выставляет погоду утра, не вчерашнюю
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Тот же пресет, сид и timestamp → та же температура и осадки
|
||||
- [ ] Январь холоднее июля на ванильном пресете
|
||||
- [ ] Ниже нуля осадки — снег, не дождь (если пресет вообще дал осадки)
|
||||
- [ ] На морозе без верхней одежды тепло падает; дома за ночь возвращается
|
||||
- [ ] Кадр часов круглый трип и байтовая раскладка на обеих сторонах
|
||||
- [ ] Клиент с старой версией протокола отваливается Hello, как обычно
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- У часов видно «−5 °C, снег» зимним утром
|
||||
- Полоска тепла на карточке шевелится
|
||||
- `dotnet test` и `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не нанимать техника. Не переодевать по погоде — замёрзший ещё терпит. Не штрафовать урок.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Фаза 33. Техник и шкафчики
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 31](31-dress-generator.md)
|
||||
- [Фаза 32](32-weather-warmth.md)
|
||||
- [Фаза 11](11-applicants.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
В школе можно нанять человека, который держит тепло зимой и прохладу летом. У учеников появляются
|
||||
личные шкафчики — кому хватило.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] `RoomDef` теплоузла и `PositionDef Technician`; комната открывает должность, как медкабинет
|
||||
- [ ] Ванильная карта: комната в основном корпусе, связана с коридором
|
||||
- [ ] Нанятый техник сдвигает внутреннюю температуру в комфортную полосу; без него здание
|
||||
только демпфирует улицу. Числа — в дефе правил климата
|
||||
- [ ] Две раздевалки у спортзала: мужская и женская, разные def, свои шкафчики. Старый один
|
||||
узел `changing-room` заменяется
|
||||
- [ ] Раздача: ученики этого пола, старшая параллель раньше, при равенстве id. Сотрудникам
|
||||
шкафчик не дают. Не хватило — место `locker` пустое, вещи в сумке и дома
|
||||
- [ ] Пересчёт раздачи на годовом наборе (параллели сдвинулись)
|
||||
- [ ] Редактор: число шкафчиков в слоте по-прежнему меняется; после создания школы раскладка
|
||||
заморожена, как вся карта
|
||||
- [ ] Карточка показывает, есть ли шкафчик (ещё без вкладки ноши)
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Новая школа без техника: январский кабинет холоднее, чем с нанятым техником, и теплее
|
||||
улицы
|
||||
- [ ] Нанятый техник в июле держит кабинет ниже раскалённой улицы
|
||||
- [ ] Две раздевалки на ванильной карте, граф связен
|
||||
- [ ] Шкафчиков 10 на 40 учениц — получают десять старших; одиннадцатая без шкафчика
|
||||
- [ ] Мальчик не получает слот девичьей раздевалки
|
||||
- [ ] После 1 сентября раздача пересчитывается, выпускник слот не держит
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Нанять техника из пула — в январе в кабинете становится тепло
|
||||
- Открыть карточку старшеклассника — шкафчик есть; у части младших нет
|
||||
- `dotnet test` проходит
|
||||
|
||||
## Стоп
|
||||
|
||||
Не переодевать на физкультуру. Не изнашивать. Не делать вкладку «Правила».
|
||||
@@ -0,0 +1,42 @@
|
||||
# Фаза 34. Износ и дом
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 31](31-dress-generator.md)
|
||||
- [Фаза 18](18-presence-walking.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Одежда портится на теле в школе. Из дома в лохмотьях не выходят — утром выдают свежую.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] Прочность экземпляра 0–1; падает только у надетого, только пока человек в школе, от
|
||||
игрового времени. Формула скорости — данные
|
||||
- [ ] Пороги подписей в дефе (`целая` / `поношенная` / `порванная` / `висит лохмотьями`);
|
||||
карточка — полоска + подпись, клиент не считает пороги сам
|
||||
- [ ] Порог «не выходить»: утром вне школы ветхая надетая вещь заменяется свежей того же def
|
||||
и цвета (или ближайшего уместного). Событие для истории фазы 36: тип и подпись готовы
|
||||
даже если лог ещё не рисуется
|
||||
- [ ] Пропуск пустого времени применяет утреннюю замену, иначе после «пропустить» школа в
|
||||
лохмотьях
|
||||
- [ ] Сумка и шкафчик не изнашиваются
|
||||
- [ ] `people.json` пишется после замены, не каждый тик износа: либо порог пересечён, либо
|
||||
утренняя выдача
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] День в школе снижает прочность надетой рубашки на заявленную величину, ±эпсилон
|
||||
- [ ] Рубашка в сумке за тот же день не меняется
|
||||
- [ ] Человек с одеждой ниже порога к утру рабочего дня одет в свежую; def совпадает
|
||||
- [ ] Skip через ночь даёт ту же замену, что прожитая ночь
|
||||
- [ ] Подпись на карточке меняется вместе с порогом
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Промотать несколько игровых недель — полоска одежды опустилась, потом утром обновилась
|
||||
- `dotnet test` и `npm test` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не показывать историю вкладкой — только состояние вещи. Не переодевать по погоде.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Фаза 35. Уместность
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 32](32-weather-warmth.md)
|
||||
- [Фаза 33](33-lockers-technician.md)
|
||||
- [Фаза 34](34-wear-home.md)
|
||||
- [Фаза 21](21-decisions.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Система сама одевает по правилам, погоде и уроку. В школе переодевание — действие в своей
|
||||
раздевалке; дома — мгновенно.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] Оценка уместности из данных: пол, возраст, погода/утепление, `pe`, формальность,
|
||||
цветовые теги, длина низа. Код знает оси, пороги — defs и правила школы
|
||||
- [ ] На школе хранятся правила учеников и сотрудников (форма + цвет). Дефолт: обычная,
|
||||
без яркого. Смена с экрана — фаза 37; API уже пишет «с завтра»
|
||||
- [ ] «Короткая» форма: длина юбки / короткий рукав; младше порога возраста ходят в обычной
|
||||
- [ ] Дома утром: мгновенно подобрать надетое под правила, погоду и сегодняшний план
|
||||
(учебники только сегодняшних уроков в сумке, остальное — шкафчик или дом)
|
||||
- [ ] В школе: действие `ChangeClothes` в своей (м/ж) раздевалке. Снятое — в шкафчик, если
|
||||
есть, иначе в сумку
|
||||
- [ ] Цель «одеться к физкультуре» и «вернуться с формы» рядом с обязанностью урока; не
|
||||
каждый тик, а по звонку / приходу
|
||||
- [ ] Цель «верх не по погоде» — дойти и сменить куртку, если уже в школе
|
||||
- [ ] Вместимость действия — сколько одновременно переодеваются в комнате; не путать с
|
||||
числом шкафчиков
|
||||
- [ ] Игрок по-прежнему не одевает с карточки
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Школа с «без яркого»: утром на теле нет цвета с тегом `bright`
|
||||
- [ ] «Короткая» + первоклассница → обычная длина; старше порога — можно короткое
|
||||
- [ ] Перед уроком физкультуры ученик идёт в свою раздевалку и надевает `pe`; после — снимает
|
||||
- [ ] Мальчик не идёт в женскую раздевалку
|
||||
- [ ] Без шкафчика снятое оказывается в сумке, не исчезает
|
||||
- [ ] Морозным утром на теле есть `Outer`; в июле шубы на теле нет
|
||||
- [ ] Смена правила через API сегодня не меняет одежду до следующего рабочего утра
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- На физкультуре в зале видно форму, не школьную рубашку
|
||||
- Смена погоды за день гонит кого-то в раздевалку, не телепортирует куртку
|
||||
- `dotnet test` проходит
|
||||
|
||||
## Стоп
|
||||
|
||||
Не рисовать вкладку «Правила». Не штрафовать урок за холод и «не по форме».
|
||||
@@ -0,0 +1,48 @@
|
||||
# Фаза 36. Вкладки карточки
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 31](31-dress-generator.md)
|
||||
- [Фаза 8](08-people-browser.md)
|
||||
- [Фаза 28](28-screen-tests.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Гардероб, ноша и сегодняшний след перестают быть секциями в одном свитке. Подробности о человеке
|
||||
читаются.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] Окно карточки: вкладки **Обзор / Одежда / Ноша / Сейчас**
|
||||
- [ ] Обзор — прежнее: тело, навыки, черты, нужды, семья, расписание; текущее дело с обзора
|
||||
уходит на «Сейчас»
|
||||
- [ ] Одежда: слои, цвет, полоска износа и подпись, короткая уместность к ситуации
|
||||
- [ ] Ноша: сумка, несёшь/можешь, шкафчик или его отсутствие, кратко «ещё N дома» без полного
|
||||
домашнего списка
|
||||
- [ ] Сейчас: на территории школы — подпись действия (`ест`, `идёт`, `учится (математика)`,
|
||||
`переодевается`). Вне школы — «дома»
|
||||
- [ ] История за сегодня под текущим делом: поиск, сортировка, пейджинг
|
||||
- [ ] `GET /api/schools/{id}/people/{personId}/log` — страница и фильтр; не сокет, не лента
|
||||
школы. Граница суток — шесть утра; skip ночи обнуляет вчерашнее
|
||||
- [ ] Запись в лог: начало/конец действия, утренняя выдача одежды, переодевание. Хранит
|
||||
работник, не `people.json`
|
||||
- [ ] Vitest: переключение вкладок, пейджер лога, «дома» когда activity пустая и человек away
|
||||
- [ ] `docs/protocol.md` — HTTP лога в том же коммите
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] Лог не едет в `GET .../people/{id}` — только отдельным запросом
|
||||
- [ ] Страница лога не пересекается; неизвестный человек — `404`
|
||||
- [ ] После 6:00 записей вчера нет
|
||||
- [ ] Вне школы вкладка «Сейчас» показывает «дома», не пусто
|
||||
- [ ] Клиентский тест: вкладка «Одежда» не монтирует таблицу лога
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Открыть ученика, переключить четыре вкладки, найти в истории сегодняшний обед
|
||||
- Тысяча строк лога не приезжает разом
|
||||
- `dotnet test` и `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не возвращать панель общих событий школы. Не давать надевать с вкладки «Одежда».
|
||||
@@ -0,0 +1,41 @@
|
||||
# Фаза 37. Правила школы
|
||||
|
||||
## Зависимости
|
||||
|
||||
- [Фаза 35](35-appropriateness.md)
|
||||
- [Фаза 36](36-person-card-tabs.md)
|
||||
- [Фаза 13](13-management-tab.md)
|
||||
|
||||
## Зачем
|
||||
|
||||
Игрок задаёт, как одевается школа. Это единственное его действие в срезе про одежду.
|
||||
|
||||
## Задачи
|
||||
|
||||
- [ ] В «Управлении» вкладка **«Правила»** рядом со штатом, не новый верхний режим
|
||||
- [ ] Четыре комбобокса: форма учеников, цвет учеников, форма сотрудников, цвет сотрудников.
|
||||
Значения — как в [`../design/inventory.md`](../design/inventory.md)
|
||||
- [ ] Сохранение пишет завтрашнее правило; на экране видно, что действует сегодня и что
|
||||
вступит завтра
|
||||
- [ ] HTTP: чтение текущих+отложенных, запись отложенных. Отказ по неизвестному коду правила —
|
||||
`400`, не тишина
|
||||
- [ ] На следующее рабочее утро отложенное становится текущим; фаза 35 уже одевает от него
|
||||
- [ ] Строки через `t(...)`, обе локали
|
||||
- [ ] Vitest: смена комбобокса не зовёт API до подтверждения; ошибка API видна текстом
|
||||
|
||||
## Тесты, без которых фаза не закрыта
|
||||
|
||||
- [ ] GET правил на новой школе — дефолт обычная / без яркого на обе роли
|
||||
- [ ] POST «строгая» сегодня не меняет одежду до следующего рабочего утра
|
||||
- [ ] После утра на теле учеников нет яркого, если отложили «без яркого»
|
||||
- [ ] Неизвестный код политики — `400`
|
||||
- [ ] Вкладка не ломает наём и сетку расписания
|
||||
|
||||
## Критерий готовности
|
||||
|
||||
- Выставить ученикам «белая верх чёрный низ», промотать на утро — рубашки белые
|
||||
- `dotnet test` и `npm test` / `build` проходят
|
||||
|
||||
## Стоп
|
||||
|
||||
Не давать игроку одевать одного человека. Не вводить магазины и оплату формы.
|
||||
@@ -113,3 +113,43 @@
|
||||
| [26. Свой сид](26-school-seed.md) | ✅ | Состав школы перестаёт зависеть от порядка создания |
|
||||
| [27. Версия сейва и дамп](27-serviceability.md) | ✅ | Формат читается, внутрь школы можно заглянуть |
|
||||
| [28. Тесты экранов](28-screen-tests.md) | ✅ | DOM-окружение и логика клиента под тестом |
|
||||
|
||||
## Срез 7. Одежда, вещи и климат
|
||||
|
||||
Дизайн: [`../design/inventory.md`](../design/inventory.md).
|
||||
|
||||
Человек одевается, несёт вещи, мёрзнет и переодевается. Игрок смотрит гардероб и выбирает
|
||||
правила школы; надевает не он. Погода видна у часов. Срез можно остановить после этапа A —
|
||||
школа останется одетой, даже если климат ещё не живой.
|
||||
|
||||
**Этап A — данные и гардероб.** Страна вместо набора имён, вещи умеют быть одеждой, генератор
|
||||
одевает.
|
||||
|
||||
| Фаза | Статус | Зачем |
|
||||
| --- | --- | --- |
|
||||
| [29. Страна](29-country.md) | ⬜ | `CountryDef`, create выбирает страну, климат-пресет от сида |
|
||||
| [30. Слои и палитра](30-apparel-defs.md) | ⬜ | Поля `ThingDef`, `ColorDef`, ванильная одежда и ноша |
|
||||
| [31. Генератор одевает](31-dress-generator.md) | ⬜ | Гардероб на человеке, ноша-число, `people.json` |
|
||||
|
||||
29 и 30 независимы; 31 стоит на обеих.
|
||||
|
||||
**Этап B — климат.** Улица, нужда тепла, техник, раздевалки.
|
||||
|
||||
| Фаза | Статус | Зачем |
|
||||
| --- | --- | --- |
|
||||
| [32. Погода и тепло](32-weather-warmth.md) | ⬜ | Пресет крутит улицу, кадр часов, нужда, две черты |
|
||||
| [33. Техник и шкафчики](33-lockers-technician.md) | ⬜ | Комната техника, две раздевалки, раздача шкафчиков |
|
||||
|
||||
32 стоит на 29; 33 — на 31 и 32.
|
||||
|
||||
**Этап C — жизнь одежды.** Износ, переодевание, экран.
|
||||
|
||||
| Фаза | Статус | Зачем |
|
||||
| --- | --- | --- |
|
||||
| [34. Износ и дом](34-wear-home.md) | ⬜ | Прочность, утренняя замена, из ветхого не выходят |
|
||||
| [35. Уместность](35-appropriateness.md) | ⬜ | Правила, переодевание действием, физкультура |
|
||||
| [36. Вкладки карточки](36-person-card-tabs.md) | ⬜ | Одежда, ноша, сейчас + история за сегодня |
|
||||
| [37. Правила школы](37-school-rules.md) | ⬜ | Вкладка в «Управлении», четыре комбобокса, с завтра |
|
||||
|
||||
34 стоит на 31; 35 — на 32–34; 36 — на 31 и может идти параллельно с 35 в части вкладок одежды,
|
||||
история — после 35; 37 стоит на 35 и 36.
|
||||
|
||||
+109
-6
@@ -142,14 +142,16 @@
|
||||
## Срез 2. Люди
|
||||
|
||||
- **Фазы:** 5–9
|
||||
- **Проверен на:** `5a00ad7`, 2026-08-19 (первичная проверка — `5cd5a6d`)
|
||||
- **Проверен на:** `bdb1253`, 2026-08-20 (первичная проверка — `5cd5a6d`; предыдущая перепроверка — `5a00ad7`)
|
||||
- **Пути:** `src/HSchool.People`, `src/HSchool.Content/PeopleDefs.cs`,
|
||||
`src/HSchool.Simulation/RosterSpawner.cs`, `src/HSchool.Simulation/School.cs`,
|
||||
`src/HSchool.Server/Api/SchoolEndpoints.cs`, `src/HSchool.Server/Game/PersonCardReader.cs`,
|
||||
`src/HSchool.Server/Game/SchoolWorker.cs`,
|
||||
`src/HSchool.Client/src/ui/peoplePanel.ts`, `src/HSchool.Client/src/ui/personCard.ts`,
|
||||
`tests/HSchool.People.Tests`, `tests/HSchool.Content.Tests/PeopleDefTests.cs`,
|
||||
`tests/HSchool.Simulation.Tests/PeopleInSchoolTests.cs`,
|
||||
`tests/HSchool.AppHost.Tests/PeopleApiTests.cs`
|
||||
`tests/HSchool.AppHost.Tests/PeopleApiTests.cs`,
|
||||
`tests/HSchool.AppHost.Tests/SchoolSeedTests.cs`
|
||||
- **Итог:** исправлен один тест, который падал на чистом клоне, укреплён второй, дописан один;
|
||||
расхождение с дизайном одно и то же, что в срезе 1 (раскладка оболочки менеджера)
|
||||
|
||||
@@ -234,16 +236,57 @@
|
||||
- Исправления среза 2 (карточка семьи, сортировка по фамилии, состав после набора и перезапуска)
|
||||
проходят на новом коде.
|
||||
|
||||
### Перепроверка на `bdb1253`, 2026-08-20
|
||||
|
||||
Дрейф после `5a00ad7` — свой сид школы (фаза 26), золотые ростеры (25), тесты панели (28) и
|
||||
данные поведения. Обещания фаз 5–9 целы.
|
||||
|
||||
Что подтверждено повторно:
|
||||
|
||||
- **Фаза 5.** Все пункты списка в `PeopleDefTests` (10/10): разбор, наследование, патч черты,
|
||||
неизвестная ссылка, склонение и таблица, мод со своим набором.
|
||||
- **Фаза 6.** Все шесть тестов генератора на месте, плюс `NewSchool_HasNoStaff` (фаза 11 не
|
||||
отменяет детерминизм и заполнение мест). `Assembly_DoesNotReferenceArchAspNetOrSockets` и
|
||||
`Sources_DoNotUseWallClock` зелёные. Неполные семьи 5–10% — `ReviewFixTests`.
|
||||
- **Фаза 7.** Одиннадцать кабинетов, сущности в `World`, `PersistPeople` только при изменении
|
||||
состава. Штат при создании пуст — это фаза 11, тест обновлён (`LeaveJobsEmpty`).
|
||||
- **Фаза 8.** Список с опубликованного снимка (`FindPeople`), карточка через `TaskCompletionSource`.
|
||||
Пять API-тестов плюс клиентские фильтры/пейджер (`peoplePanel.test.ts` 3/3). Вкладка, не нижний ряд.
|
||||
- **Фаза 9.** Выпуск старшей имеющейся, вместимость, семьи через поколения, reload после набора
|
||||
(`ReloadAfterTheYearlyIntake_RestoresTheNewComposition`).
|
||||
- **Сид.** Больше не `school.Id`. Новая школа берёт `_createSeed`, сейв — `loaded.Seed`; запасной
|
||||
`school.Id` только если `people.json` нет. `Card_IncludesFamilyAndLiveNeeds` передаёт `seed: 1`.
|
||||
`SchoolSeedTests`: тот же сид — те же люди, два без сида — разные, reload хранит выпавший.
|
||||
|
||||
Исправлено:
|
||||
|
||||
- В `design/people.md` скорость нужд всё ещё была «ноль» (нарратив, совет и таблица), хотя срез 5
|
||||
это отменил. Помечено как отменённое со ссылкой на `ai.md`, по тому же шаблону, что расписание.
|
||||
Код не трогался.
|
||||
|
||||
Закрыто из прошлого прохода:
|
||||
|
||||
- **Раскладка оболочки.** «Открыто» выше больше не действует: `design/people.md` и фаза 8 уже
|
||||
записаны под вкладку рядом с картой. Решение принято в том же ходе, что отказ от панели событий.
|
||||
|
||||
Замечено рядом:
|
||||
|
||||
- «Заведомо не сейчас» в `people.md` всё ещё говорит «должности закрываются генератором» —
|
||||
отменено срезом 3. Не переписывал исторический список стопов.
|
||||
|
||||
People 34, PeopleDef 10, PeopleInSchool 7, PeopleApi+SchoolSeed 13, клиентская панель 3/3.
|
||||
|
||||
## Срез 3. Штат
|
||||
|
||||
- **Фазы:** 10–13
|
||||
- **Проверен на:** `5a00ad7`, 2026-08-19 (первичная проверка — `21d79cb`)
|
||||
- **Проверен на:** `bdb1253`, 2026-08-20 (первичная проверка — `21d79cb`; предыдущая перепроверка — `5a00ad7`)
|
||||
- **Пути:** `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`
|
||||
`tests/HSchool.AppHost.Tests/StaffingApiTests.cs`,
|
||||
`src/HSchool.Client/src/ui/managementPanel.test.ts`
|
||||
- **Итог:** дописано 3 теста (один из них — прямо требуемый фазой 12 и отсутствовавший),
|
||||
дополнен `docs/protocol.md`; расхождений кода с дизайном не найдено
|
||||
|
||||
@@ -335,16 +378,48 @@
|
||||
как штатный исход. Это правильно: с пулом в 32 человека нанять всех и остаться в пределах суммы
|
||||
уже нельзя.
|
||||
|
||||
### Перепроверка на `bdb1253`, 2026-08-20
|
||||
|
||||
Дрейф после `5a00ad7` — `teachersShort` (фаза 25), свой сид, удостоверение пака. Обещания фаз 10–13
|
||||
целы; новых тестов не дописывал, расхождений с `design/staffing.md` нет.
|
||||
|
||||
Что подтверждено повторно:
|
||||
|
||||
- **Фаза 10.** `PETeacher` нет, кабинеты без учительской должности, места через `defaultSeats`,
|
||||
редактор показывает у homeroom одно поле «мест». `Subject_UnknownSkill_FailsTheCatalog`,
|
||||
стартовая дата 31 марта 2012.
|
||||
- **Фаза 11.** Все шесть тестов пула на месте (`SameSeedAndWeek`, частичное обновление, 50 недель,
|
||||
сильный просит больше, пустой штат, соискатель вне ростера). Пул 32, reload хранит ставки.
|
||||
- **Фаза 12.** `Hire_TwoPeopleAtThreeAndSevenThousand_RejectsTheThird` на фикстуре 10 000.
|
||||
`AssigningPastTheCap_IsRejectedWithTheNumbers` на API. `GET /staffing` читает снимок,
|
||||
наём/назначение — `TaskCompletionSource`. `MaxWeeklyHours` не запрещает назначение
|
||||
(`SubjectNeedingMoreHoursThanOnePersonCarries_StaysUncovered`). Ветка `if/else` вокруг предела
|
||||
убрана.
|
||||
- **Фаза 13.** Деньги, непокрытые, пул, штат, назначение с карточки, всё через `t(...)`.
|
||||
Отказ по пределу текстом — `managementPanel.test.ts`.
|
||||
- **Покрытие.** `PrimarySchool` на ванили требует трёх учителей (`TeachersShort == 3` в API и в
|
||||
`PrimarySchool_OnVanillaMap_NeedsThreeTeachers_AndASecondDoesNotCloseIt`). Это фаза 25, не
|
||||
ломает фазу 12: список непокрытых был и раньше, появилось число.
|
||||
|
||||
Замечено рядом:
|
||||
|
||||
- `people.md` «Заведомо не сейчас» всё ещё говорит, что должности закрывает генератор — то же, что
|
||||
в срезе 2. Исторический стоп среза 2, не трогал.
|
||||
|
||||
Staffing+ApplicantPool 18, Content 3, StaffingApi 9.
|
||||
|
||||
## Срез 4. Расписание
|
||||
|
||||
- **Фазы:** 14–17
|
||||
- **Проверен на:** `5a00ad7`, 2026-08-19 (первичная проверка — `21d79cb`)
|
||||
- **Проверен на:** `bdb1253`, 2026-08-20 (первичная проверка — `21d79cb`; предыдущая перепроверка — `5a00ad7`)
|
||||
- **Пути:** `src/HSchool.Schedule`, `src/HSchool.Content` (каркас дня, каникулы, `SubjectDef.room`),
|
||||
`src/HSchool.Simulation/SchoolTimetables.cs`, `src/HSchool.Server/Api/TimetableEndpoints.cs`,
|
||||
`src/HSchool.Server/Game/SchoolWorker.cs` (пин, перестроение),
|
||||
`src/HSchool.Client/src/ui/timetableGrid.ts`, `src/HSchool.Client/src/ui/gameScreen.ts`,
|
||||
`tests/HSchool.Schedule.Tests`, `tests/HSchool.Content.Tests/CalendarTests.cs`,
|
||||
`tests/HSchool.AppHost.Tests/TimetableApiTests.cs`
|
||||
`tests/HSchool.Content.Tests/LunchBreakTests.cs`,
|
||||
`tests/HSchool.AppHost.Tests/TimetableApiTests.cs`,
|
||||
`src/HSchool.Client/src/ui/timetableGrid.test.ts`
|
||||
- **Итог:** дописан один тест на пять непокрытых кодов отказа, поправлены две устаревшие строки
|
||||
дизайна; расхождений кода с принятыми решениями нет
|
||||
|
||||
@@ -413,6 +488,34 @@
|
||||
Планировщик, каркас дня и API расписания не менялись; дописанный в прошлый проход тест на коды
|
||||
отказа пина проходит.
|
||||
|
||||
### Перепроверка на `bdb1253`, 2026-08-20
|
||||
|
||||
Дрейф после `5a00ad7` — обеденные смены в каркасе дня (`SchoolDay` / `CalendarDefs`) и сид/дамп в
|
||||
воркере. Планировщик и API расписания не менялись. Обещания фаз 14–17 целы; тестов не дописывал.
|
||||
|
||||
Что подтверждено повторно:
|
||||
|
||||
- **Фаза 14.** Суббота, каникулы и ночь — «вне учебного дня»; 10:20 вторника — третий урок;
|
||||
шестидневка делает субботу рабочей; зима через 1 января. Физкультура в спортзале.
|
||||
Обеденные смены уже стоят в `design/schedule.md`: младшие после 3-го, старшие после 4-го,
|
||||
обе перемены длинные (`LunchBreakTests`).
|
||||
- **Фаза 15.** Все шесть тестов планировщика на месте, плюс самопроверка сборки без Arch/ASP.NET
|
||||
и `DateTime.Now`.
|
||||
- **Фаза 16.** Перестроение только при `PeopleChanged` + `TimetableDirty`, не по тику.
|
||||
`GET /timetable` читает снимок, пин — `TaskCompletionSource`. `Reload_RestoresLockedLessons`,
|
||||
`PinAndUnpinRefusals_CarryTheDocumentedCodes`.
|
||||
- **Фаза 17.** Сетка, закрепление, тексты отказа — `timetableGrid.test.ts` (pin-rejected /
|
||||
no-teacher / unknown-lesson). Всё через `t(...)`.
|
||||
|
||||
Замечено рядом:
|
||||
|
||||
- `GET /api/catalog` по-прежнему отдаёт каркас без `lunchBreaks` (только `longBreakAfter`).
|
||||
Сетке расписания смены не нужны — они для решений. Молча расширять HTTP ревью не стало.
|
||||
- `OpeningASchoolDuringAMathLesson_...` с этой перепроверки падает и в одиночку — см. срез 1;
|
||||
это явка, не раскладка часов.
|
||||
|
||||
Calendar+обеды 20, планировщик 9, TimetableApi 6.
|
||||
|
||||
## Срез 5. Жизнь школы
|
||||
|
||||
- **Фазы:** 18–21
|
||||
|
||||
Reference in New Issue
Block a user