# HTML и выпуск SEO-версии По умолчанию Go отдаёт HTML существующих React-компонентов, отрендеренный локальным Node.js из текущих публичных данных PostgreSQL. Главная, услуги, врачи и специализации, цены и категории, контакты, чек-апы, акции и правовые документы доступны до JavaScript. Гидратация включает прежние формы и навигацию. CSS, изображения и макеты не заменены. ## Обновление данных На каждый запрос Go читает необходимые опубликованные данные. Отпечаток включает содержимое, публичные настройки, базовый HTML и версии серверных файлов. Если данные совпадают, используется кеш HTML; после админской правки следующая выдача рендерится заново. Повторная сборка после изменений контента, цен, врачей, отзывов, SEO-полей или филиалов не нужна. Процесс Node не обращается к БД или API: получает публичные данные через stdin. Кеш ограничен 64 страницами / 16 МБ. Одновременно работают максимум два рендера с таймаутом 10 секунд. Query-варианты не сохраняются в кеш, получают noindex и canonical без query. Ошибочный рендер возвращает 503 с noindex, не устаревшую 200. Снятые с публикации данные проверяются до кеша. Изменения React/SEO JSON/CSS требуют новой сборки; Go-кода — новой сборки Go и перезапуска. ## Локальная сборка Нужны PostgreSQL, Go версии не ниже указанной в go.mod, Node.js и зависимости web. Сначала запустить API с DATABASE_URL и MEDIA_DIR. Без web/dist допустим API-only режим. Затем: ```powershell cd D:\dana\web $env:DANA_API = 'http://127.0.0.1:8080' $env:SITE_URL = 'http://127.0.0.1:8080' npm ci npm run build npm run test:seo # Go: WEB_DIR=./web/dist, SSR_RENDERER=./web/scripts/render-page.mjs, # NODE_BINARY=node, SITE_URL совпадает с origin сборки. # После запуска новой версии Go: $env:VERIFY_URL = 'http://127.0.0.1:8080' npm run test:seo:live ``` На сервере сохранить web/dist, web/.ssr, web/scripts/render-page.mjs, web/scripts/seo-document.mjs, web/package.json и production-зависимости web/node_modules. linkedom — runtime-зависимость. npm run build создаёт также резервные снимки 65 текущих услуг. SSR_RENDERER=off явно включает старый статический режим: тогда после контентных правок нужны новые снимки, а остальные страницы остаются SPA. Основной режим — live SSR. ## Боевой выпуск Подтвердить домен, HTTPS, филиалы, операции, лицензию и медицинские тексты. Передавать SITE_URL одинаковый при сборке и запуске. Для локального SITE_URL robots.txt закрывает весь сайт; это защита, не настройки боевого домена. На production robots исключает API и админку; query разрешён для обхода, чтобы робот увидел noindex. Sitemap строится из опубликованных услуг, врачей, специализаций с врачами, чек-апов, непустых категорий цен и правовых документов. Заглушки, дубль-адреса акций и неизвестные URL исключены. Reverse proxy должен направлять страницы, /api/, /admin/, /media/, /assets/, /robots.txt и /sitemap.xml в Go. Не применять SPA fallback вместо HTML. Собрать и проверить релиз в отдельном каталоге, затем переключить процесс целиком; не пересобирать live web/dist под работающим процессом. Dockerfile теперь собирает клиент и SSR без работающей БД, содержит Node runtime и согласован с go.mod. docker compose config можно проверить без запуска. Сам Docker-образ и контейнерный выпуск здесь не проверены: Docker daemon недоступен. Новая БД контейнера пустая до импорта данных; существующая локальная БД не затрагивается. Боевой деплой, подтверждение лицензии, медицинская редактура и отправка sitemap в панели поисковиков не выполнялись. Существующие реквизиты документов показаны как данные проекта, не как результат юридической проверки. ## Перелинковка и контроль контента ServiceDoctors получает реальные специализации для связанных врачей: URL карточек и Physician совпадают с основным адресом каталога. Специалисты, показанные по направлению без прямой связи с услугой, обозначены как специалисты направления, не как оперирующие хирурги или авторы. Связи услуг и категорий прайса находятся в web/src/lib/serviceNavigation.js. Это общие редакторские связи направлений, не соответствие конкретной операции цене. На услуге видна ссылка в существующий опубликованный прайс направления; на прайсе — обратно в услуги направления. Снятый с публикации/пустой раздел не получает ссылку. Legacy URL не переименованы. Внутренние ссылки на перенаправленные документы выводятся сразу с canonical URL. Неперенесённые пункты подвала остались на своих местах с прежними классами оформления, но стали неактивным текстом с пояснением. Их старые URL по-прежнему возвращают 404. pages/about не публикуется как пустая посадочная: в исходной записи нет содержательного текста. ```powershell cd D:\dana\web npm run audit:content # Фактический обход сайта, внутренних ссылок/якорей и локальных ресурсов: $env:STRICT_AUDIT = '1' npm run audit:seo ``` Результаты: seo/crawl-audit.json, seo/content-audit.json и seo/content-gaps.md. Контентный аудит ищет упоминания тем, не подтверждает медицинскую корректность. Одноимённые позиции с разными суммами отмечены для проверки и не сопоставляются автоматически с посадочными. Существующий прайс не переписан. CSS и графические файлы при этом этапе не менялись; приоритет загрузки первого изображения главной/hero услуги задан в HTML.