# Automotive Security Capstone – Development Roadmap (Device-Agnostic Phase) _This document converts all professor requirements and recent design agreements into a concrete, hardware-independent action plan. Follow the checklist in order; each task is phrased so that it can be completed with nothing more than laptop-level tooling, your existing repositories, and free-tier cloud services._ ## 0 Prerequisites | Tool | Min Version | Purpose | |------|-------------|---------| | Python | 3.11 | Runs backend, unit tests, code-gen tools | | Node.js | 20 LTS | Realm Flutter generator & web tooling | | Flutter | 3.22 | Cross-platform mobile build | | Docker | 25 | Local MongoDB + FastAPI containers | | Git CLI | 2.43 | Branch & CI workflows | | Poetry | 1.8 | Backend dependency/virtual-env manager | Download and install everything before you begin Sprint 7. --- ## 1 Repository Hygiene 1. `git pull --all` to ensure local clones are current. 2. Add the following protected branches in GitHub: `main`, `dev`, `edge-dev`, `backend-dev`, `mobile-dev`. 3. Create a mono-repo **commit template** in `.gitmessage` that enforces _scope – subject – body – footer_. 4. Register pre-commit hooks: ```bash pre-commit install # runs ruff, black, and flutter format ``` --- ## 2 Edge Folder (MicroPython – Device Stub Only) > _Directory: `backend/hardware` will **not** touch physical I/O – we rely on pure Python stubs for now._ ### 2.1 Create Packet & Metric Domain Classes ```python # hardware/packet.py class Packet: def __init__(self, ts: int, rssi: int, freq: float, payload: bytes): self.ts, self.rssi, self.freq, self.payload = ts, rssi, freq, payload ``` ### 2.2 Implement `signal_filter.py` 1. Copy constants table (RSSI, band list, dupe window) into module-level variables. 2. Write `should_accept(pkt: Packet) -> bool` covering * RSSI ≥ `MIN_RSSI_DBM` * `FREQ_BANDS` containment * duplication placeholder `dupe_count(pkt) < MAX_DUPES` 3. Write unit tests in `tests/test_signal_filter.py`. ### 2.3 Implement `report_logic.py` 1. Add dummy helpers `is_replay`, `is_jam`. 2. `classify(pkt)` → returns `"benign" | "replay" | "jam" | "drop"` based on filter + helpers. 3. Test coverage ≥ 90 %. ### 2.4 Lightweight Persistence Layer (In-Memory) 1. `edge/dao.py` with dict-backed tables `packets`, `alerts`. 2. CRUD functions mirror the future SQLite schema but do **not** write to disk. ### 2.5 Logging Stub `edge/log_utils.py` collects JSON objects into a list `LOG_BUFFER`; define `flush()` that prints to console (acting as JSONL rotation). --- ## 3 Backend Folder (FastAPI) ### 3.1 Poetry Setup ```bash cd backend && poetry init --name automotive_security_backend poetry add fastapi uvicorn[standard] motor pydantic-settings python-dotenv poetry add --group dev pytest pytest-asyncio black ruff ``` ### 3.2 Folder Conventions ``` backend/ ├─ app_logging/ # existing structured-logging helpers ├─ api/ │ ├─ dependencies.py # auth, db injection │ ├─ routers/ │ │ ├─ alerts.py # /v1/alerts │ │ └─ packets.py # /v1/packets/bulk │ └─ __init__.py └─ dao/ ├─ mongo.py # Async DAO layer └─ __init__.py ``` ### 3.3 DAO Implementation (`dao/mongo.py`) ```python from motor.motor_asyncio import AsyncIOMotorClient from pydantic import BaseModel from os import getenv client = AsyncIOMotorClient(getenv("MONGODB_URI")) db = client.auto_sec signals = db.signals alerts = db.alerts rolling_codes = db.rolling_codes async def insert_alert(doc: BaseModel): await alerts.insert_one(doc.model_dump()) ``` ### 3.4 Routers * **`/v1/packets/bulk`** – validates JWT, inserts batch via `signals.insert_many`. * **`/v1/alerts`** – returns last 100 alerts for a given `vehicle_id`. ### 3.5 Auth Middleware 1. Mutual-TLS postponed → implement JWT only (`pyjwt[crypto]`). 2. Dependency `get_current_device` decodes token, returns device claims. ### 3.6 Dockerfile & DO App Platform * `Dockerfile`: ```dockerfile FROM python:3.11-slim ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 WORKDIR /app COPY pyproject.toml poetry.lock /app/ RUN pip install poetry && poetry install --no-root --only main COPY . /app CMD ["uvicorn","main:app","--host","0.0.0.0","--port","8080"] ``` * Push to GitHub → DigitalOcean will build & deploy. --- ## 4 Mobile Folder (Flutter + Realm) ### 4.1 Add Dependencies ```bash flutter pub add realm realm_flutter flutter_dotenv ``` ### 4.2 Generate Realm Models Run `dart run realm generate` after editing `realm_models.dart`. ### 4.3 Sync Service Prototype ```dart class SyncService { late Realm realm; Future<void> init() async { final appConfig = AppConfiguration('<APP_ID>'); final app = App(appConfig); realm = Realm(Configuration.flexibleSync(app, [Alert.schema])); await realm.subscriptions.update((mutable) { mutable.add(realm.all<Alert>()); }); await realm.syncSession.waitForDownload(); } } ``` ### 4.4 Widget Test Create `test/realm_open_test.dart` verifying `SyncService.init()` does not throw. --- ## 5 Cloud Database – Atlas Quick Start 1. Sign up → Create **Shared M0** cluster. 2. Region: same as DO app. 3. Add user `capstone_api` w/ readWrite on `auto_sec` DB. 4. Whitelist `0.0.0.0/0` for dev; later tighten. 5. In **Data Explorer** create collections. 6. Open **Web Shell**: ```js db.alerts.createIndex({ timestamp: 1 }, { expireAfterSeconds: 7776000 }) db.signals.createIndex({ timestamp: 1 }, { expireAfterSeconds: 7776000 }) ``` 7. Copy SRV connection string → place in DO secrets & `.env.development`. --- ## 6 Continuous Integration Matrix | Job | Runs On | Key Steps | |-----|---------|-----------| | `edge-tests` | ubuntu-latest | `pip install -r edge/requirements-dev.txt && pytest edge/tests` | | `backend-tests` | ubuntu-latest | `poetry install && pytest` | | `flutter-tests` | macos-latest | `flutter test` | | `docker-build` | ubuntu-latest | `docker build -t backend . && docker push` | --- ## 7 Immediate Sprint Tasks | ID | Task | Owner | Hours | |----|------|-------|-------| | S7-1 | Implement `should_accept` full logic | Alice | 4 | | S7-2 | DAO layer + `/bulk` API | Bob | 6 | | S7-3 | Realm sync POC | Carol | 5 | | S7-4 | CI pipeline file | Dan | 3 | | S7-5 | Update docs & diagrams | Eve | 2 | Review pull-requests daily; merge freeze Wednesday @ 17:00.