Перейти к основному содержимому

Разработчику: с чего начать

Эта страница — вход в раздел. Она отвечает на три вопроса: что мы вообще строим, что уже есть в коде и что надо знать до первого коммита.

Что за система

Аренда инструмента через уличный постамат. Шкаф с ячейками, в каждой ячейке электрозамок. Планшет на стенке шкафа — это «киоск»: он показывает экран клиенту и разговаривает с платой замков. Клиент забирает и сдаёт инструмент по семизначному коду. Оператор следит за постаматами из веб-панели.

Устройство ставится в Риге, то есть в ЕС. Камеры и микрофон из прошивки выпилены намеренно, ради 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 на машине владельца). Здесь она не переписана: пересказано только то, что влияет на код. Первоисточники по каждой теме названы на месте.