Объявления администрации (#84) — те же изменения, что в PR #85 в dev, но перенесённые на mainбез рейтинговых изменений из dev (#22, #23, #76, #77, #80) и без удаления test-контура. Ветка сделана от origin/main, коммиты объявлений перенесены через cherry-pick.
Описание самой фичи, модель угрозы и детали — в PR #85.
Коммиты
07a14ec Гитигнор: локальный AGENTS.md не идёт в репозиторий (из 2e496a3)
976b8fc Объявления: модель, API игрока и админки, очистка HTML (из a0a0e52; конфликт только в импортах schemas/api.py, в main нет Annotated из рейтинга; миграция 0015 сразу от 0013)
d31e998 Объявления: окно у игрока и редактор в админке (из ab1fc3f, без конфликтов)
Миграции
В main последняя миграция — 0013, в dev — рейтинговая 0014. Поэтому 0015_announcements отходит от 0013 в обеих ветках, а в dev пустая 0016 сводит ветки 0014 и 0015 (коммит ec0445f в PR #85). Проверенный путь прода на копии базы:
сейчас прод на 0013;
этот релиз: 0013 → 0015 — создаются таблицы объявлений;
позже, когда в main придёт dev с рейтингом: alembic сам применит 0014 (рейтинговые столбцы) и 0016.
Без этого прод после релиза стоял бы на 0015, и при переходе на dev alembic счёл бы базу актуальной — 0014 не применилась бы никогда.
Проверки
pytest — 161 passed (набор main + 14 тестов объявлений).
npm run build (typecheck + сборка) — зелёный.
schema.d.ts сверен с живым OpenAPI этой ветки — совпадает с перенесённым (полей рейтинга нет).
Миграции: путь прода 0013 → 0015 → (dev) 0014 + 0016 прогнан на одной базе; все таблицы и столбцы на месте.
В браузере не проверялось — расширение Chrome в сессии не подключено.
Отклонения от плана
Нет в самой фиче. Этот PR — дополнительный, по просьбе владельца: объявления нужны в проде раньше рейтинга.
Будущее слияние dev → main
В main нет собственных изменений, кроме релизных merge-коммитов. Пробное слияние dev (с PR #85) в эту ветку даёт один конфликт — строка импортов в backend/app/schemas/api.py; правильная версия — из dev (from typing import Annotated, Literal). Остальное, включая schema.d.ts, сливается автоматически.
## Что сделано
Объявления администрации (#84) — те же изменения, что в PR #85 в `dev`, но перенесённые на `main` **без** рейтинговых изменений из `dev` (#22, #23, #76, #77, #80) и без удаления test-контура. Ветка сделана от `origin/main`, коммиты объявлений перенесены через cherry-pick.
Описание самой фичи, модель угрозы и детали — в PR #85.
## Коммиты
- `07a14ec` Гитигнор: локальный AGENTS.md не идёт в репозиторий (из `2e496a3`)
- `976b8fc` Объявления: модель, API игрока и админки, очистка HTML (из `a0a0e52`; конфликт только в импортах `schemas/api.py`, в `main` нет `Annotated` из рейтинга; миграция `0015` сразу от `0013`)
- `d31e998` Объявления: окно у игрока и редактор в админке (из `ab1fc3f`, без конфликтов)
## Миграции
В `main` последняя миграция — `0013`, в `dev` — рейтинговая `0014`. Поэтому `0015_announcements` отходит от `0013` в обеих ветках, а в `dev` пустая `0016` сводит ветки `0014` и `0015` (коммит `ec0445f` в PR #85). Проверенный путь прода на копии базы:
1. сейчас прод на `0013`;
2. этот релиз: `0013 → 0015` — создаются таблицы объявлений;
3. позже, когда в `main` придёт `dev` с рейтингом: alembic сам применит `0014` (рейтинговые столбцы) и `0016`.
Без этого прод после релиза стоял бы на `0015`, и при переходе на `dev` alembic счёл бы базу актуальной — `0014` не применилась бы никогда.
## Проверки
- `pytest` — **161 passed** (набор `main` + 14 тестов объявлений).
- `npm run build` (typecheck + сборка) — зелёный.
- `schema.d.ts` сверен с живым OpenAPI этой ветки — совпадает с перенесённым (полей рейтинга нет).
- Миграции: путь прода `0013 → 0015 → (dev) 0014 + 0016` прогнан на одной базе; все таблицы и столбцы на месте.
- В браузере не проверялось — расширение Chrome в сессии не подключено.
## Отклонения от плана
Нет в самой фиче. Этот PR — дополнительный, по просьбе владельца: объявления нужны в проде раньше рейтинга.
## Будущее слияние dev → main
В `main` нет собственных изменений, кроме релизных merge-коммитов. Пробное слияние `dev` (с PR #85) в эту ветку даёт **один** конфликт — строка импортов в `backend/app/schemas/api.py`; правильная версия — из `dev` (`from typing import Annotated, Literal`). Остальное, включая `schema.d.ts`, сливается автоматически.
Часть #84 — задачу закроет PR #85 в `dev`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
AGENTS.md — такой же локальный гайд для ассистента, как CLAUDE.md, только
для другого инструмента. Он лежал в рабочем дереве незакоммиченным и висел
в git status; теперь он в блоке «AI-ассистенты» рядом с CLAUDE.md
и .claude/, так что случайный `git add .` его не подхватит. #84
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Объявление администрации показывается игроку окном в свой период, пока игрок
не закроет его («Понятно»). Отметка о закрытии хранится на сервере с номером
версии: правка с «показать заново» поднимает версию, и закрывшие прежнюю
увидят объявление снова — ответ помечен updated («обновлено»). Флаг
show_to_new_players=false прячет объявление от зарегистрировавшихся после
начала показа. Пересекающиеся объявления идут от старого к новому.
Текст приходит HTML-ом из редактора админки и сохраняется только после
очистки по белому списку (b, em, mark и mark.red, p, br): атрибуты
отбрасываются, script/style/svg — вместе с содержимым, текст экранируется
заново. Фронт вставляет только этот HTML.
API: GET /api/announcements/pending, POST /api/announcements/{id}/ack;
админка — список со статусом и счётчиком «закрыли N из M», создание, правка,
«снять с показа», удаление, всё в аудит. SSE-событие announcements активным
игрокам. Миграция 0015 идемпотентная.
Тесты: очистка (XSS-попытки, вложенные div), права, период и порядок,
«новые игроки», повторный показ, снятие, удаление, валидация. #84
Перенесено в main без рейтинга из a0a0e52; миграция 0015 — сразу от 0013
(как в ec0445f).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Окно — вариант E из макетов: заголовок в плашке-шапке, текст, точки очереди
и «Понятно», крестика нет. Очередь идёт от старого к новому; закрытое сразу
уходит из кэша, следующее открывается без ожидания сети. У повторно
показанного объявления под заголовком — красная пометка «обновлено».
AppShell показывает окно на любой странице и только когда пароль задан:
обязательное окно пароля всегда первое. Новые и изменённые объявления
приходят SSE-событием announcements, отложенное начало показа — перезапросом
раз в 5 минут.
Админка — вкладка «Объявления» с редактором R1: contenteditable и панель
(жирный, курсив, золотой и красный акцент, эмодзи, снятие оформления),
вставка и перетаскивание только простым текстом, счётчик символов, период
показа по МСК, переключатели «показывать новым игрокам» и «показать заново».
Предпросмотр — тем же окном, что у игрока. Список со статусом, счётчиком
«закрыли N из M» и действиями: изменить, снять с показа, дублировать,
удалить. Выделение текста в форме — полупрозрачный оранжевый вместо синего.
schema.d.ts пересобран из OpenAPI. #84
Перенесено в main без рейтинга из ab1fc3f; schema.d.ts сверен с OpenAPI этой ветки.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что сделано
Объявления администрации (#84) — те же изменения, что в PR #85 в
dev, но перенесённые наmainбез рейтинговых изменений изdev(#22, #23, #76, #77, #80) и без удаления test-контура. Ветка сделана отorigin/main, коммиты объявлений перенесены через cherry-pick.Описание самой фичи, модель угрозы и детали — в PR #85.
Коммиты
07a14ecГитигнор: локальный AGENTS.md не идёт в репозиторий (из2e496a3)976b8fcОбъявления: модель, API игрока и админки, очистка HTML (изa0a0e52; конфликт только в импортахschemas/api.py, вmainнетAnnotatedиз рейтинга; миграция0015сразу от0013)d31e998Объявления: окно у игрока и редактор в админке (изab1fc3f, без конфликтов)Миграции
В
mainпоследняя миграция —0013, вdev— рейтинговая0014. Поэтому0015_announcementsотходит от0013в обеих ветках, а вdevпустая0016сводит ветки0014и0015(коммитec0445fв PR #85). Проверенный путь прода на копии базы:0013;0013 → 0015— создаются таблицы объявлений;mainпридётdevс рейтингом: alembic сам применит0014(рейтинговые столбцы) и0016.Без этого прод после релиза стоял бы на
0015, и при переходе наdevalembic счёл бы базу актуальной —0014не применилась бы никогда.Проверки
pytest— 161 passed (наборmain+ 14 тестов объявлений).npm run build(typecheck + сборка) — зелёный.schema.d.tsсверен с живым OpenAPI этой ветки — совпадает с перенесённым (полей рейтинга нет).0013 → 0015 → (dev) 0014 + 0016прогнан на одной базе; все таблицы и столбцы на месте.Отклонения от плана
Нет в самой фиче. Этот PR — дополнительный, по просьбе владельца: объявления нужны в проде раньше рейтинга.
Будущее слияние dev → main
В
mainнет собственных изменений, кроме релизных merge-коммитов. Пробное слияниеdev(с PR #85) в эту ветку даёт один конфликт — строка импортов вbackend/app/schemas/api.py; правильная версия — изdev(from typing import Annotated, Literal). Остальное, включаяschema.d.ts, сливается автоматически.Часть #84 — задачу закроет PR #85 в
dev.🤖 Generated with Claude Code
Объявление администрации показывается игроку окном в свой период, пока игрок не закроет его («Понятно»). Отметка о закрытии хранится на сервере с номером версии: правка с «показать заново» поднимает версию, и закрывшие прежнюю увидят объявление снова — ответ помечен updated («обновлено»). Флаг show_to_new_players=false прячет объявление от зарегистрировавшихся после начала показа. Пересекающиеся объявления идут от старого к новому. Текст приходит HTML-ом из редактора админки и сохраняется только после очистки по белому списку (b, em, mark и mark.red, p, br): атрибуты отбрасываются, script/style/svg — вместе с содержимым, текст экранируется заново. Фронт вставляет только этот HTML. API: GET /api/announcements/pending, POST /api/announcements/{id}/ack; админка — список со статусом и счётчиком «закрыли N из M», создание, правка, «снять с показа», удаление, всё в аудит. SSE-событие announcements активным игрокам. Миграция 0015 идемпотентная. Тесты: очистка (XSS-попытки, вложенные div), права, период и порядок, «новые игроки», повторный показ, снятие, удаление, валидация. #84 Перенесено в main без рейтинга из a0a0e52; миграция 0015 — сразу от 0013 (как вec0445f). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>