
Анти-ALPR-наблюдение PWA. Архив камеры хранится на устройстве.
они следят. мы следим в ответ.
Ориентированное в первую очередь на Android PWA-приложение для противодействия слежке, которое сообщает водителю, где находятся автоматические считыватели номерных знаков, ещё до того, как он проедет мимо них.
Оно обеспечивает оповещения о близости в реальном времени на основе работающего офлайн архива камер, локальную историю воздействия, хранящуюся на устройстве очередь подписанных и связанных хеш-цепочкой сообщений о камерах, а также подкреплённый источниками контекст публичных записей о ведомствах, эксплуатирующих камеры вокруг вас.
У развёрнутого приложения нет конечной точки для загрузки сообщений. Сообщения на данный момент остаются в IndexedDB. Шлюз для отправки существует как операторский код и не является развёрнутым маршрутом; это различие намеренно подчёркивается на протяжении всего этого README.
Оно намеренно не делает шестой вещи: оно не запрашивает ни одну систему поставщика, и значения номерных знаков никогда не покидают устройство.
darkroute/
├── apps/
│ ├── pwa/ React 19 + TypeScript + Vite PWA
│ ├── desktop/ developer console at api.darkroute.ai; its functions/ proxy /v1 and /api/v1 to the apex
│ └── android/ buildable Android Trusted Web Activity shell
├── packages/
│ ├── core/ pure geometry and alert engine; no DOM or I/O
│ └── api-client/ empty placeholder; the live contract is GET /api/v1/openapi.json
├── functions/
│ ├── cameras/ same-origin camera tiles from the CAMERA_TILES R2 binding
│ └── api/
│ ├── v1/ the public API: reads, /submit (opens a PR), /photo, openapi.json, _middleware
│ └── admin/ Cloudflare Access tester allowlist (private dev host only)
├── scripts/ camera pipeline, deploy, asset and policy checks
├── docs/ implementation, operations and public documentation
├── the design-gap ledger unresolved design decisions and stand-ins
└── installer.sh
Стек LoRa — это собственный, немодифицированный стек Meshtastic: этот проект не собирает прошивку и работает в паре со стандартным узлом. packages/api-client остаётся заглушкой; production PWA его не использует.
Развёрнутый продукт — это статическое PWA плюс Cloudflare Pages Functions: маршрут для тайлов камер, публичный API по пути /api/v1/ (см. Публичный API) и два административных маршрута, защищённых Access, на приватном dev-хосте. В нём нет процесса FastAPI, базы данных Postgres, API присутствия или развёрнутой конечной точки для сообщений; единственный путь записи, POST /api/v1/submit, открывает публичный pull request, а не пишет куда-либо.
flowchart LR
OSM["OpenStreetMap"] --> PIPE["scheduled Node camera pipeline"]
PIPE --> R2[("R2 camera archive")]
R2 --> CAM["/cameras/* Pages Function"]
subgraph device["Browser or Android TWA"]
GPS["geolocation + other adapters"] --> CORE["packages/core alert engine"]
CORE --> UI["DRIVE / map / reports"]
UI <--> IDB[("IndexedDB + service-worker cache")]
end
CAM --> IDB
MAP["project tile host (PMTiles)"] --> UI
Тайлы камер запрашиваются с того же источника по пути /cameras/*, отдаются из привязки R2 CAMERA_TILES и кэшируются для офлайн-использования. Архивы базовой карты и данных о скорости — это кросс-доменные range-запросы к публичному хосту тайлов, управляемому проектом. darkroute.ai — это публичное приложение. Административные Functions полностью находятся за пределами этого дистрибутива.
Инструменты курирования и шлюз для отправки — это операторский код, исключённый из этого дистрибутива. Ни то, ни другое не является развёрнутым сервером времени выполнения, и ничто в этом репозитории не зависит ни от того, ни от другого: приложение собирается, запускается, тестируется и проходит аудит без них.
Геопространственные вычисления находятся в packages/core; экраны используют хранилища и адаптеры. Сопоставление номерных знаков, история поездок и цепочка доказательств сообщений остаются на устройстве.
Архив доступен для чтения любому без ключа по адресу https://darkroute.ai/api/v1/, а также отдаётся как https://api.darkroute.ai/v1/ и https://api.darkroute.ai/api/v1/ через прокси консоли разработчика. Машиночитаемый контракт — GET /api/v1/openapi.json; текстовое описание — docs/public/API.md §1.3; консоль для его проверки — api.darkroute.ai.
| Маршрут | На что отвечает |
|---|---|
GET /api/v1/cameras | камеры в bbox (≤ 1.5° по стороне, ≤ 24 тайла, ≤ 1000 строк), необязательный фильтр owner |
GET /api/v1/stats | размер архива, поколение, временные метки сборки и вышестоящего источника |
GET /api/v1/abuse | задокументированные случаи и дата генерации; необязательный fips округа |
GET /api/v1/news | автоматически собранные заголовки об ALPR, ссылки на источники и статус сбора |
GET /api/v1/atlas | ведомства и поставщики EFF Atlas по округам, с датами получения/проверки; необязательный fips |
GET /api/v1/monitoring | инвентаризация оборудования дорожного мониторинга; необязательные kind и bbox |
GET /api/v1/monitoring/image?id=... | доступная фотография от издателя для выбранной камеры дорожного движения |
GET /api/v1/place | поиск места в США/Пуэрто-Рико, проксируемый так, чтобы геокодер никогда не видел адрес водителя |
GET /api/v1/route | маршрут движения, обходящий до 60 точек; никогда не кэшируется |
GET /api/v1/doc/{name} | опубликованный документ из публичного зеркала, в формате Markdown |
POST /api/v1/submit | исправление, превращаемое в pull request с меткой [unreviewed], в архив ничего не записывается |
PUT /api/v1/photo | фотография, на которую ссылается отправка, с ключом по её байтам; GET /api/v1/photo/{key} отдаёт её обратно |