
PWA anti-surveillance ALPR. L'archive de la caméra réside sur l'appareil.
ils nous surveillent. nous les surveillons aussi.
Une PWA de contre-surveillance pensée d'abord pour Android qui indique au conducteur où se trouvent les lecteurs automatiques de plaques d'immatriculation, avant qu'il ne passe devant.
Elle fournit des alertes de proximité en temps réel s'appuyant sur une archive de caméras fonctionnant hors ligne, un historique local d'exposition, une file d'attente sur l'appareil de signalements de caméras signés et chaînés par hachage, ainsi qu'un contexte de documents publics sourcés concernant les agences qui exploitent les caméras autour de vous.
L'application déployée n'a aucun point de terminaison de téléversement de signalements. Les signalements restent dans IndexedDB aujourd'hui. Une passerelle de soumission existe en tant que code opérateur et n'est pas une route déployée ; cette distinction est intentionnelle tout au long de ce README.
Elle ne fait délibérément pas une sixième chose : elle n'interroge le système d'aucun fournisseur, et les valeurs de plaques d'immatriculation ne quittent jamais l'appareil.
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
La pile LoRa est celle de Meshtastic, non modifiée : ce projet ne construit aucun firmware et s'apparie
avec un nœud standard. packages/api-client reste un espace réservé ; la PWA de production ne l'utilise
pas.
Le produit déployé est une PWA statique plus des Cloudflare Pages Functions : la route des tuiles de
caméras, l'API publique sous /api/v1/ (voir API publique), et deux routes
administratives protégées par Access sur l'hôte de développement privé. Il n'a pas de processus FastAPI,
de base de données Postgres, d'API de présence ni de point de terminaison de signalement déployé ; le
seul chemin d'écriture, POST /api/v1/submit, ouvre une pull request publique plutôt que d'écrire quoi
que ce soit.
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
Les tuiles de caméras sont demandées depuis /cameras/* de même origine, servies depuis la liaison R2
CAMERA_TILES, et mises en cache pour un usage hors ligne. Les archives de fond de carte et de vitesse
sont des requêtes de plage cross-origin vers l'hôte de tuiles public exploité par le projet.
darkroute.ai est l'application publique. Les Functions administratives vivent entièrement en dehors de
cette distribution.
Les outils de curation et la passerelle de soumission sont du code opérateur, tenu hors de cette distribution. Ni l'un ni l'autre n'est un serveur d'exécution déployé, et rien dans ce dépôt ne dépend de l'un ou de l'autre : l'application se construit, s'exécute, se teste et s'audite sans eux.
Le calcul géospatial réside dans packages/core ; les écrans consomment des stores et des adaptateurs.
La correspondance de plaques, l'historique des trajets et la chaîne de preuves des signalements restent
sur l'appareil.
L'archive est lisible par quiconque, sans clé, à https://darkroute.ai/api/v1/, également servie comme
https://api.darkroute.ai/v1/ et https://api.darkroute.ai/api/v1/ via le proxy de la console
développeur. Le contrat lisible par machine est GET /api/v1/openapi.json ; la prose est dans
docs/public/API.md §1.3 ; la console pour l'essayer est
api.darkroute.ai.