AutoKey — расшифровщик ошибок китайских EV и гибридов
Владельцу BYD, Geely, Zeekr, Li Auto не нужен сканер за 150 000 ₽ и часы на форумах. Ввёл код — за минуту понял: «можно ехать» или «срочно в сервис».
Обзор проекта
AutoKey — веб-сервис, который переводит непонятный код или символ на приборной панели китайского электромобиля/гибрида в человекочитаемое описание: что это, насколько опасно и что делать прямо сейчас.
В отличие от универсальных баз OBD-II, сервис специализируется на китайских электрифицированных авто (BYD, Geely, Zeekr, Li Auto, Voyah, Changan, Avatr), где многие ошибки — заводские, не гуглятся одной строкой и приходят в машинном переводе низкого качества.
Быстрая карта решений
| Решение | Выбор |
|---|---|
| Ядро MVP | Ручной ввод кода → расшифровка из БД |
| Бэкенд | Laravel 11 + Filament 3 |
| Публичный фронт | Blade + Livewire + Alpine + Tailwind (SSR ради SEO) |
| БД | PostgreSQL (+ Redis) |
| Документация | Один HTML-файл на autokey.rosveb.ru |
| Монетизация | Freemium soft-gate |
| Старт наполнения | BYD → Geely/Zeekr → Li Auto → Voyah/Changan/Avatr |
Ключевые решения
Зафиксированы принятые решения и — главное — почему. Это защита от повторного обсуждения одного и того же в будущих итерациях.
1. Ядро MVP: ручной ввод кода, а не фото и не OBD
Три способа ввода из идеи — это три независимых проекта:
- Фото → распознавание значка — полноценный ML-проект (нужна размеченная выборка изображений, которой нет).
- Прямое подключение OBD по BLE — требует нативного мобильного приложения; вдобавок многие китайские EV не отдают полезные данные по generic OBD-II. Это техническое ограничение платформы.
- Ручной ввод кода — минимум зависимостей, полностью легально, ядро ценности продукта.
Решение: MVP = только ручной ввод. Остальное — отдельные фазы.
2. Главная проблема — данные и право, а не код
Инженерная часть проста. Весь риск и вся ценность — в том, откуда легально взять базу расшифровок. Пять источников из исходной идеи в трезвой оценке:
| Источник | Реальность для соло-разработчика |
|---|---|
| B2B-API Launch/Thinkcar | Переговоры на месяцы, слабая мотивация вендора. На MVP недоступно. |
| Подписка на дилерские порталы OEM | Стоит денег; ToS почти всегда запрещают перепродажу — прямой юр. риск. |
| Скрапинг autohome/dongchedi/cheari | Нарушение ToS + перепродажа спарсенного = двойная экспозиция. |
| Лицензирование профилей Car Scanner | Права размыты, лицензировать не у кого. |
| Краудсорсинг из логов Launch/Autel | Идея здоровая, но стимул толкает редистрибутировать чужие проприетарные данные. |
Решение: база = открытый OBD-II + ручные карточки из официальных руководств + модерируемый краудсорсинг «своими словами». Партнёрства — бизнес-трек будущего, не инженерия MVP.
3. Бэкенд: Laravel + Filament (а не FastAPI)
По сути продукт — курируемый каталог + модерация краудсорсинга, а не «сервис с логикой». 80% работы — админка наполнения и очередь модерации.
- Laravel + Filament даёт продакшн-админку (CRUD, роли, модерация, аудит), зрелые auth и биллинг почти даром.
- FastAPI пришлось бы дополнять рукописной админкой (SQLAdmin/starlette-admin слабее Filament).
- Аргумент «будущий ML на Python» слабый: CV-часть в любом случае выносится в отдельный микросервис.
Решение: Laravel 11 + Filament 3. CV-сервис (Фаза 3) — отдельный Python-сервис.
4. Публичный фронт: SSR (Blade + Livewire), а не Vue-SPA
Поиск по коду — SEO-продукт. Серверный рендеринг даёт индексируемый HTML из коробки и минимум стека. Vue-SPA потребовал бы SSR-обвязки ради того же результата.
Решение: Blade + Livewire + Alpine + Tailwind. Vue — точечно, если появится тяжёлый интерактив.
5. Монетизация: freemium soft-gate
Платить за расшифровку пустой базы никто не будет, а жёсткий paywall убивает SEO-трафик.
Решение: публичный поиск бесплатен и индексируется; за подпиской — подробное руководство, полный список причин, история. Без клоакинга.
6. Домен
autokey.rosveb.ru — пока под документацию (этот файл). При запуске продукта домен может уехать под приложение, а доки — на поддомен.
Границы и фазы
Пользователи
- Основной: владелец BYD / Geely / Zeekr / Li Auto / Voyah / Changan / Avatr с непонятной ошибкой. Приходит из поиска по запросу вида «BYD Han ошибка P1C85».
- Вторичный (будущее): небольшие СТО и таксопарки — пакетный доступ к базе (Фаза 2+).
- Внутренний: авто-эксперт и модератор, наполняющие базу через админку.
Что входит в MVP (Фаза 1)
- Публичный поиск: бренд + модель + код → карточка расшифровки.
- Курируемая база (все 4 группы брендов в модели; наполнение приоритетно с BYD).
- SEO-страницы под каждый
(бренд, модель, код)с SSR иsitemap.xml. - Аккаунты пользователей.
- Soft-gate: бесплатная краткая часть индексируется; подробное руководство — за подпиской (платёж — Фаза 1.5).
- Filament-админка: наполнение, курирование, роли, аудит.
- Захват промахов: каждый запрос «код не найден» пишется в очередь
(бренд, модель, код, счётчик)— одновременно сигнал спроса и приоритет курирования (см. Технические риски). - Ревью-гейт критичности:
severityпроставляется только вручную экспертом, никогда из крауда/машинного перевода; неизвестно → консервативный «жёлтый».
Что НЕ входит в MVP
- Фото-распознавание значков (Фаза 3).
- Прямое подключение OBD по BLE (Фаза 4).
- Приём платежей (Фаза 1.5).
- Краудсорсинг и очередь модерации (Фаза 2).
- Мобильное приложение.
Дорожная карта
| Фаза | Содержание | Зачем именно так |
|---|---|---|
| 1 — MVP | Админка + БД + публичный SSR-поиск + SEO + аккаунты + soft-gate | Ядро ценности, легально, растит органику |
| 1.5 | Эквайринг подписки (YooKassa/CloudPayments) | Платёж — когда база уже ценна |
| 2 | Краудсорсинг + очередь модерации | Живой массив под модерацией |
| 3 | Фото-распознавание (отдельный Python CV-сервис) | Модель нельзя держать в веб-процессе |
| 4 | OBD по BLE (нативное мобильное приложение) | Другой класс приложения |
source, status, confidence, скоуп кода), но код пишем только для Фазы 1.Критерии успеха MVP
- Поиск по коду отдаёт корректную карточку для наполненных брендов < 1 с.
- Каждая карточка
(бренд, модель, код)доступна по SSR-URL и индексируется. - Авто-эксперт заводит новую карточку через админку без разработчика.
- Есть измеримый органический трафик из поиска.
Архитектура и стек
┌────────────────────────────┐
Google/Яндекс ──▶│ Caddy (reverse proxy, TLS) │
Гость ───────▶│ 80 / 443, автосертификаты │
└──────────────┬─────────────┘
│ Host-роутинг
┌─────────────────┼──────────────────┐
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ Laravel 11 (PHP 8.3) │ │ Статика (этот HTML) │
│ ── публичный SSR-сайт │ │ autokey.rosveb.ru │
│ Blade + Livewire │ │ (эта документация) │
│ ── REST (внутр.) │ └──────────────────────────┘
│ ── Filament 3 (админка) │
└───────┬───────────┬──────┘
│ │
▼ ▼
┌────────────┐ ┌────────────┐
│ PostgreSQL │ │ Redis │
│ данные+FTS │ │ кэш/очереди│
└────────────┘ └────────────┘
Компоненты
Ядро — Laravel 11 (PHP 8.3). Одно приложение обслуживает публичный сайт (SSR на Blade + Livewire + Alpine + Tailwind), внутренний REST и админку Filament 3. Filament сам построен на Livewire — единый фронт-стек на весь проект.
Разделение ответственности: app/Models/ (Eloquent), app/Services/ (бизнес-логика: нормализация кода, поиск/фоллбэк, гейтинг — не в контроллерах), app/Livewire/ (публичные компоненты), app/Filament/ (ресурсы админки), app/Http/Controllers/ (тонкие контроллеры SSR + sitemap).
БД — PostgreSQL (уже развёрнута; помним про OOM-настройки: shared_buffers=4GB, work_mem=64MB). Поиск и нормализация — встроенный full-text + расширение pg_trgm (фаззи). Отдельный движок на MVP не нужен; при росте — Meilisearch.
Кэш и очереди — Redis: горячие карточки, результаты поиска; очереди (нотификации модерации, регенерация sitemap) — Фаза 2+.
Стек (сводка)
| Слой | Технология | Примечание |
|---|---|---|
| Язык | PHP 8.3 | |
| Фреймворк | Laravel 11 | |
| Админка | Filament 3 | Livewire-based |
| Публичный фронт | Blade + Livewire + Alpine + Tailwind | SSR ради SEO |
| БД | PostgreSQL | + pg_trgm, full-text |
| Кэш/очереди | Redis | |
| Auth | Laravel Fortify | Фаза 1 |
| Биллинг | YooKassa / CloudPayments | Фаза 1.5, не Cashier (он под Stripe/Paddle) |
| Инфра | Docker + Caddy | restart: unless-stopped, автобэкапы |
Развёртывание
- Всё в Docker, за общей сетью
proxy; публикацию домена делает только Caddy (порты 80/443 хоста заняты им). - Прямой dev-доступ — через свободный порт из
PORTS.md. - Публикация продакшн-домена — через
proxy add.
app/Services/Billing/, чтобы сменить провайдера без переписывания логики подписок.Модель данных
Это моат продукта. Модель сразу проектируется под все фазы (краудсорсинг, модерация, доверие к источнику), но заполняется только тем, что нужно Фазе 1.
brands — марки
| Поле | Тип | Описание |
|---|---|---|
slug | string, unique | byd, geely, zeekr (для URL) |
name / name_ru | string | BYD / БИД |
country | string | CN |
models — модели
| Поле | Тип | Описание |
|---|---|---|
brand_id | fk → brands | |
slug / name / name_ru | string | han / Han / Хан |
powertrain | enum | BEV | PHEV | EREV | HEV |
years | int4range? | диапазон лет (опц.) |
codes — идентичность и скоуп кода
| Поле | Тип | Описание |
|---|---|---|
code | string | нормализованный: P1C85, U0100, BMS_0X1234 |
code_type | enum | OBD2_STD | MFR | BMS_HEX | TELLTALE |
brand_id | fk? | NULL + OBD2_STD → generic (для всех); задан → производитель-специфичный (moat) |
model_id | fk? | опц. сужение до модели |
Один и тот же code у разных брендов — разные строки. Уникальность — (code, brand_id, model_id).
decodings — человекочитаемое содержимое
| Поле | Тип | Описание |
|---|---|---|
code_id | fk → codes | |
title_ru | string | «Ошибка датчика темп. батареи, модуль №3» |
severity | enum | green | yellow | red (светофор) |
causes | jsonb | список вероятных причин |
short_action | text | быстрое действие (бесплатная часть) |
deep_guide | text | подробное руководство (за гейтом) |
source | enum | manual | from_manual | crowd |
status | enum | draft | pending | published | rejected |
confidence, verified_by, verified_at | — | уверенность и верификация |
Разделение codes и decodings нужно для Фазы 2: на один код может прийти несколько кандидатных расшифровок из краудсорсинга, модерируемых независимо.
Нормализация и поиск
- Нормализация ввода:
trim,upper, унификация hex-форматов (0x1234/BMS_0x1234/BMS 1234→ канонBMS_0X1234). - Точный поиск published-расшифровки для
(код, brand_id пользователя). - Фоллбэк: если производитель-специфичной нет, а код похож на OBD-II — отдаём generic с пометкой «общий код, значение может отличаться».
- Фаззи (
pg_trgm): при опечатке предлагаем ближайшие коды.
Публичный поиск и SEO
Публичный поиск — не только фича, а главный канал привлечения. Каждая расшифровка должна существовать как отдельная индексируемая страница.
Макет карточки
[ Марка: BYD ▾ ] [ Модель: Han ▾ ]
[ Код ошибки: P1C85_______ ] [ Расшифровать ]
──────────────────────────────────────────────
⚠ Ошибка датчика темп. батареи, модуль №3
Критичность: 🟡 жёлтая — можно ехать, снизьте скорость
Причины: перегрев / обрыв датчика
Действие: дать остыть; если горит постоянно — в сервис
──────────────────────────────────────────────
🔒 Подробное руководство и полный список причин — по подписке
Светофор критичности
| Цвет | Значение | Пример |
|---|---|---|
| green | Информационная, можно ехать | Активен эко-режим |
| yellow | Осторожно, снизить/скоро в сервис | Перегрев модуля батареи |
| red | Стоп, опасность | Замыкание в высоковольтной цепи |
URL и индексация
- Каноничный URL расшифровки:
/byd/han/p1c85— тысячи long-tail страниц, каждая SSR и индексируема. - Страницы бренда/модели (
/byd,/byd/han) — хабы со списком кодов. - Автогенерируемый
sitemap.xml; разметка schema.org для сниппетов; canonical на каждой странице.
deep_guide. Показ поисковику иного контента — риск санкций.Производительность: горячие карточки в Redis; цель отклика < 1 с; фаззи-поиск через GIN-индекс pg_trgm по нормализованному коду.
Админка (Filament)
Админка — рабочее место наполнения базы. Именно здесь создаётся моат, поэтому она должна позволять авто-эксперту заводить карточки без участия разработчика.
Ресурсы и роли
| Ресурс | Действия | Кто |
|---|---|---|
| Бренды | CRUD | админ |
| Модели | CRUD | админ, эксперт |
| Коды | CRUD, привязка скоупа (бренд/модель, тип) | эксперт |
| Расшифровки | CRUD, draft → published, deep_guide, causes, severity | эксперт |
| Модерация (Фаза 2) | Просмотр pending, approve/reject, правка | модератор |
| Пользователи/подписки (Фаза 1.5) | Просмотр, ручное управление доступом | админ |
Процесс наполнения (Фаза 1)
- Эксперт заводит модель (если её ещё нет).
- Создаёт код с корректным скоупом.
- Пишет расшифровку:
title_ru,severity,causes,short_action,deep_guide; указываетsourceиconfidence. - Переводит в
published— запись доступна публичному поиску и попадает в sitemap.
Источник данных на этом шаге — только официальные руководства производителя и собственные снятые логи. Все изменения расшифровок логируются (аудит).
severity — самое опасное: неверное «зелёный» на красной ошибке = совет ехать с неисправностью. Оно НИКОГДА не берётся из непроверенного краудсорсинга или машинного перевода — только ручная экспертная простановка. Неизвестно → консервативный дефолт «жёлтый / осторожно».Монетизация (soft-gate / freemium)
Что бесплатно (и индексируется)
- Название ошибки (
title_ru), светофор (severity), краткая причина и быстрое действие (short_action).
Что за гейтом
- Подробное руководство (
deep_guide), полный список причин, история запросов; (будущее) прогноз износа батареи, пакеты для СТО.
Тарифы (ориентир)
| Тариф | Цена | Что даёт |
|---|---|---|
| Разовая расшифровка | 99–149 ₽ | доступ к deep_guide конкретной ошибки |
| «Защищённый водитель» | 399 ₽/мес | безлимит на руководства + история |
| Пакет для СТО/таксопарков | договорная | проф. база с руководствами (Фаза 2+) |
Реализация: Фаза 1 — аккаунты (Fortify) + гейтинг deep_guide за авторизацией, платёж ещё не подключён. Фаза 1.5 — эквайринг YooKassa/CloudPayments за интерфейсом app/Services/Billing/. Требует юрлица/самозанятости.
Юридическая граница данных
Самый важный раздел ТЗ. Ценность продукта — в базе расшифровок, а главный риск — нелегальный источник этой базы. Граница фиксируется жёстко и не размывается ради скорости наполнения.
✅ Разрешённые источники
- Стандарт OBD-II (
P0xxx,U0xxx) — открытый отраслевой стандарт. - Официальные руководства производителя — карты кодов, которые производитель сам публикует; заводятся вручную.
- Собственные снятые логи — расшифровки с реальных авто, верифицированные экспертом.
- Краудсорсинг «своими словами» — пользователь описывает наблюдаемый симптом; проходит модерацию (Фаза 2).
❌ Запрещённые источники
- Скрапинг и перепродажа autohome.com.cn, dongchedi.com, dtc.cheari.com и подобных.
- Данные дилерских порталов OEM для редистрибуции — ToS запрещают перепродажу.
- Проприетарные расшифровки Launch/Autel из логов как источник наполнения — риск редистрибуции. Краудсорсинг принимает симптом и слова пользователя, не копипаст текста платного сканера.
- Лицензирование community-профилей (Car Scanner) — права размыты.
Партнёрства — отдельный бизнес-трек
B2B-API Launch/Thinkcar и подписки на официальные OEM-порталы могут дать полноту данных легально, но это переговоры и договоры, а не разработка; не входят в MVP и не блокируют его. При заключении интегрируются как ещё один source без изменения архитектуры.
Технические риски и добыча данных
Оценка чисто технической осуществимости — механизмы, без юридической плоскости. Здесь сконцентрирован реальный риск проекта.
код → текст + критичность. Этот словарь физически живёт в диагностической базе производителя (ODX/PDX, ISO 22901). Чтение машины даёт не словарь, а лишь список активных кодов. По UDS ($19 ReadDTCInformation) видно «горит DTC 0x1C8500 + статус-байт», но что это значит — только в ODX-базе OEM. Добыть данные = восстановить справочник, а не подключиться к авто.Каналы добычи — техническая осуществимость
| Канал | Что технически получаешь | Осуществимость | Технический блокер |
|---|---|---|---|
| Стандарт OBD-II (P0/U0) | ~5000 generic-кодов (SAE J2012 / ISO 15031) | 🟢 тривиально | Для BEV почти пуст: нет эмиссионных ECU → Mode 03 ничего не отдаёт |
| ODX/PDX OEM (ISO 22901) | Полный словарь DTC каждого ECU — источник истины | 🟢 парсить / 🔴 достать | Внутренний артефакт OEM/поставщика, не публикуется |
| Дилерское диаг-ПО OEM | Тот же словарь в ресурсах/БД программы | 🟡 реверс возможен | Труднодоступно, на китайском, дилер-креденшелы, частые апдейты |
| Облако Launch/Autel/Thinkcar | Расшифровка на запрос VIN+код через API | 🟡 mitmproxy приложения | Нельзя дампнуть БД — только запросить уже известный код. Верификация, не массовая добыча |
| Локальные БД сканеров | Часть словаря в SQLite/блобах приложения | 🟡 реверс | Ценная китайская часть обычно cloud-only и зашифрована |
| Чтение по UDS + CAN-реверс | Активные коды + телеметрия (SoC, temps) через DBC | 🟡 телеметрия / 🔴 словарь | BMS/HV за SecurityAccess ($27, seed/key нет); UDS вернёт номер, не текст |
| Руководства (PDF) | Значения индикаторов + частые предупреждения | 🟡 OCR+MT-пайплайн | Полного словаря DTC в мануалах нет |
| Китайский веб (cheari, autohome, форумы) | Разрозненные пары код→текст | 🟢 скрапится | Шум, китайский, ручной ввод → тяжёлый ETL (OCR/MT/нормализация/дедуп) |
| Краудсорсинг (экспорты сканеров) | Пары код→текст из отчётов Launch/Autel | 🟢 парсинг PDF/CSV | Chicken-and-egg по объёму; нужна модерация корректности |
| LLM-генерация | «Объясни код X на модели Y» | 🔴 как источник | Галлюцинирует конкретику DTC — опасно для критичности. Только нормализатор/переводчик того, что уже есть |
Недооценённые проблемные вопросы
| Проблема | Суть и следствие |
|---|---|
| Идентичность кода | UDS-DTC = 3 байта + статус-байт per-ECU: одно число на разных ECU значит разное, ELM327 покажет в третьем формате. Ключ правильнее делать (адрес ECU, номер DTC, subtype), а не плоской строкой. Отдельный класс — китайский текст на экране (не код, а перевод). |
| Дешёвый ELM327 у BEV | Generic-режим видит эмиссионные DTC, которых у BEV нет; ценные BMS/HV/motor — за SecurityAccess. Пользователь может не суметь добыть интересный код своим железом. Подрывает Фазу 4 и путь «впиши код с ELM327». |
| Безопасность вывода | «Можно ехать / стоп» — ошибка в критичности = совет ехать с HV-неисправностью. Нужны провенанс, консервативный дефолт и ревью-гейт на severity. |
| Скоуп кода | Han 2021 vs 2023 — разные BMS/прошивки → разные значения. Точнее нужно до поколения/прошивки, но это ×10 к курированию скудных данных. Конфликт: точность vs покрытие vs стоимость. |
| SEO ≠ быстрый канал | Автогенерация страниц под нерасшифрованные коды = thin/doorway-контент = штраф Google. SEO масштабируется данными, не пространством кодов; медленный, data-gated. |
| Cold-start | На старте большинство запросов = «не найдено» → нет удержания и SEO. Нужна петля захвата промахов. |
| VIN ненадёжен | Публичные VIN-декодеры плохо покрывают китайские OEM. Ручной выбор бренда/модели прагматичнее; VIN как фичу де-скопить. |
| Фото — open-set | ISO 2575 (~100 значков) классифицируется, но полноэкранные LCD-сообщения с китайским = OCR+layout+MT. Реальная точность на фото ниже лабораторной; ложное «зелёный» на красной ошибке — риск. |
| Протухание данных | OTA меняют смысл кодов с версией прошивки → база деградирует. Нужны versioning и цикл ре-верификации. |
| Ёмкость сервера | Ещё один стек Laravel+PG+Redis конкурирует за 38 GB WSL; PG тут уже OOM-чувствителен. |
Что меняем в MVP (следствия)
- Петля захвата промахов — в Фазе 1: каждый «не найдено» пишется в очередь
(бренд, модель, код, счётчик), курируем по реальному спросу. Лечит cold-start и задаёт приоритет наполнения. - Ревью-гейт критичности —
severityникогда не из крауда/MT, только ручная экспертная простановка; неизвестно → «жёлтый / осторожно». - Идентичность кода — в модели хранить
(ECU, DTC-номер, subtype), строкаcode— производное для отображения/поиска. - Ожидания по OBD (Фаза 4) — зафиксировать: дешёвый ELM327 у BEV видит мало; ценность OBD-фазы под вопросом до проверки на реальных авто.
- Приоритет — data-пайплайн, а не ширина фич: ETL из руководств + краудсорсинг-экспорты + верификация важнее веб-функционала.
Открытые вопросы
Решённые
- ✅ Ядро MVP — ручной ввод кода → расшифровка.
- ✅ Бэкенд — Laravel 11 + Filament 3.
- ✅ Публичный фронт — Blade + Livewire + Alpine + Tailwind (SSR).
- ✅ Монетизация — freemium soft-gate.
- ✅ Старт наполнения — BYD → Geely/Zeekr → Li Auto → Voyah/Changan/Avatr.
- ✅ Домен —
autokey.rosveb.ruпока под документацию.
Открытые
- Домен продукта vs домен доков. При запуске продукт займёт
autokey.rosveb.ru, а доки уедут на поддомен — или продукт на отдельном домене. Решить к деплою MVP. - Эквайринг и юрлицо. YooKassa или CloudPayments? Есть ли юрлицо/самозанятость под приём платежей? Без этого Фаза 1.5 не стартует.
- Кто пишет экспертные карточки. Реальное узкое место — не код, а наполнение: сам разработчик / наёмный авто-эксперт / комбинированно. От ответа зависит скорость выхода на полезный объём базы.
- Скоуп кода по поколению/году. В v1 достаточно
(бренд, модель)или нужен ещё(поколение/год)? Задел в модели уже есть. - Язык. RU-only на старте или сразу закладывать мультиязычность? Ретрофит позже дороже.
- Объём стартового наполнения. Сколько карточек на бренд считаем «минимально полезным» для запуска и SEO-эффекта?