Skip to content

lstmind/stroy

Repository files navigation

Ведомость — демо-каталог отделочных материалов

Каталог на 320 позиций: фасетный поиск по русской морфологии целиком в браузере и расчёт раскладки плитки по нормам СП. Статика — на сервере не появляется ни одного процесса.

→ Открыть: stroy.lstmind.ru

Ведомость — отделка, посчитанная до подрезки

Демонстрационная работа для портфолио, а не действующий магазин: компания, ассортимент и цены вымышлены. Что здесь настоящее и что придумано — на странице «О проекте» и в ATTRIBUTION.md.

Автор — Алексей, веб-разработчик · lstmind.ru

Что здесь интересного

Поиск понимает, как люди пишут. Падежи, опечатки, латиница, забытая раскладка, профессиональные аббревиатуры: «ломинат», «kfvbyfn», «гкл влагостойкий», «кг 600», «эппс». Индекс MiniSearch сериализуется на сборке и весит 11,9 КБ brotli; стеммер — русский Snowball из @orama/stemmers.

Поверх стеммера — доменный словарь на 156 строк, и он там не для красоты. Snowball схлопывает падежи, но не схлопывает существительное и относительное прилагательное: «плитка» → плитк, а «плиточный» → плиточн. Расстояние три, fuzzy не спасает и не должен. Лемматизатор решил бы задачу и потянул словарь на мегабайты — в браузер такое не грузят.

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

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

Каталог фильтруется и с отключённым JavaScript: каждый фасет — ссылка на статически собранную страницу одного фильтра.

Расчёт считает раскладку, а не площадь. Симметрирует ряды, держит правило «подрезка не уже половины плитки», учитывает шов между полем и подрезкой, знает про выход двух кусков из одной плитки только с противоположных краёв одной оси — и про то, что направленный рисунок это правило отменяет. Клей по высоте гребёнки, обратное намазывание отдельным слагаемым, а не множителем. Затирка по формуле, оба контрольных примера зафиксированы тестами до третьего знака. Округление до упаковок происходит один раз и в конце. Переплата показывается всегда.

Схема рисуется одним SVG-паттерном для поля целых плиток и индивидуально только для подрезок. Иначе ванная, выложенная мозаикой, — это десять тысяч узлов, и бюджетный Android умирает на первом перетаскивании.

Стек

Astro 7 в режиме чистой статики, острова на Svelte 5 (руны), Tailwind v4 для утилит, TypeScript, Vitest. React отсутствует полностью — это второе демо в портфолио, и оно доказывает гибкость после первого на Next.js.

Данные — YAML в репозитории. Сборка валидирует ссылки и реестр характеристик, детерминированно генерирует артикулы, считает упаковку и вес из размеров и плотности. Ни одна упаковка не вбита руками.

Команды

npm install
npm run dev          # сборка данных + astro dev
npm run build        # dist/, 609 страниц
npm test             # 79 тестов: расчёт, развёртка стен, поиск, фасеты
npm run precompress  # .br и .gz сайдкары — без них brotli-цифры вымышлены
npm run budget       # замер бюджетов, а не «на глаз»
npm run deploy       # rsync → симлинк → health-check → откат при сбое

Ассеты тянутся отдельными командами и коммитятся, поэтому обычная сборка не ходит в сеть:

npm run fonts       # woff2-подмножества по алфавитам + реестр
npm run textures    # 89 фактур CC0, кроп по физическому размеру плиты
npm run photos      # 21 фотография: первый кадр, кадры страниц, предметная съёмка
npm run forms       # 5 чертежей упаковки — запас, если кадра нет
npm run social      # og.jpg 1200×630 и apple-touch-icon

Изображения устроены в три слоя, и это не эстетика, а разные обещания.

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

Предметная съёмка — то, у чего фактуры нет: гребёнка клея, торец штабеля листов, россыпь саморезов. Кадры раздаются коллекциям по кругу и по существу: у кадра в реестре стоит match, и каменная вата не может показаться пенополистиролом. Ни одного логотипа и ни одной брендированной упаковки — кадры с читаемой этикеткой отбракованы.

Чертежи упаковки — запас на случай, когда пригодного кадра нет: линия, штриховка, миллиметровая сетка в языке схемы раскладки.

Замеры

search.json 11,9 КБ brotli (бюджет 14)
catalog.json 9,3 КБ brotli (бюджет поднят с 9 до 10, см. ниже)
JS островов 58,1 КБ gzip (бюджет 60)
Страниц в сборке 609
Процессов Node на сервере 0

Два честных отклонения от плана:

  • facets.json — 6,4 КБ brotli вместо оценки 2–3 КБ. Оценка не учитывала, что реестр характеристик хранит подписи, единицы и подсказки для 69 полей. Файл грузится лениво, вместе с каталогом, и на первый экран не влияет.
  • catalog.json — 9,3 КБ вместо 9. Позиции разложены витринным порядком (по кругу между коллекциями), а не пачками, поэтому длинные серии одинаковых идентификаторов, на которых экономил brotli, разорваны. Плата за то, что первый экран категории не выглядит четырьмя кадрами одной фактуры подряд.

Юридическая часть

  • Ни одного реального бренда и ни одного логотипа в кадре. Все 13 производителей придуманы. Фотографии — лицензии Pexels, Unsplash, CC0 и CC-BY-SA; кадры с читаемой этикеткой или маркой на инструменте отбракованы.
  • Персональные данные не собираются вообще: нет формы с именем и телефоном, поэтому 152-ФЗ не возникает — ни оператора, ни политики, ни галочки согласия.
  • Каталог и карточки отдают noindex, follow. Микроразметка ограничена WebSite и BreadcrumbList: отдавать поисковикам Product и Offer с вымышленными ценами — прямой риск для домена, который кормит.
  • Выдуманные названия остаётся проверить по базам ФИПС (классы 19 и 35) и ЕГРЮЛ — это ручной шаг, и он ещё не сделан.

Документы проекта

  • PRODUCT.md — что это за продукт и для кого
  • DESIGN.md — визуальный контракт: мир, палитра, правила
  • ATTRIBUTION.md — источники и лицензии
  • PLAN.md — исходный технический план

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages