Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbd854d933 | ||
|
|
6aaee107a9 |
@@ -10,6 +10,8 @@ RF4 Spotter — неофициальный сервис свежих точек
|
|||||||
|
|
||||||
Актуальные следующие задачи находятся только в [ROADMAP](docs/ROADMAP.md). Старые планы и аудиты сохранены как история и больше не задают порядок работ. До внешнего запуска нужны сервер, DNS/TLS, production-секреты, публичные контакты, внешний backup и канал уведомлений.
|
Актуальные следующие задачи находятся только в [ROADMAP](docs/ROADMAP.md). Старые планы и аудиты сохранены как история и больше не задают порядок работ. До внешнего запуска нужны сервер, DNS/TLS, production-секреты, публичные контакты, внешний backup и канал уведомлений.
|
||||||
|
|
||||||
|
Разрешённые интеграции и недостающие первичные подтверждения сведены в [реестр разрешений](docs/source-permissions.md). Перед открытой публикацией пустые поля реестра являются блокером конкретного источника, особенно для изображений.
|
||||||
|
|
||||||
Web Docker-образ устанавливает зависимости через `npm ci` по lock-файлу и удаляет devDependencies после сборки. Локальные `.env` исключены из web build context.
|
Web Docker-образ устанавливает зависимости через `npm ci` по lock-файлу и удаляет devDependencies после сборки. Локальные `.env` исключены из web build context.
|
||||||
|
|
||||||
Очередь внешних наблюдений выбирает только ожидающие проверки записи на сервере и показывает их страницами по 50. Обработанные записи не скрывают более старые необработанные наблюдения.
|
Очередь внешних наблюдений выбирает только ожидающие проверки записи на сервере и показывает их страницами по 50. Обработанные записи не скрывают более старые необработанные наблюдения.
|
||||||
@@ -65,6 +67,8 @@ Production-контур для домена `rf4spotter.ru`, TLS, секреты
|
|||||||
Политика минимизации данных и ежедневная dry-run-first очистка описаны в [`docs/data-retention.md`](docs/data-retention.md).
|
Политика минимизации данных и ежедневная dry-run-first очистка описаны в [`docs/data-retention.md`](docs/data-retention.md).
|
||||||
|
|
||||||
Host-side мониторинг контейнеров, readiness, диска, объёма PostgreSQL/MinIO, резервных копий и TLS описан в [`docs/production-monitoring.md`](docs/production-monitoring.md).
|
Host-side мониторинг контейнеров, readiness, диска, объёма PostgreSQL/MinIO, резервных копий и TLS описан в [`docs/production-monitoring.md`](docs/production-monitoring.md).
|
||||||
|
|
||||||
|
Принятые границы стека, memory-cache, scheduler и хранилищ зафиксированы в [архитектурных решениях](docs/architecture-decisions.md). Порядок действий при заполнении диска, отказах PostgreSQL/MinIO, зависшем импорте, ошибке миграции и утечке секрета находится в [incident runbook](docs/incident-runbook.md).
|
||||||
Ежедневный systemd timer создаёт проверяемую копию до retention-очистки, а production Compose ограничивает рост JSON-логов контейнеров.
|
Ежедневный systemd timer создаёт проверяемую копию до retention-очистки, а production Compose ограничивает рост JSON-логов контейнеров.
|
||||||
|
|
||||||
Фактическое состояние DNS/TLS домена и серверный чек-лист ведутся в [`docs/deployment-status.md`](docs/deployment-status.md).
|
Фактическое состояние DNS/TLS домена и серверный чек-лист ведутся в [`docs/deployment-status.md`](docs/deployment-status.md).
|
||||||
|
|||||||
+2
-2
@@ -36,7 +36,7 @@
|
|||||||
- [x] **B14 · Атласные переходы сущностей.** Боковые списки рыб и водоёмов на detail-страницах получили компактные силуэты и отпечатки рядом с полным текстовым названием. Знаки продолжают систему каталога в рабочей навигации, а стрелка явно показывает переход к странице сочетания.
|
- [x] **B14 · Атласные переходы сущностей.** Боковые списки рыб и водоёмов на detail-страницах получили компактные силуэты и отпечатки рядом с полным текстовым названием. Знаки продолжают систему каталога в рабочей навигации, а стрелка явно показывает переход к странице сочетания.
|
||||||
- [x] **B15 · Целостность медиакаталога.** Локальный audit сводит статусы очереди и проверяет наличие файлов, SHA-256, фактические dimensions/MIME, каноническое соответствие approved-записей и бесхозные файлы. Проверка не обращается в сеть и может использоваться как pre-publication gate.
|
- [x] **B15 · Целостность медиакаталога.** Локальный audit сводит статусы очереди и проверяет наличие файлов, SHA-256, фактические dimensions/MIME, каноническое соответствие approved-записей и бесхозные файлы. Проверка не обращается в сеть и может использоваться как pre-publication gate.
|
||||||
|
|
||||||
- [ ] **Q01 · Документы источников.** Приложить или дать устойчивые ссылки на первичные разрешения RF4DB, RF4-STAT, RF4MAP и RF4 Posts; для каждого зафиксировать атрибуцию, точный production-лимит, срок хранения и процедуру удаления.
|
- [ ] **Q01 · Документы источников — реестр готов, нужны первичные подтверждения.** Создан единый production-gate с атрибуцией, общим лимитом 30 минут, хранением и процедурой отзыва для RF4DB, RF4-STAT, RF4MAP, RF4 Posts и официального RF4. До открытой публикации приложить устойчивые ссылки/копии первичных разрешений, контакты, даты и отдельно подтвердить право на изображения; пустое поле блокирует соответствующий источник.
|
||||||
- [ ] **Q02 · Управляемое удаление источника.** Добавить обнаружение изменённых/удалённых опубликованных записей без отдельного частого обхода: статус, журнал решения и безопасное исключение из активности после проверки.
|
- [ ] **Q02 · Управляемое удаление источника.** Добавить обнаружение изменённых/удалённых опубликованных записей без отдельного частого обхода: статус, журнал решения и безопасное исключение из активности после проверки.
|
||||||
- [ ] **Q03 · Целостность ссылок.** Проверять исходные ссылки только во время разрешённого планового обращения к площадке, разделяя `missing`, `temporary_error` и `blocked`; не создавать дополнительный сетевой цикл.
|
- [ ] **Q03 · Целостность ссылок.** Проверять исходные ссылки только во время разрешённого планового обращения к площадке, разделяя `missing`, `temporary_error` и `blocked`; не создавать дополнительный сетевой цикл.
|
||||||
- [x] **Q04 · Состояния ожидания.** Асинхронные admin-очереди получили каркасные карточки, `aria-busy`, очистку при ошибке и поддержку `prefers-reduced-motion`. Публичные страницы остаются SSR и не показывают искусственный skeleton; форма уже блокирует повторную отправку и сообщает «Отправка…».
|
- [x] **Q04 · Состояния ожидания.** Асинхронные admin-очереди получили каркасные карточки, `aria-busy`, очистку при ошибке и поддержку `prefers-reduced-motion`. Публичные страницы остаются SSR и не показывают искусственный skeleton; форма уже блокирует повторную отправку и сообщает «Отправка…».
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
- [ ] **Q14 · Полная CSP.** Расширить текущую CSP (`frame-ancestors`, `base-uri`, `object-src`) до `default-src`, `script-src`, `style-src`, `img-src`, `connect-src` и `form-action`. Сначала инвентаризировать inline scripts/styles Astro, затем внедрить nonce/hash или безопасное вынесение; проверить report/admin/OG без ослабления до произвольных внешних origin.
|
- [ ] **Q14 · Полная CSP.** Расширить текущую CSP (`frame-ancestors`, `base-uri`, `object-src`) до `default-src`, `script-src`, `style-src`, `img-src`, `connect-src` и `form-action`. Сначала инвентаризировать inline scripts/styles Astro, затем внедрить nonce/hash или безопасное вынесение; проверить report/admin/OG без ослабления до произвольных внешних origin.
|
||||||
- [ ] **Q15 · Частичная деградация главной.** Разделить получение activity, community signals и справочников так, чтобы отказ одного источника не превращал всю главную в общий 503. Для SSR не добавлять искусственный client-side loading/optimistic UI; показывать независимые `StatePanel` и корректный HTTP/cache статус.
|
- [ ] **Q15 · Частичная деградация главной.** Разделить получение activity, community signals и справочников так, чтобы отказ одного источника не превращал всю главную в общий 503. Для SSR не добавлять искусственный client-side loading/optimistic UI; показывать независимые `StatePanel` и корректный HTTP/cache статус.
|
||||||
- [x] **Q16 · Контракт OpenAPI.** `apps/api/openapi.json` детерминированно генерируется из FastAPI; CI проверяет его актуальность после backend suite. Изменение artifact обязательно рассматривается вместе с реализацией, а ручное редактирование не используется.
|
- [x] **Q16 · Контракт OpenAPI.** `apps/api/openapi.json` детерминированно генерируется из FastAPI; CI проверяет его актуальность после backend suite. Изменение artifact обязательно рассматривается вместе с реализацией, а ручное редактирование не используется.
|
||||||
- [ ] **Q17 · Эксплуатационные документы.** Добавить короткие ADR по Astro/FastAPI/PostgreSQL, локальному cache и стратегии scheduler, а также incident runbook для заполнения диска/PostgreSQL, отказа MinIO, зависших импортов, ошибок миграции и компрометации секретов.
|
- [x] **Q17 · Эксплуатационные документы.** Зафиксированы ADR по Astro/FastAPI/PostgreSQL, локальному cache, scheduler/cooldown и разделению PostgreSQL/MinIO. Incident runbook покрывает заполнение диска, отказ PostgreSQL/MinIO, зависшие импорты, ошибки миграций, компрометацию секретов и критерии закрытия без опасных reset/recreate операций.
|
||||||
- [ ] **Q18 · Минимальная observability.** До открытой альфы определить дешёвые метрики request count/latency/error rate, глубины moderation/staging и возраста последнего успешного импорта. Формат и exporter выбрать после выбора мониторинга сервера; полноценный tracing не внедрять без подтверждённой потребности.
|
- [ ] **Q18 · Минимальная observability.** До открытой альфы определить дешёвые метрики request count/latency/error rate, глубины moderation/staging и возраста последнего успешного импорта. Формат и exporter выбрать после выбора мониторинга сервера; полноценный tracing не внедрять без подтверждённой потребности.
|
||||||
|
|
||||||
### Административная панель
|
### Административная панель
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Архитектурные решения
|
||||||
|
|
||||||
|
## ADR-001 · Astro + FastAPI + PostgreSQL
|
||||||
|
|
||||||
|
Статус: принято. Astro отвечает за быстрый SSR-интерфейс и SEO, FastAPI — за типизированный API и фоновые операции, PostgreSQL — за канонические данные, блокировки и миграции. Next.js/Vinext не вводятся: второй web-runtime усложнит сборку, кэш и эксплуатацию без пользы для текущего продукта.
|
||||||
|
|
||||||
|
## ADR-002 · Локальный cache API
|
||||||
|
|
||||||
|
Статус: принято для одного API-процесса. Публичная активность хранится в ограниченном memory-cache 20 секунд и инвалидируется после изменений в том же процессе. Данные scheduler могут появиться с задержкой до TTL. Redis нужен только при нескольких API-процессах или измеренной проблеме; до этого он создаёт лишнюю stateful-зависимость.
|
||||||
|
|
||||||
|
## ADR-003 · Отдельный scheduler и общий cooldown
|
||||||
|
|
||||||
|
Статус: принято. Scheduler отделён от HTTP API, а попытка импорта резервируется в PostgreSQL до сетевого запроса. Endpoint одной площадки делят минимальный интервал 30 минут; ошибка также расходует окно, повторные ошибки увеличивают паузу до 24 часов. Ручной production-запуск проходит через тот же журнал, чтобы не обходить лимит.
|
||||||
|
|
||||||
|
## ADR-004 · PostgreSQL и MinIO как разные контуры данных
|
||||||
|
|
||||||
|
Статус: принято. Метаданные и moderation state хранятся в PostgreSQL; бинарные скриншоты — в MinIO под отдельными минимальными credentials. База не содержит большие изображения, а API не получает root-доступ к object storage. Backup считается полноценным только при согласованном сохранении обоих контуров и проверенном restore.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Incident runbook RF4 Spotter
|
||||||
|
|
||||||
|
Сначала зафиксировать время, revision из `/api/v1/admin/diagnostics`, симптомы и последние изменения. Не удалять volumes и не запускать миграции повторно вслепую. Если есть риск порчи или утечки, включить maintenance mode по `deploy/README.md`.
|
||||||
|
|
||||||
|
## Заполнение диска
|
||||||
|
|
||||||
|
1. Проверить host disk, размеры PostgreSQL/MinIO и возраст backup через `deploy/monitor.sh`.
|
||||||
|
2. Остановить scheduler, чтобы не росли импорт и логи; публичное чтение оставлять только если база стабильна.
|
||||||
|
3. Освободить место вне volumes: старые build-artifacts и журналы согласно системной retention. Не удалять файлы MinIO или PostgreSQL вручную.
|
||||||
|
4. Выполнить штатный retention dry-run, затем apply только после проверки отчёта. После восстановления места проверить `/ready` и создать свежий backup.
|
||||||
|
|
||||||
|
## PostgreSQL недоступен
|
||||||
|
|
||||||
|
1. Проверить контейнер, healthcheck, свободное место и последние логи без вывода секретов.
|
||||||
|
2. Не выполнять автоматический reset/recreate. При повреждении развернуть отдельный чистый контур и использовать `deploy/restore.sh` с последним проверенным backup.
|
||||||
|
3. После запуска сверить Alembic head, `/ready`, счётчики diagnostics и контрольные данные.
|
||||||
|
|
||||||
|
## MinIO недоступен
|
||||||
|
|
||||||
|
1. Проверить health, диск и доступ app-пользователя только к целевому bucket.
|
||||||
|
2. Отключить загрузку новых скриншотов или включить maintenance; текстовые заявки не считать потерянными.
|
||||||
|
3. После восстановления проверить stat bucket, отрицательную проверку глобального list и чтение одного тестового объекта подписанной ссылкой.
|
||||||
|
|
||||||
|
## Зависший импорт
|
||||||
|
|
||||||
|
1. Проверить import run, advisory lock, время старта и процесс scheduler. Не запускать второй импорт того же источника.
|
||||||
|
2. Если процесса уже нет, сохранить диагностику и пометить run failed штатным административным способом; не менять опубликованные записи.
|
||||||
|
3. Следующий запуск делать только после site-wide cooldown. При повторных ошибках оставить backoff и проверить DOM-контракт на fixture.
|
||||||
|
|
||||||
|
## Ошибка миграции
|
||||||
|
|
||||||
|
1. Остановить rollout; не запускать API новой версии поверх неизвестной схемы.
|
||||||
|
2. Сохранить логи migrate и backup. Определить, транзакционна ли упавшая ревизия и какой `alembic current` фактически записан.
|
||||||
|
3. Предпочесть исправленную forward migration. Rollback приложения допустим, только если старая версия совместима с текущей схемой; восстановление БД — по документированной release-процедуре.
|
||||||
|
|
||||||
|
## Компрометация секрета
|
||||||
|
|
||||||
|
1. Немедленно включить maintenance и отозвать затронутый секрет: admin token, Basic Auth, rate-limit HMAC, app S3 или root MinIO.
|
||||||
|
2. Создать новый уникальный секрет, обновить `.env.production` вне Git и перезапустить только зависимые сервисы. Для MinIO сначала выпустить нового app-пользователя, проверить policy, затем удалить старого.
|
||||||
|
3. Проверить moderation history, auth attempts, object operations и deploy-доступ за предполагаемый период без публикации персональных данных.
|
||||||
|
4. Если мог раскрыться `RATE_LIMIT_SECRET`, учитывать, что сменятся HMAC-идентификаторы клиентов. Зафиксировать инцидент и время ротации.
|
||||||
|
|
||||||
|
## Закрытие инцидента
|
||||||
|
|
||||||
|
`/health` и `/ready` успешны, monitor не выдаёт предупреждений, последняя миграция и backup проверены, причина и принятые меры записаны. После критического инцидента обязателен отдельный restore drill и короткое обновление этого runbook.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Реестр разрешений источников
|
||||||
|
|
||||||
|
Этот файл — production-gate, а не заявление о правах. Словесного подтверждения достаточно для разработки интеграции, но перед открытой альфой у каждого источника должна быть сохранена первичная ссылка или копия разрешения, дата и контакт стороны. Пустое поле блокирует публикацию данных соответствующего источника.
|
||||||
|
|
||||||
|
| Источник | Данные | Атрибуция на сайте | Лимит | Хранение | Удаление | Первичное подтверждение |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| RF4DB | уловы, справочники, разрешённые изображения | название + ссылка на исходную запись/страницу | не чаще 1 запроса на площадку за 30 минут, ошибки учитываются | нормализованные данные; raw по retention policy | отключить источник, скрыть публикации, очистить raw и согласованные данные по запросу | **требуется приложить** |
|
||||||
|
| RF4-STAT | уловы и посты | название + ссылка на запись | не чаще 1 запроса на площадку за 30 минут, общий для endpoint | то же | то же | **требуется приложить** |
|
||||||
|
| RF4MAP | точки и разрешённые media-кандидаты | название + ссылка на страницу | не чаще 1 запроса на площадку за 30 минут, включая media/CDN | media только локально по hash; публикация после review | удалить mapping и локальный оригинал, затем записи источника | **требуется приложить** |
|
||||||
|
| RF4 Posts | точки | название + ссылка на запись | не чаще 1 запроса на площадку за 30 минут | нормализованные данные; raw по retention policy | отключить и удалить по source system | **требуется приложить** |
|
||||||
|
| Официальный RF4 | рекорды и отдельно проверенные справочные изображения | «Официальный сайт RF4» + ссылка | не чаще 1 запроса на домен за 30 минут | по общей retention policy; media в карантине до review | скрыть/удалить mapping и данные конкретного источника | **уточнить основание для media-публикации** |
|
||||||
|
|
||||||
|
## Требования к подтверждению
|
||||||
|
|
||||||
|
- устойчивый URL либо сохранённый исходный файл/скриншот с датой;
|
||||||
|
- кто дал разрешение и в каком качестве;
|
||||||
|
- точный перечень данных и право публичной переработки/публикации;
|
||||||
|
- отдельное упоминание изображений, если они используются;
|
||||||
|
- допустимая частота, атрибуция, срок хранения и процедура отзыва;
|
||||||
|
- дата следующей ревизии условий.
|
||||||
|
|
||||||
|
## Процедура отзыва
|
||||||
|
|
||||||
|
1. Немедленно отключить источник и scheduler endpoint.
|
||||||
|
2. Скрыть его опубликованные записи из активности без физического уничтожения аудита.
|
||||||
|
3. Выгрузить список затронутых нормализованных записей и media mappings.
|
||||||
|
4. Выполнить согласованное удаление; сохранить только минимальный журнал факта удаления без исходного payload.
|
||||||
|
5. Проверить публичный API, sitemap/страницы сущностей и media audit, затем зафиксировать решение в журнале эксплуатации.
|
||||||
Reference in New Issue
Block a user