Перейти к содержанию

Подготовка архива к выпуску

В двенадцатом состоянии «Архив» объединяет политику заявки, ownership, закрытое S3, подтверждение версии, перекодирование, очередь и очистку. Подготовим передачу проекта к выпуску. Учебный пакет остаётся локальным черновиком: зависимости, база, бакет и worker не запускались. Поэтому наша задача — описать проверяемые границы и порядок будущего ввода, не превращая исходники в заявление о готовой производственной системе.

Выпуск архива отличается от публикации статической статьи. Работающий сервер должен иметь реальные права, ограниченные процессы, управляемые секреты и процедуру восстановления. Одновременно нужно сохранить контракт для пользователя: upload создаёт попытку, confirm закрепляет версию, ready разрешает короткий download, удаление сначала запрещает новые операции и только потом освобождает байты. Этот контракт остаётся ориентиром для всех эксплуатационных решений.

Версии и воспроизводимая среда

В исходниках закреплены прямые версии pg 8.13.3, AWS SDK 3.758.0 и sharp 0.33.5. Для runtime выбран учебный Node.js 22.14.0. Их существование и API сверены по первичным источникам, но транзитивные зависимости не разрешались: package-lock.json отсутствует. Точная строка direct dependency не является полной воспроизводимостью установки, поскольку вложенные зависимости могут использовать диапазоны.

Для отдельной лаборатории выбирают одну папку состояния, подготавливают окружение, получают lockfile и фиксируют его вместе с проверенной средой. Нельзя переносить незаметно часть файлов lesson-08 в lesson-12: старый одноразовый обработчик не соблюдает новый lease-протокол. Снимки нужны для учебного сравнения, а не для смешивания двух поколений одной процедуры. Начальная SQL-схема применяется только к пустой базе.

Полный файл package.json состояния 12:

{
  "name": "archive-lesson-12",
  "private": true,
  "type": "module",
  "engines": {
    "node": ">=22.14.0"
  },
  "dependencies": {
    "pg": "8.13.3",
    "@aws-sdk/client-s3": "3.758.0",
    "@aws-sdk/s3-presigned-post": "3.758.0",
    "@aws-sdk/s3-request-presigner": "3.758.0",
    "sharp": "0.33.5"
  }
}

Указанные исторические pins помогают обсуждать конкретный API; они не объявлены актуальными безопасными версиями для публичного сервиса. Перед настоящим выпуском проверяют обновления безопасности runtime, libvips/sharp, SDK и базового окружения, затем согласованно обновляют и проверяют пример. Обновить только номер sharp в статье недостаточно: бинарная библиотека, доступные платформы и лимиты декодирования тоже участвуют в результате.

Границы процессов и секретов

API слушает loopback и получает доступ к базе и хранилищу через окружение. За публичным входом нужен HTTPS и ограничения запросов, размер управляющего JSON и частота резервирования. Lab bearer-токены заменяют реальной авторизацией с временем истечения и отзывом. Если организация использует cookies, добавляют CSRF-токен и проверку Origin для изменяющих операций; защитные cookie-атрибуты применяются вместе с этим протоколом.

Worker работает отдельным процессом с ограничением памяти, CPU и общего времени обработки. Недоверенные изображения не декодируются внутри API. Время процесса согласуют с lease: двухминутное право фиксации требует более короткой верхней границы либо реализованного heartbeat. Cleanup запускается отдельной ролью по расписанию и получает права удаления только управляемых префиксов. Такой порядок позволяет ограничить последствия ошибки каждого компонента.

Credentials S3 не попадают в браузер. Upload и download передают только короткие разрешения. В журнале не сохраняются подписи, Authorization, имена документов или байты. Для расследования достаточно UUID, состояния и безопасного кода события. Даже путь объекта может раскрывать структуру данных, поэтому внешние панели поддержки должны использовать идентификатор карточки и проверяемый доступ к подробностям, а не пересылку подписанного URL.

Сервисы имеют разные обязанности готовности. HTTP health подтверждает способность процесса ответить; readiness для upload должен учитывать доступность PostgreSQL и поддерживаемые функции бакета. Worker оценивается по очереди и последнему успешному завершению, cleanup — по возрасту задолженности. Один зелёный /health не доказывает работоспособности всех частей архива и не заменяет наблюдение бизнес-состояний файлов.

Проверка провайдера и данных

Совместимость S3 проверяют предметно: точные POST conditions, отклонение лишнего размера, HEAD с VersionId, GET принятой версии после перезаписи, CORS из нужного origin, пагинация списка версий и частичные ошибки пакетного удаления. Эти пункты следуют из выбранного протокола. Наличие слова S3 на странице поставщика не подтверждает каждый из них и не гарантирует одинаковое поведение delete markers.

Для собственных ручных сценариев нужны два пользователя. Алиса создаёт файл, Боб пробует его подтвердить, скачать и удалить: каждый раз ожидается отказ без раскрытия карточки. После обработки Алиса получает WebP собственной версии. После смены состояния на deleting новый URL не выдаётся; старая ссылка имеет собственный короткий срок. Такие сценарии показывают границы прав лучше, чем проверка только счастливого пути одного пользователя.

Проверка изображений должна включать корректный PNG, JPEG с ориентацией, статический WebP, повреждённый файл, ложный MIME и слишком большие размеры. Полный decoder и перекодирование должны завершиться до ready. Не существует учебного антивирусного заключения, которое можно приложить к этим результатам: антивирусный движок здесь не включён. Для расширения на PDF и офисные файлы проектируют отдельный quarantine и реальный сервис проверки.

Полный файл release.md состояния 12:

# Передача «Архива» на сопровождение

Статус учебного пакета: example_execution=not_run. Зависимости, PostgreSQL, S3 и обработчик не запускались.
Прямые версии закреплены; package-lock.json ещё не разрешён.

Для отдельной лаборатории: выберите один lesson-NN, скопируйте .env.example в .env,
задайте два случайных независимых bearer-токена, закрытый versioned bucket и credentials.
После самостоятельной установки зависимостей примените schema.sql в пустую базу.
Запуск API: node --env-file=.env server.mjs. Этап 08: node --env-file=.env process-one.mjs UUID.
Начиная с этапа 09 запускайте worker.mjs вместо process-one.mjs; cleanup.mjs доступен с этапа 11.
Не применяйте полный schema.sql повторно к существующей базе: это начальная схема, а не миграция.

Перед реальным выпуском требуется отдельная проверка провайдера S3: exact POST policy,
versioning, HEAD VersionId, GET с VersionId, CORS, пагинация списка версий, частичные ошибки delete.
Учебные bearer-токены заменить внешней проверенной авторизацией с отзывом и сроком действия.
При переходе на cookies добавить CSRF-проверку, проверку Origin и SameSite/HttpOnly/Secure.
Лимиты CPU/RAM и timeout для image worker задаются изолированным процессом/контейнером.
Обновление безопасности Node/sharp/SDK и проверка образов обязательны для конкретного выпуска.
Аудит не содержит имён файлов, URL и credentials. Бакет не используется как статический сайт.
Резервная копия охватывает PostgreSQL и точные object versions; восстановление сверяет ссылки.
Долгосрочные lifecycle rules не должны удалять referenced versions раньше DB retention.

Восстановление и порядок изменения

Резервная копия должна согласованно охватывать карточки PostgreSQL и referenced object versions. Восстановленная база, указывающая на уже удалённые версии, не восстановит документы сама. После восстановления сверяют пары key/version и статусы; временные ссылки генерируют заново. Копировать старые presigned URL бессмысленно: они истекут и несут лишние права доступа в архиве резервной копии.

Перед изменением схемы выпускают совместимые версии API и worker либо останавливают новые claims на время согласованного перехода. Например, новая политика статусов должна быть понятна обоим процессам. Полный schema.sql не является миграцией для существующей базы, поэтому его повторное применение не допустимый план обновления. Реальная миграция отдельно описывает входное состояние, изменение и способ отката без потери карточек.

Откат к прежнему приложению тоже зависит от данных. Если новый worker записал другой формат производной или новое состояние, прежний код должен уметь их читать либо откат потребует совместимого слоя. Простое возвращение старых файлов не гарантирует восстановления поведения. Поэтому перед выпуском фиксируют версию приложения в операционном журнале и сохраняют подходящие исходники, lockfile и конфигурацию среды.

В завершённой учебной цепочке вы можете объяснить путь каждой фотографии, отличить подтверждённые метаданные от декодированного содержимого, указать проверку владельца и причину каждого интервала очистки. ZIP содержит двенадцать накопительных состояний, а план — результаты и связи уроков. Это конкретная основа для будущей самостоятельной лаборатории; заявлять успешное исполнение или производственный выпуск до отдельной проверки среды мы не можем.

Предыдущий урок: Очистка сирот и сроки хранения

Оглавление серии · Исходники всех состояний.

Документация: Node.js: выбранный runtime, sharp: требования.