8.3 KiB
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 режим. Затем:
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 не публикуется как пустая посадочная: в исходной записи нет содержательного текста.
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.