Передача Angular-кабинета и подключение Nest
К концу серии кабинет имеет список, адрес отдельной заявки, URL-фильтры, форму и контролируемое сохранение. Последний шаг превращает набор механизмов в понятную передачу проекта. Другому человеку нужны не только файлы, но и версия инструментов, выбранный источник данных, ожидаемые сценарии и честная граница проверки. Результат главы — договор самостоятельного воспроизведения Angular и переключения на соседний Nest без изменения предметной модели и адресов API.
Архив содержит одну конечную версию. Внутри нет шестнадцати наборов копий проекта, которые нужно последовательно накладывать друг на друга. Ранние уроки показывали явно названные упрощённые состояния App; поздние разбирали фрагменты окончательных файлов. Поэтому для изучения итогового кабинета распакуйте архив и читайте README, а для исследования первого шага заменяйте именно указанный файл целиком. Смешивание половины раннего App с половиной конечной оболочки не является предусмотренным способом сборки.
Карта ответственности
Main.ts запускает App, app.config.ts предоставляет Router и HttpClient, app.routes.ts получает страницы лениво. Model.ts описывает Ticket, исходные fixtures и чтение unknown. ListPage владеет операцией списка, DetailPage — основой и черновиком одной заявки. Session сохраняет выбранную учебную роль в root-области. TicketsApi отвечает за транспортную форму, а fixtureInterceptor моделирует источник в памяти. Такая карта помогает локализовать изменение: новый параметр фильтра затронет модель URL и API, а новое оформление карточки — компонент строки.
Ниже полный config.ts конечного клиента. Mode fixture выбран по умолчанию, чтобы Angular изучался независимо. ApiBase остаётся /api в обоих режимах. Demo tokens открыто заданы для учебного подключения; соответствующие значения Nest находятся в .env.example. Это не secret management. При замене их читатель должен согласовать обе стороны, иначе видимая роль диспетчера не убедит сервер разрешить PATCH. Такая ошибка ожидаемо проявится как 401, а не как проблема длины title.
export const config = {mode: 'fixture' as 'fixture' | 'remote', apiBase: '/api'};
// Учебные публичные токены. В реальном приложении нужны серверная сессия/IdP.
export const demoTokens = {viewer: 'lab-viewer-token', dispatcher: 'lab-dispatcher-token'};
В fixture-режиме запросы проходят через HttpClient, но не уходят к PostgreSQL. Перезагрузка восстанавливает исходные три заявки, а отдельные вкладки имеют разные базы. Наличие успешного PATCH fixture не доказывает server transaction, общую конкуренцию или сохранение на диске. Оно позволяет изучить форму и сообщения, соблюдая wire-контракт. В remote-режиме те же методы проходят локальный dev proxy и обращаются к Nest на 127.0.0.1:3000. Источник меняется явно, без молчаливого fallback на fixtures при ошибке сервера.
Версии и действия читателя
Пакеты Angular, CLI и build фиксированы на 22.0.0, TypeScript — 6.0.3, RxJS — 7.8.2, tslib — 2.8.1. Node 22.22.3+ внутри ветки 22 выбран по таблице Angular 22 и одновременно подходит профилю Nest. Все точные зависимости находятся в package.json. Lockfile отсутствует, потому что установка не выполнялась. Поэтому перед реальной передачей команды должны проверить разрешение npm-дерева и сохранить lockfile после осознанной установки. Документация и manifest не являются заменой такого runtime-шага.
Читатель может выполнить npm install, затем npm start и открыть /tickets на 4200. Эти действия записаны в README и не выполнялись автором. Для remote сначала нужно подготовить отдельную локальную PostgreSQL 18, применить schema/seed из Nest и запустить сервер согласно его README. Затем mode меняется на remote и клиент перезапускается. CORS в лаборатории не включается: браузер видит Angular-origin, а dev-server проксирует API. Production reverse proxy и публикация требуют самостоятельной конфигурации.
Ожидаемый базовый сценарий: список содержит rq-101…103, q «проектор» оставляет rq-101, выбор dispatcher позволяет изменить title/status, успешный PATCH увеличивает version. Повтор старой основы даёт 409. Смена route id во время ожидания не должна показать ответ прежней заявки в новой форме. Каждый ожидаемый эффект привязан к конкретному механизму и может быть отдельно проверен после подготовки окружения. В этой сессии приложение, HTTP и compiler не запускались, поэтому слова «получено» и «проверено выполнением» к этим эффектам не применяются.
Что потребуется развивать
Список показывает максимум 200 строк, а total может быть больше. UI сообщает найденное и показанное, но следующей страницы нет. Для большого набора потребуется пагинация с согласованными order/cursor или offset, query DTO и URL. Нельзя добавить только кнопку «Ещё», не определив, как новые строки относятся к изменению фильтра и текущему request. Педагогическая модель уже помогает: адрес выбирает условия, ListPage владеет актуальностью чтения, wire-ответ должен сообщить всё необходимое для продолжения.
Конфликт версии не решается автоматическим merge. Черновик остаётся после 409, а reload заменяет его по явному действию. Потеря ответа PATCH также неоднозначна: сервер мог завершить запись. Производственная версия потребует политики восстановления и, возможно, idempotency keys. Следует определить, какие действия безопасно повторять и какие требуют чтения актуального состояния. Мы не добавляем случайный retry на любую мутацию, потому что это скрыло бы предметный результат под удобством транспорта.
Авторизация ограничена публичными demo tokens одного списка. Нет аккаунтов, tenants, отзыва сессии, TLS и проверки права на конкретную заявку. UI canEdit помогает объяснить действие; Nest guards проверяют демо-договор. Для настоящего продукта нужен самостоятельный проект модели доступа. Доступность также имеет непроверенные части: переход фокуса при Router-навигации, чтение live regions screen читатель и поведение формы на малом экране. Наличие labels и focus-visible полезно, но не доказывает полную UX-приёмку.
Если продолжать клиент самостоятельно, выберите один следующий результат: канонический URL для неизвестных параметров, явное предупреждение о потере dirty-черновика или проверенный фокус после перехода. Такой шаг легче оценить, чем одновременное добавление всех недостающих production-механизмов. Общий архив уже содержит читаемые границы файлов и общий контракт, поэтому любое новое изменение можно связать с одной причиной и наблюдаемым эффектом. Нынешняя серия завершена именно как локальная учебная основа, готовая к самостоятельному воспроизведению.
Статус примера — not_run. Зависимости, приложение, SQL, HTTP и тесты не запускались. Описанные ответы и изменения интерфейса ожидаемые; чтение документации не является проверкой выполнением. Полная конечная версия находится в архиве исходников, а её ограничения и действия читателя — в README и CONTRACT.md.
Перейдите к оглавлению серии или общему маршруту интерактивной веб-разработки. Механизм этой главы сверяется с официальным первичным источником; конкретные версии и непроверенные части перечислены в договоре курса.