Разработчику: с чего начать
Эта страница — вход в раздел. Она отвечает на три вопроса: что мы вообще строим, что уже есть в коде и что надо знать до первого коммита.
Что за система
Аренда инструмента через уличный постамат. Шкаф с ячейками, в каждой ячейке электрозамок. Планшет на стенке шкафа — это «киоск»: он показывает экран клиенту и разговаривает с платой замков. Клиент забирает и сдаёт инструмент по семизначному коду. Оператор следит за постаматами из веб-панели.
Устройство ставится в Риге, то есть в ЕС. Камеры и микрофон из прошивки выпилены намеренно, ради GDPR — это и была изначальная цель проекта. Отсюда ограничения, которые выглядят странно, пока не знаешь причину: библиотека, которой нужна камера, на этой плате работать не будет, а микрофонный тракт физически есть, но включать его нельзя.
| Плата | RK3566, 2 ГиБ, Android 11, ядро 4.19 от вендора |
| Экран | одна панель 800 × 1280, портрет |
| Замки | плата UPUS-SKB27 по RS485, 27 каналов, порт /dev/ttyS0 |
| Связь в проде | Wi-Fi, на роутере фильтр — только до нашего backend |
| Приложение | Expo / React Native, запечено в образ как системное, держит роль рабочего стола |
Три вещи, которые надо знать до того, как трогать код
1. Плата физически отключена
Живого железа больше нет. Всё, что не покрыто тестами и не записано в документах, проверить
негде. Векторы в packages/lock-protocol/test/vectors.ts сгенерированы из съёма живого
устройства и руками не правятся: если тест на них падает, это не «поправить тест», а «вернуть
код как было».
Разработка идёт на эмуляторе платы — как тестировать без платы.
2. Некоторые команды платы необратимо ломают железо
Кадры 9A и 9B — это удержание питания катушки соленоида. Катушка рассчитана на импульс
в треть секунды; постоянный ток сжигает её за десятки секунд, и замок после этого меняется
только целиком. Плата при этом кадр примет и ответит эхом — отказа не будет.
Поэтому любая отправка в шину идёт через барьер assertFrameAllowed(), а отдельный тест ищет
такие литералы по всему репозиторию и падает, если находит.
Подробно: четыре запрета.
3. Ответ 0x00 означает два разных состояния сразу
«Дверь открыта» и «на этом канале нет замка» плата сообщает одинаково, байт в байт. Различить их опросом невозможно — это свойство протокола, а не наш недосмотр.
Отсюда главное архитектурное решение проекта: состояние ячейки — это свод трёх источников, а не показание датчика.
| Источник | На какой вопрос отвечает |
|---|---|
| конфигурация | существует ли такая ячейка вообще |
| опрос платы | что на входе прямо сейчас |
| журнал событий | что с ней было раньше |
Подробно: состояние ячейки.
Что уже готово, а что в работе
Состояние на 2026-09-01, вечер. Репозиторий наполняется быстро — проверяйте по коду, а не по этой таблице.
| Состояние | |
|---|---|
packages/lock-protocol | ✅ готов, тесты на векторах с живого железа |
packages/lock-sim | ✅ эмулятор платы, включая режимы неисправностей |
packages/domain | ✅ состояние ячейки, машина состояний киоска, журнал, антибрут, коды |
packages/contracts | ✅ zod-схемы обмена, 123 теста |
packages/i18n | ✅ 62 ключа × 5 языков, 80 тестов. ⚠️ литовский и эстонский не вычитаны носителями |
packages/design-tokens | ✅ генерация из CSS дизайн-системы, расхождение ловит тест |
apps/panel | ✅ написана целиком, 200 тестов, строго статическая сборка |
apps/api | 🟡 пишется прямо сейчас |
apps/kiosk | 🟡 пишется прямо сейчас: есть нативный порт, шина замков, надзор за живостью; бизнес-логика в работе |
infra | 🟡 сеть и скрипты развёртывания готовы, машины не созданы — упёрлись в дисковую квоту Oracle, решение за владельцем |
Два документа в корне репозитория, которые надо прочитать
Они не дублируются здесь намеренно — это оперативные списки, которые меняются чаще документации.
NATIVE-GATE.md— что обязано попасть в единственную нативную заливку. Нативная часть меняется только выездом, поэтому всё, что может понадобиться позже, кладётся в неё сейчас. См. что обновляется по воздуху.COMMISSIONING.md— порядок дня установки и приёмка. Половина шагов необратима, и придумывать их на морозе у открытого шкафа — плохая идея.
Быстрый старт
npm install
npm test # тесты протокола на векторах с живого железа
npm run build:packages
Документация (этот сайт) ставится и собирается отдельно — см. развёртывание.
Куда дальше
- Устройство монорепо — что в каком пакете и зачем.
- Протокол замков — кадры, контрольная сумма, состояния.
- Четыре запрета — то, что ломает железо и то, что ломает разбор.
- Состояние ячейки — модель, из которой растёт вся бизнес-логика.
- Сторожевой таймер — почему плата перезагружается сама и что это значит для кода.
- Среда устройства — экран, права, сеть, что сломает залочка.
Прошивка, образы, разделы памяти, UART-консоль, стоп-правила заливки — это отдельный
репозиторий (/Users/vik/todelete на машине владельца). Здесь она не переписана:
пересказано только то, что влияет на код. Первоисточники по каждой теме названы на месте.