55 lines
3.9 KiB
Markdown
55 lines
3.9 KiB
Markdown
# Фаза 87. Субъект кадра
|
||
|
||
## Зависимости
|
||
|
||
- [Фаза 66](../11-events/66-scene-prompt.md)
|
||
- [Фаза 60](../off-queue/60-portrait-models.md) (пресеты и shot kind)
|
||
- [Фаза 39](../08-session/39-school-owners.md) (гость уже генерирует портрет человека)
|
||
|
||
## Зачем
|
||
|
||
Кабинет и футболка — не человек в URL портрета. Появляется HTTP субъекта «узел» и «вещь»,
|
||
PNG на диске, kind `scene`/`thing` без лифта живых пресетов.
|
||
|
||
## Задачи
|
||
|
||
- [ ] `GET`/`POST` `.../schools/{id}/nodes/{nodeId}/image` и `.../image/prompt`. Ключ узла —
|
||
id карты. PNG: `saves/{id}.images/node.{safeId}.png`
|
||
- [ ] `GET`/`POST` `.../schools/{id}/things/{defName}/image` (query `color`) и `.../image/prompt`.
|
||
PNG: `saves/{id}.images/thing.{def}.{color\|none}.png`. Нет instance id
|
||
- [ ] Сборка узла: Room/Territory prompt + fill с текстом + погода, если улица. Без внешности и
|
||
одежды человека. При ненулевой занятости узла — не больше одного общего фрагмента из
|
||
`SimulationOptions`, не имена
|
||
- [ ] Сборка вещи: `prompt` def + цвет + износ, если смотрим надетое (износ в промпте; ключ файла
|
||
без износа). Молчаливый def — не Swarm
|
||
- [ ] Пустой вклад — `400` `cannot-generate`. Нет узла/def — `404`. Swarm как портрет (`503`/`502`/`504`)
|
||
- [ ] Гость: тот же успех, что `POST .../people/.../portrait`, не `403`
|
||
- [ ] В шаблоне `swarmui.json` у пресетов shot kind `scene` и `thing`. Живая школа без них не
|
||
переписывается; fallback строки в `SimulationOptions`
|
||
- [ ] [`protocol.md`](../../protocol.md) — маршруты и коды, тем же коммитом. Сокет не бампить.
|
||
`PortraitKind` человека не расширять значением `scene`
|
||
|
||
## Тесты, без которых фаза не закрыта
|
||
|
||
- [ ] GET картинки узла до POST — `404` `image-missing` (или согласованный код в protocol.md)
|
||
- [ ] POST класса: prompt содержит место/fill, не «teenage girl» / возраст карточки
|
||
- [ ] POST узла без вклада (этаж/лестница без prompt) — `400`, Swarm не звали
|
||
- [ ] POST `Chair` — `400` `cannot-generate`
|
||
- [ ] POST `TShirt?color=White` — prompt английский про футболку, без субъекта-человека
|
||
- [ ] Гость POST узла — не `403` (тот же класс исхода, что портрет; хост с фикстурой Swarm или
|
||
тот же skip-контракт, что у портрета)
|
||
- [ ] Живой `portraitSettings` без kind `scene` генерирует узел через fallback и не перезаписывает
|
||
сейв пресета
|
||
- [ ] Occupancy > 0 добавляет не больше одного общего фрагмента; имён людей в prompt нет
|
||
- [ ] Сокет Version не меняется
|
||
|
||
## Критерий готовности
|
||
|
||
- curl/хостовый тест: POST кабинета → PNG на диске; GET отдаёт image/png
|
||
- «Показать промпт» узла доступен HTTP, даже если кнопки в UI ещё нет
|
||
- Отфильтрованные тесты: AppHost (маршруты), сборщик на сервере; не весь раствор
|
||
|
||
## Стоп
|
||
|
||
Не кнопки в DOM. Не автоген всем узлам. Не ControlNet. Не бамп сокета. Не групповые лица.
|