Учебник веб-разработки
Разделы учебника
На этой странице

Начало

Программа учебника

На примере Atmanki изучаем JavaScript и TypeScript, React, Next.js, управление состоянием, API, Strapi и развёртывание. Сквозной проект — сайт «Атмановских кулачек»: от преобразования данных и компонентов до публикации контента и релиза на VPS. В интерфейсе используются Mantine и собственный UIKit, для контрактов — Zod и tRPC, для хранения — PostgreSQL и Garage S3.

Читать онлайн · Запустить проект

Для кого написан учебник

Предполагаем математический бэкграунд: множества и отображения, логика, отношения, графы, индукция и базовое понимание сложности алгоритмов. Опыт JavaScript, React или эксплуатации серверов при этом не обязателен. Перед векторным поиском кратко освежаем линейную алгебру, перед оценкой качества и задержек — вероятность и статистику. Знание теории категорий не требуется.

Объяснения связывают модель, её свойства и исполняемый пример:

  • Типы — множества допустимых значений; объект — произведение, tagged union — размеченная сумма. Отдельно рассматриваем ограничения этой модели для TypeScript.
  • Валидация — проверка предиката и разбор внешнего значения в модель приложения; преобразование и ошибка разбора описываются явно.
  • Чистая функция — отображение с явным входом; композиция и законы проверяются на примерах, побочные эффекты рассматриваются отдельно.
  • Переход состояния — step: State × Event → State; для недопустимых событий явно выбираем отказ, отсутствие изменения или отдельный результат перехода.
  • Реактивность — зависимости и значения во времени; сравниваем дискретные события и модель сигнала, прежде чем связывать понятия с библиотеками.
  • Распределённая агрегация — объединение частичных результатов; проверяем ассоциативность, нейтральный элемент и условия перестановки.
  • Идемпотентность — f(f(s)) = f(s) для фиксированной операции и моделируемого эффекта. Эта формула не утверждает одинаковых ответов или однократной доставки.

Математическая модель сопровождается областью применимости и контрпримером: числа JavaScript не являются точной вещественной арифметикой, сеть может потерять ответ, а типы не выполняют проверку HTTP-данных во время работы программы.

Как пользоваться учебником

Ниже — последовательная программа написанного учебника: основы, разбор Atmanki и лаборатории. Все части имеют материалы и критерии самостоятельной проверки. Готовый текст лаборатории не означает, что её внешние сервисы уже испытаны: границы проверки отделяют выполненные примеры от ручных браузерных и инфраструктурных опытов.

Читайте части по порядку, если осваиваете стек впервые. Если знаете основы, переходите к нужной части и сверяйтесь с её входными требованиями. Команды выполняются из корня репозитория, если явно не указан другой каталог. Документация описывает код; наличие инструкции не подтверждает публикацию изменения или его проверку на живом сайте.

Устройство учебной главы

Каждая новая или переработанная глава следует одному порядку:

  1. Задача и знания, которые нужны для её решения.
  2. Понятие, математическая модель, небольшая схема, её границы и типичная ошибка.
  3. Применение в Atmanki со ссылкой на исходный код.
  4. Самостоятельное изменение на локальных учебных данных.
  5. Проверка результата и вопросы для объяснения своими словами.

Проверки вводятся вместе с примерами с самого начала; отдельная часть о качестве позже систематизирует инструменты. Учебный пример, упражнение и реализованное поведение приложения всегда обозначаются отдельно.

Схемы как часть объяснения

Схема отвечает на один вопрос и дополняется пояснением: что означают узлы, стрелки, состояния и границы. Для сложной темы используем несколько небольших схем: общая модель → конкретный сценарий → отказ или контрпример. Один рисунок не должен смешивать зависимости кода, движение данных и время.

Ниже — карта роли иллюстраций в частях учебника. Схемы встроены в главы; Mermaid поддерживается документационным сайтом. Не каждое действие требует рисунка: короткую последовательность команд удобнее читать текстом.

ЧастьКакие схемы нужны
I. НачалоБраузер, приложение, CMS, БД и медиа; путь исходника до работающей страницы
II. JS/TS и FPКомпозиция функций; ссылки и мутация; порядок асинхронных действий
III. Данные и переходыПроизведение и размеченная сумма; граница валидации; автомат допустимых состояний
IV. ReactДерево компонентов; поток props и событий; Flux; граф реактивных зависимостей; подписка и очистка
V. ИнтерфейсСлои CSS; тема и локальная геометрия; композиция слотов; адаптивные состояния
VI. Next.js и кешиВременные шкалы CSR/SSR/SSG/ISR; уровни кеша и ключи; публикация и ревалидация; холодный запрос и отказ
VII. APIОдин сценарий через разные API; запрос и ответ; потерянный ответ и повтор; конкурентная обработка ключа идемпотентности
VIII. ХранилищаER-диаграмма; колонки и JSONB; строчное и столбцовое чтение; MapReduce shuffle; векторные соседи; реплики и партиции
IX. Strapi и S3Модель контента; draft/publish; загрузка файла и публичное чтение; запись CMS и объект Garage
X. Инструменты и проверкиИсходник, AST, анализ и сборка; границы проверок; цикл изменения; дерево гипотез расследования
XI. DevOpsСеть Compose; pipeline и digest; переключение релиза; резервная копия и восстановление

Используем flowchart для структуры и зависимостей, sequence diagram для взаимодействий во времени, state diagram для переходов, ER-диаграмму для связей данных. Геометрию интерфейса и численные результаты показываем отдельными макетами или графиками, если схема узлов их не объясняет.

Пример: вычисления и граница эффекта

Это концептуальная схема глав FP/валидации, а не описание конкретной реализации клиента CMS. Стрелки обозначают передачу значений, а не время.

Исходник схемы
flowchart LR
  IO["HTTP: внешний эффект"] --> Raw["Внешнее значение: unknown"]
  Raw --> Parse["Разбор и валидация"]
  Parse --> Data["Допустимые данные"]
  Parse --> Error["Ошибка разбора"]
  Data --> Transform["Чистое преобразование"]
  Transform --> Model["Модель представления"]

Разбор имеет два исхода: данные или ошибка. После успешного разбора преобразование работает с явным входом; сетевой доступ остаётся за его границей. Это позволяет отдельно проверять вычисление и поведение при ошибке источника.

Пример: сумма состояний запроса

Автомат — учебная модель одного запроса без параллельных попыток и отмены. Переходы подписаны событиями; данные каждого состояния уточняются в ADT-главе.

Исходник схемы
stateDiagram-v2
  [*] --> Idle
  Idle --> Loading: Запросить
  Loading --> Success: Получен результат
  Loading --> Failure: Получена ошибка
  Success --> Loading: Обновить
  Failure --> Loading: Повторить

Здесь выбрано только одно состояние из Idle | Loading | Success | Failure, поэтому одновременные «загрузка» и «ошибка» не представляются двумя независимыми флагами. Если при обновлении нужно сохранять прошлые данные, расширяем модель явно. Одного рисунка недостаточно: тип должен задавать, какие данные доступны в каждом состоянии, а реализация — соблюдать показанные переходы.

Часть I. Начало и рабочее окружение

Вход: математический бэкграунд, описанный выше, и умение пользоваться компьютером и браузером. Практические инструменты разработки вводятся с нуля. Результат: запускаете проект и можете проследить путь от исходника до страницы.

  1. Что строим: браузер, сервер, CMS, база и хранилище — архитектура.
  2. Терминал, Git, ветки и worktree — первый рабочий цикл.
  3. Node.js, пакеты, pnpm workspace, установка и dev-режим — быстрый старт.
  4. Основа веб-страницы: HTML, семантика, DOM, CSS и инструменты браузера — веб-платформа.
  5. Редактор и первые проверки: навигация по коду, диагностика TypeScript, запуск линтера и форматтера, чтение diff — инструменты и первый цикл; действующие команды описаны в проверках.
  6. Первое изменение и цикл «изменить → проверить → закоммитить» — вводное задание, затем сквозные задания.

Часть II. JavaScript, TypeScript и функциональное мышление

Вход: рабочее окружение из части I. Результат: преобразуете данные и отличаете вычисление от побочного эффекта.

  1. Значения, переменные, функции, объекты, массивы и модули — JavaScript.
  2. Замыкания, ссылки, мутация и неизменяемость — JavaScript и граница эффектов.
  3. Асинхронность: Promise, async/await, ошибки и отмена — асинхронность.
  4. TypeScript: вывод типов, сужение, generics, unknown, null и граница runtime — типы и проверки.
  5. FP: чистые функции, композиция, преобразование коллекций, вычисления и эффекты — преобразования и эффекты.

Сквозной пример этих глав — группировка расписания: входные события преобразуются в дни и площадки без изменения исходного массива. Изучаем наблюдаемое поведение функции, а не требуем запрета всех локальных мутаций.

Часть III. Моделирование данных и переходов

Вход: функции и типы из части II. Результат: описываете допустимые данные, проверяете внешний вход и задаёте переходы состояния.

  1. Алгебраические типы данных: произведения, суммы, discriminated unions, исчерпывающий разбор и непредставимость недопустимых состояний — ADT и валидация.
  2. Валидация: внешний JSON как unknown, Zod, разбор и нормализация — вводная глава ADT и валидация, конкретный обработчик — API и контракты.
  3. Форма данных, бизнес-инварианты и ошибки: границы проверок; лаборатория записи и конкуренции.
  4. События, reducers, машины состояний, чистое ядро и эффекты — переходы состояния.

Материал для разбора — контракты контента. Сравните runtime-схему Blocks с TypeScript-типом BlockNode: наличие discriminatedUnion в Zod само по себе не делает объявленный тип строгой суммой.

Часть IV. React и состояние приложения

Вход: части II–III; понимание событий и переходов состояния. Результат: строите интерфейс из компонентов и выбираете место хранения состояния.

  1. Декларативный UI, JSX, компоненты, props, композиция и ключи — компоненты и композиция.
  2. События, локальное состояние, производные значения и подъём состояния — события и владельцы.
  3. Формы, ошибки ввода и доступность — формы.
  4. Эффекты, подписки, очистка и жизненный цикл — эффекты и очистка.
  5. Однонаправленный поток данных, Flux, reducer и Context — Flux и Context.
  6. Реактивность и FRP: значения во времени, события, зависимости и отмена; связь с React и различия моделей — реактивность и FRP.
  7. Сравнительная лаборатория управления состоянием: Flux, MobX, атомы и сигналы на одной задаче фильтрации расписания — сравнительная лаборатория.
  8. Разные владельцы состояния: вводная модель; URL, формы, серверный кеш и долговременное хранение — сравнение владельцев.

Лаборатория нужна для сравнения моделей, а не для подключения всех механизмов к основному сайту. MobX 7.0.6 запускается в отдельном временном каталоге; атомы и сигналы представлены учебными реализациями с явными ограничениями. Workspace-зависимости остаются прежними. Каждое решение сравниваем по потоку данных, обновлениям, эффектам, отладке и сложности. FRP не используем как общее название любой реактивности.

Часть V. Интерфейс, CSS и UIKit

Вход: компоненты, props и композиция из части IV. Результат: собираете адаптивный интерфейс и проверяете компоненты изолированно.

  1. HTML, семантика, CSS, каскад, раскладка и адаптивность — веб-платформа; материал проекта есть в главе о сайте.
  2. Mantine, тема, примитивы и составные компоненты — UIKit и API пакета.
  3. CSS Modules, слои стилей и границы темы — каскад Mantine и UIKit.
  4. Storybook: stories, Controls, Docs, состояния и примеры — UIKit и Storybook.
  5. Практика композиции и типографики — семь уроков Storybook.

Уроки доступны в разделе «Обучение» после pnpm --filter @atmanki/ui storybook. Вводный HTML/CSS читайте до первого упражнения с оформлением; основы семантики — до упражнений с формами.

Часть VI. Next.js, рендеринг, доставка и кеширование

Вход: React и различие браузера и сервера. Перед серверной загрузкой данных нужен вводный разбор HTTP из части VII; расширенный разбор API идёт после Next.js. Результат: объясняете, где и когда появляется страница, что кешируется и как изменение контента становится видимым пользователю.

Устройство страницы

  1. App Router, маршруты, layout, Server и Client Components — сайт и Next.js.
  2. Серверная загрузка контента, адаптеры и границы UIKit — архитектура и устройство сайта.
  3. CSR, SSR, SSG и ISR: место и время выполнения, HTML, гидратация, свежесть данных и ограничения — способы рендеринга; реализованный SSG/ISR разобран в статической генерации.
  4. Server Components и способ рендеринга, потоковая передача и Suspense — вводная модель, лаборатория границ ожидания.

Как работает кеш

  1. Ключ, источник истины, hit/miss, срок жизни, вытеснение и инвалидирование — ключи и уровни кеша, включая исполняемую модель с ручными часами.
  2. Что сохраняется и где: данные, результат вычисления, HTML, браузер, HTTP-прокси/CDN и сервер приложения — уровни.
  3. HTTP-кеш: Cache-Control, ETag, условные запросы, публичный и приватный кеш, stale-while-revalidate — вводная глава. Не смешиваем его с состоянием React.
  4. Кеши Next.js: мемоизация чтений, кеш данных, результата маршрута и клиентский Router Cache — модель и текущие настройки, конкретные сценарии проекта.
  5. Обновление по времени и событию: теги, пути, новые страницы, закешированный 404, потерянный webhook и ошибка CMS — SSG/ISR и webhook.
  6. Гонки, массовые одновременные промахи, устаревший ответ и данные пользователя в общем кеше — границы кеширования. Расширенная лаборатория конкурентных запросов — промахи и устаревшая запись. Общую теорию связываем с Redis из части VIII, не предполагая, что текущий сайт хранит там кеш.

Практика и границы проверки

Существующий практикум и серверные проверки дают основу для сценария: публикация в Strapi → webhook → инвалидирование → запрос → новый HTML. Итоговый сценарий дополняет его сравнением холодного и прогретого запроса, изменением записи, новым slug, закешированным 404 и отказом локальной CMS. Отдельно проверяем открытое окно браузера: инвалидирование серверного кеша само по себе не является доставкой нового интерфейса всем активным клиентам.

SSR/CSR и CDN изучаются как модели и варианты доставки, а не как обещание реализованных режимов каждой страницы или настроенного CDN. Поведение кешей сверяется с конфигурацией и кодом; фиксируем отдельно dev и production-сценарии. Руководство Next.js по кешированию без Cache Components служит источником для текущей модели; перед написанием примеров проверяем, какая модель включена в проекте.

Часть VII. HTTP, API и границы доверия

Вход: асинхронность, типы и runtime-валидация. Начальный разбор HTTP читается до серверной загрузки данных в части VI; остальные темы — после неё. Результат: проектируете контракт, выбираете способ взаимодействия, различаете ошибки и объясняете поведение при повторах и потерянном ответе. HTTP-семантика, повторы и идемпотентность и сравнение API дают вводную модель. Глава API разбирает tRPC и webhook проекта. Сравнительная лаборатория, OpenAPI и браузерные границы дополняют концепции практикой.

Семантика HTTP

Вводная глава покрывает сообщения, методы, статусы и If-Match.

  1. Ресурс и представление, URL, запрос/ответ, заголовки, тело, Content-Type и согласование представления. HTTP-семантика и версии транспорта — разные темы.
  2. GET, HEAD, POST, PUT, PATCH и DELETE: намерение операции, безопасные и идемпотентные методы. Идемпотентность относится к предполагаемому эффекту, а не к обязательному совпадению ответов; безопасность не означает отсутствие логирования.
  3. Коды ответа: успешное выполнение, создание, принятие в обработку, отсутствие тела, неверный вход, отсутствие прав, конфликт, лимит и отказ зависимости. Отличаем HTTP-статус от ошибки внутри протокольного ответа.
  4. ETag, If-Match и условное обновление: защита от потерянных изменений. Кешируемость, безопасность и идемпотентность рассматриваются отдельно; HTTP-кеш подробно разбирается в части VI.
  5. Аутентификация и авторизация, cookies и Bearer token, CORS и CSRF, серверные секреты и ограничения запроса. Подробную главу о браузерных границах доступа — origin, cookies, CORS и CSRF; текущий webhook разобран в API.

REST и описание контракта

Сравнение API вводит REST и роль OpenAPI; исполняемый контракт с пагинацией и проверкой совместимости — OpenAPI и keyset.

  1. REST как архитектурный стиль: ресурсы, представления, stateless-взаимодействие, единообразный интерфейс и гипермедиа. Не называем любой JSON endpoint полноценным REST.
  2. Практический HTTP API: адреса, фильтрация, сортировка, пагинация, ошибки и совместимость. Контракт для чтения и изменения учебной публикации.
  3. OpenAPI: описание операций и данных, документация, генерация клиента и контрактные проверки. Генерация типов не заменяет runtime-валидацию.

GraphQL, tRPC и gRPC/Protobuf

Вводное сравнение содержит иллюстративные GraphQL/Protobuf-схемы. Лаборатория четырёх API проверяет один сервис через разные adapters.

  1. GraphQL: схема, query, mutation, subscription, resolvers, выбранные поля, частичные данные и ошибки. Стоимость запроса, N+1 и права доступа; GraphQL не является интерфейсом для произвольного доступа к базе.
  2. tRPC: общий TypeScript-контракт, Zod, router, context, caller и HTTP-клиент — реализованный пример. Где удобно совместное развитие клиента и сервера, а где важны независимые языки, версии и публичный контракт.
  3. gRPC: определения сервисов, unary и streaming-вызовы, metadata, статусы, deadlines и отмена. Доступ из браузера и необходимые адаптеры изучаем отдельно.
  4. Protobuf: схема сообщений, сериализация, генерация кода, номера полей, присутствие значения и эволюция контракта. Protobuf не тождественен gRPC; совместимость формата не гарантирует совместимость бизнес-смысла.
  5. Сравнение одной задачи по потребителям, контракту, транспортным ограничениям, кешированию, отладке и стоимости сопровождения. REST — стиль, GraphQL — язык запросов и модель выполнения, tRPC — инструмент типизированного RPC, gRPC — RPC-фреймворк, Protobuf — описание и формат сообщений.

Повторы, идемпотентность и побочные эффекты

Вводная глава задаёт закон перехода и границы дедупликации. Транзакционная лаборатория содержит журнал результатов, rollback, повтор после потерянного ответа и протокол опыта с двумя сессиями.

  1. Ошибка до эффекта, после эффекта и потерянный ответ: timeout не доказывает, что операция не выполнена. Отмена ожидания не является откатом удалённой операции.
  2. Повтор запроса: условия retry, backoff, jitter, deadline и ограничение попыток. POST/PATCH не считаются идемпотентными только из-за повторяемого payload; прикладной контракт может отдельно обеспечить безопасный повтор операции.
  3. Ключ идемпотентности: область действия, совпадение ключа и разных данных, конкурентные запросы, хранение результата, срок хранения и повтор после рестарта.
  4. Атомарность эффекта и фиксации обработки внутри своей БД; внешняя операция за пределами транзакции. Дедупликация и retry сами по себе не гарантируют exactly-once.
  5. Webhook: проверка входа и доступа, дубли, порядок, повторная доставка, наблюдаемость и восстановление — текущий обработчик. Повтор инвалидирования кеша не используем как доказательство безопасности любой операции записи или внешнего эффекта.
  6. Эволюция API: добавление и удаление полей, необязательность, версии, старый клиент с новым сервером и обратное сочетание.

Сравнительная практика

Сравнительная лаборатория проверяет получение учебной публикации по ID и изменение. OpenAPI и пагинация дополняют этот контракт чтением списка. Сравниваем варианты API на одинаковом контракте поведения, не смешивая протокол с бизнес-логикой. Моделируем неверный вход, отсутствие записи, запрет доступа, конфликт версии, повтор и потерянный ответ. Практику идемпотентности выполняем после транзакций из части VIII.

В основном проекте уже используются REST Strapi, tRPC и webhook. GraphQL, gRPC, Protobuf и OpenAPI изучаются в отдельных лабораториях и не внедрены в production. Версии временных лабораторий указаны в главах; основной API не переписывается ради сравнения. Итоговый практикум связывает контракт, повтор операции и наблюдаемые результаты.

Источники для подготовки: HTTP Semantics, RFC 9110, REST у Филдинга, GraphQL, tRPC, gRPC, Protobuf.

Часть VIII. Модели данных и системы хранения

Вход: типы, валидация, серверный код и HTTP; для агрегаций — FP из части II. Результат: выбираете модель по запросам и инвариантам, объясняете её цену и отличаете операционные данные от аналитики. Вводные главы: модели хранения, PostgreSQL/JSONB, Redis и доступ к данным/смена СУБД. Это учебный материал, а не новый слой данных сайта. Лаборатории данных, аналитики и ANN, распределённого SQL содержат команды, наблюдения и критерии приёмки дополнительных систем. Основы реляционной модели нужны перед частью IX; распределённые системы, аналитика и векторный поиск — углублённый маршрут, который можно изучить позже.

Реляционная модель, SQL и доступ к данным

Основы ключей, ограничений и конкурентного UPDATE разобраны в PostgreSQL; сравнение доступа вводит ORM и план миграции. Упражнения по JOIN, нормализации, пулу и TypeORM находятся в лабораториях данных.

  1. Таблицы, ключи, связи, ограничения и нормализация.
  2. Параметризованные запросы, JOIN, индексы, EXPLAIN, транзакции и конкурентные изменения. Прямой SQL — полноценный инструмент, а не признак устаревшего приложения.
  3. PostgreSQL и MySQL/MariaDB: переносимые идеи и различия типов, SQL-диалектов, генерации идентификаторов, дат, сортировок и обработки NULL.
  4. Драйвер, query builder и ORM на одной задаче. TypeORM в отдельной лаборатории: entities, связи, repositories, Active Record и Data Mapper, миграции схемы.
  5. Цена абстракций: сгенерированный SQL, N+1, границы транзакций и пул соединений. Типы ORM не заменяют проверку внешнего входа и ограничения базы.

Документы, NoSQL и JSONB

Модели хранения разделяют семейства; JSONB и Redis дают вводные примеры. Практикум SQL/JSONB/Redis задаёт проверки ограничений, TTL и отказа кеша.

  1. Документная модель, ключ–значение, графы и wide-column: виды запросов, индексы, связи, ограничения и гарантии конкретных систем.
  2. JSON и JSONB в PostgreSQL: колонки, документ или сочетание обоих; операторы, индексы, проверка структуры и стоимость обновления. Учебный пример — гибкое содержимое публикации в отдельной схеме, без обещания, что Strapi хранит свои Blocks именно таким способом.
  3. Redis: ключи и структуры данных, кеш, TTL, инвалидирование, поведение при промахе и недоступности. Его вводят для конкретной задачи, а не как обязательный следующий шаг после MySQL или PostgreSQL.

Аналитика и обработка данных

OLTP/OLAP и столбцовое хранение дают вводную модель; MapReduce — исполняемую локальную агрегацию. Лаборатория аналитики сравнивает SQL/JS/MapReduce и вводит event-time окна. Кластер Hadoop/Spark/Flink не нужен для локальной модели; его гарантии нельзя считать проверенными этим опытом.

  1. OLTP и OLAP: изменить одну запись или агрегировать большой набор событий. Строчное и столбцовое хранение, сжатие и чтение нужных колонок. Различаем столбцовое хранение для аналитики и семейство wide-column.
  2. Агрегации в JavaScript и SQL GROUP BY на одинаковых учебных событиях. Преобразование, группировка и свёртка; требования к объединению частичных итогов.
  3. Распределённый MapReduce: map → shuffle и группировка по ключу → reduce. Партиционирование, передача данных, перекос ключей, повторы задач, ассоциативность агрегации и воспроизводимость результата. Метод массива reduce сам по себе не является распределённым MapReduce.
  4. Локальная модель MapReduce и сравнение результата с SQL GROUP BY. Отдельно показываем ограничения модели: она не проверяет поведение кластера.
  5. Пакетная и потоковая обработка: конечный набор и непрерывные события, окна, время события и поздние данные. Hadoop — исторический контекст, Spark — тема для дальнейшего знакомства; кластер для вводной практики не нужен.

Векторный поиск и распределённые SQL-системы

NewSQL введён в моделях хранения. Векторный поиск вводит геометрию и точный baseline. Лаборатория ANN сравнивает exact baseline с HNSW; распределённый SQL разбирает quorum, isolation и отказ.

  1. Embeddings, метрики сходства, точный и приближённый поиск ближайших соседей, фильтрация и оценка качества. Семантическое сходство не равно достоверности ответа.
  2. Векторное расширение реляционной базы и специализированная векторная БД: сравнение задач, индексов, обновлений и эксплуатации.
  3. NewSQL и распределённый SQL: шардирование, репликация, транзакции, согласованность, задержки и поведение при отказе узла. Разбираем термин и гарантии конкретной системы вместо общего обещания «масштабируется».

Выбор хранилища и лаборатории

SQL — язык, NoSQL — широкая группа подходов, JSONB — тип данных, столбцовое хранение — организация данных, векторный поиск — способ поиска, а NewSQL — термин для семейства систем. Это разные оси сравнения, а не последовательность замены старой технологии новой.

Для лабораторий используем одинаковые небольшие данные: события и публикации. Сначала формулируем запросы, инварианты, объём и требования к эксплуатации, затем обосновываем выбор. Основная интеграция проекта остаётся через API Strapi: лаборатория использует собственную схему и не пишет во внутренние таблицы CMS. Дополнительные БД, расширения, TypeORM и Redis не подключаются в production-путь. Временные лаборатории используют указанные версии и отдельные учебные schemas/instances. Границы выполненных проверок фиксируются отдельно от готовности инструкции.

Источники для подготовки: JSON/JSONB в PostgreSQL 17, TypeORM, Redis, столбцовая аналитика ClickHouse, исходная работа о MapReduce, pgvector, архитектура распределённой SQL-базы.

Часть IX. Strapi, контент и медиа

Вход: HTTP, схемы и контракты из предыдущих частей. Результат: управляете контентом и проверяете его путь от CMS до страницы.

  1. Модели, связи, REST, Blocks и draft/publish — CMS и контент.
  2. Вход в панель, настройки и русский интерфейс — панели.
  3. Импорт: снимок, dry-run, конфликты, сохранение редакторских изменений — импорт.
  4. Объектное хранилище и S3 и жизненный цикл медиа: модель, доступ, пути и границы отказов. Интеграция проекта описана в главе о контенте и инструкции Garage.
  5. Папки, подписи и безопасная реорганизация — медиабиблиотека.
  6. Публикация → webhook → обновление сайта — редакторский сценарий.
  7. Когда нужна задача по расписанию — cron Strapi.

Cron сейчас не включён: глава объясняет границы и выбор механизма при появлении конкретной задачи. Детали самостоятельного Strapi-проекта — его README.

Объектное хранилище и S3

Вход: HTTP, устройство CMS и различие между данными записи и содержимым файла. Результат: объясняете выбор хранилища и путь фотографии от загрузки до браузера. Вводная глава объясняет модель и путь чтения, жизненный цикл — связь байтов, записи и публикации. Практикум S3 содержит загрузку, multipart, presigned GET и abort в отдельном приватном bucket. Живое хранилище не проверяется сборкой учебника.

  1. Задача хранения файлов: файловая система, Docker volume, база данных и объектное хранилище. Когда отдельное хранилище полезно, а когда достаточно локальных файлов; что меняется при пересоздании контейнера.
  2. Amazon S3 как сервис и S3-совместимый API как интерфейс. Garage как реализация в нашем проекте; совместимость API и её границы.
  3. Модель объекта: bucket, key, содержимое и metadata. Префикс ключа, «папка» медиабиблиотеки CMS и каталог файловой системы — разные понятия.
  4. Операции загрузки, чтения, перечисления и удаления; endpoint, region, path-style и multipart upload. Сначала обычная загрузка, затем её усложнения.
  5. Доступ: серверные credentials, права на bucket, публичные и приватные объекты, подписанные URL. Последние изучаем как механизм, а не как реализованную функцию нашего сайта; совместимость проверяется отдельно.
  6. Доставка в браузер: S3 API и публичный HTTP-адрес, reverse proxy, Content-Type, кеширование и CORS. Почему ключ объекта и публичный URL могут различаться.
  7. Интеграция со Strapi: upload provider, файл в Garage, запись и связь в CMS, публикация контента и независимая от неё доступность файла.
  8. Сохранность: удаление, потерянный ответ и повтор загрузки, резервная копия и восстановление. Отдельно разбираем версионирование и репликацию как возможности хранилищ, не предполагая их наличия в текущем Garage.

Локальный практикум задаёт сценарий: загрузить тестовую фотографию через Strapi, найти запись CMS и ключ объекта, проследить публичный запрос, затем удалить собственный тестовый файл и проверить результат. Исполнение практикума в этом этапе не подтверждено. Используем только учебные данные; отдельно объясняем, почему черновик записи не делает файл приватным и почему хранилище на том же VPS не является резервной копией.

Часть X. Инструменты разработки, качество и диагностика

Вход: опыт выполнения небольших изменений в предыдущих частях. Начальная настройка редактора и запуск проверок вводятся уже в части I. Результат: понимаете роль каждого инструмента, выбираете проверку по риску изменения и воспроизводите её вне редактора и в CI. От исходника до запуска вводит инструменты и модули; лаборатория разделяет типы, lint, format, runtime и поведение. Существующая глава описывает команды и покрытие проекта. Отладчик и профилировщик дополняют вводную главу.

От исходника до работающей программы

  1. Редактор и language server: поиск символов, переход к определению, подсказки, диагностика и безопасный рефакторинг. Версия TypeScript workspace и версия редактора; результат CLI-проверки как воспроизводимая точка сравнения.
  2. Парсинг, AST, статический анализ, преобразование кода и выполнение. Различаем проверку типов, удаление типовых аннотаций и сборку приложения.
  3. ESM, разрешение модулей, aliases, workspace-пакеты, lockfile и границы зависимостей. Сопоставляем dev-режим, тестовый запуск и production-артефакт.
  4. Dev-сервер, обновление модулей, sourcemaps и отладчик: breakpoints, stack trace, локальные значения. Инструменты браузера: Network, DOM, вычисленные CSS, console, storage и профилирование.
  5. Storybook для отдельного компонента и dev-сайт для интеграции; возможности и границы изолированной проверки — UIKit.

Что проверяют инструменты

ИнструментНа какой вопрос отвечаетЧто остаётся за границей
TypeScript typecheckСогласован ли код с правилами типов и конфигурацией проекта?Реальные HTTP-данные, бизнес-инварианты и поведение при выполнении
OxlintНарушены ли включённые правила статического анализа?Полная корректность программы и все возможные дефекты
OxfmtСоответствует ли запись кода принятому форматированию?Смысл программы и архитектурные решения
СборкаПолучается ли артефакт заданного приложения?Полнота проверок поведения и работа на конкретном VPS
ZodСоответствует ли конкретное значение runtime-схеме?Правила предметной области, не выраженные этой схемой
Jest и Node test runnerПроходят ли заданные сценарии и утверждения?Непроверенные сценарии и реальная интеграция, заменённая фикстурой
Ручная проверка UI и интеграцииРаботает ли наблюдаемый сценарий в выбранной среде?Все устройства, все входы и повторяемость без фиксации условий

Качество — сочетание независимых свидетельств. Нет правила «тесты прошли, значит типы, доступность и публикация тоже проверены».

Конфигурация и ежедневный цикл

  1. TypeScript: strict, границы проекта, разрешение импортов, generated types, noEmit, декларации и отдельная конфигурация Strapi — проверки.
  2. Линтер: включённые правила, область файлов, warnings/errors, исключения и autofix. Учимся объяснять диагностику до исправления или подавления.
  3. Форматтер: единая конфигурация, проверка и запись, интеграция с редактором. После autofix и форматирования читаем diff; подавления ошибок не становятся способом сделать индикатор зелёным.
  4. Маленькое изменение → целевые проверки → чтение diff → отдельный коммит. Быстрый feedback в watch-режиме; общий набор и сборка релиза — по задаче и в CI.
  5. Локальные scripts и GitHub Actions: одинаковый ref, версии, lockfile, переменные и рабочий каталог. Отличаем воспроизводимую проверку от успеха только в одном настроенном редакторе.

Команды и конфигурация имеют один источник: root package.json, Oxlint, Oxfmt, TypeScript и глава проверок. Основные инструменты проекта — Oxlint, Oxfmt, TypeScript, Jest через next/jest и Node test runner для импорта Strapi; учебная программа не меняет этот набор.

Проверка поведения и расследование

  1. Контрактные тесты, фикстуры, отказ зависимости и интеграционные сценарии — покрытие.
  2. Ручная проверка интерфейса, доступности и адаптивности — сайт и проверки.
  3. Симптом → гипотеза → проверка → исправление — лаборатория диагностики и разбор проблем.
  4. Профилирование: измеряем время, запросы, память и размер ресурсов; отличаем измеренный bottleneck от предположения — отладчик и профилировщик.

Подготовленная лаборатория содержит раздельные примеры ошибки типа, нарушения явно выбранного lint-правила, расхождения форматирования, неверного runtime-входа и дефекта поведения. Сначала предсказываем результат, затем подтверждаем его. Ошибочная сумма проходит typecheck, но нарушает контракт; исправление проверяется тестом. Это временные файлы, не изменение стека проекта.

Часть XI. DevOps и эксплуатация

Вход: устройство приложения, API и CMS; подход к проверкам из части X. Результат: понимаете состав релиза, умеете диагностировать запуск и проверять восстановление.

  1. Linux, процессы, права и SSH — основы и локальные упражнения.
  2. Docker: образы, контейнеры, Compose, сеть, тома и readiness — жизненный цикл сервиса и инфраструктура.
  3. PostgreSQL, хранение данных и жизненный цикл базы — жизненный цикл, миграции схемы и инфраструктура.
  4. Caddy, DNS, HTTPS и reverse proxy — DNS/TLS, прокси и HTTP/2–HTTP/3, инфраструктура.
  5. Конфигурация и секреты — настройки. Конфигурация своего экземпляра вводит единую identity и вычисление адресов; подключение к delivery — следующий этап.
  6. CI/CD: GitHub Actions, GHCR, digest и релизы — основы, лаборатория чтения релиза и деплой.
  7. Логи, метрики и трассировки — наблюдаемость; резервные копии, восстановление и откат — эксплуатация.
  8. Ограничения одного VPS и границы гарантий — ограничения.

Production-образы собираются в GitHub CI; VPS получает готовый релиз. Учебные сбои и восстановление выполняются в изолированной локальной среде.

Дополнительный маршрут: от PHP и MySQL/MariaDB

Для читателя с опытом PHP этот маршрут связывает знакомые задачи с материалом учебника. Он не предполагает, что PHP, прямой SQL или MySQL/MariaDB обязательно нужно заменить. Глава перехода содержит сравнение функций, карту типов, сверку и cutover; существующий импорт сайта в Strapi не является примером переноса PHP-кода или MySQL-базы.

  1. Сравнить обработку запроса в исходном PHP-приложении с серверным JavaScript: жизненный цикл процесса, async/await, ошибки, соединения и состояние между запросами.
  2. Разделить изменения: язык приложения, база данных и способ доступа к ней. Смена PHP на TypeScript не требует одновременной смены СУБД или внедрения ORM.
  3. Перенести одну функцию: PHP и параметризованный SQL → TypeScript и SQL → query builder/ORM. Сравнить поведение и реальные запросы; TypeORM — инструмент отдельной лаборатории, а не зависимость production-проекта.
  4. Подготовить миграцию в PostgreSQL: карта типов и связей, преобразование данных, пробный перенос, сверка количества записей и содержимого, новая запись во время переноса, переключение и границы отката. Отдельно отличить миграции схемы от переноса данных между СУБД.
  5. Добавить кеш Redis только к измеренной задаче: источник истины, ключи, срок жизни, инвалидирование и работа приложения без кеша.
  6. Выполнить постепенный переход на изолированных учебных данных, проверить контракт старого и нового пути и записать результаты. Автоматической миграции реального приложения эта глава не обещает.

Сквозной практикум

Сквозные задания связывают упражнения отдельных глав в итоговые сценарии с наблюдаемым результатом:

  • Преобразовать события CMS в проверенные данные и адаптивное расписание.
  • Сравнить модели состояния на одном фильтре, объяснить выбранное решение.
  • Проследить draft → publish → webhook → обновлённую страницу без rebuild.
  • Сравнить способы API на одном контракте и проверить повтор операции после потерянного ответа.
  • Сравнить агрегирование учебных событий в JavaScript, SQL и локальной модели MapReduce.
  • Обосновать выбор колонок или JSONB и сравнить точный и приближённый векторный поиск.
  • Проверить свежесть страницы после публикации и объяснить поведение каждого кеша.
  • Проверить отказ зависимости, выпустить релиз и восстановить учебную копию.

Для каждого сценария практикум указывает материалы, порядок действий и приёмку. Выполнение читателем не добавляет функцию в production автоматически.

Справочник и устройство учебника

История проекта

Эти документы фиксируют решения и проверки на конкретную дату. Они не заменяют текущие инструкции и не являются подтверждением нынешнего состояния VPS.