feat: add Phase 25.5a server-side device config API endpoints
- Add database migration (migrate_phase25_5a.sql): * Add owner_name, car_model, device_name, avatar_path columns to devices table * Add config_version and config_updated_at for cache invalidation - Add server/modules/device_config.py: * get_device_config(device_id): retrieve config for Pi sync * update_device_config(device_id, data): update config with validation - Add server API endpoints: * GET /api/device-config (authenticated with device_key, Pi fetches config) * POST /api/device-config (authenticated as user, admin updates config) - Enhance server/modules/db.py: * Add get_device_by_id() function to retrieve all device config fields Phase 25.5a enables server-side device identity management and connection-driven sync. Pi will fetch from this endpoint when internet available, keeping config in sync. Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -17,6 +17,7 @@ from flask_login import login_user, logout_user, current_user
|
||||
from modules import db
|
||||
from modules.auth import require_device_auth
|
||||
from modules.user_auth import login_manager, User, check_password, require_login
|
||||
from modules import device_config
|
||||
|
||||
# ── Geocode cache ──────────────────────────────────────────────────────────
|
||||
try:
|
||||
@@ -618,6 +619,44 @@ def portal_trip_compat(trip_id):
|
||||
return portal_trip_detail(trip_id)
|
||||
|
||||
|
||||
# ── Phase 25.5a: Device configuration sync ──────────────────────────────────
|
||||
|
||||
@app.get("/api/device-config")
|
||||
@require_device_auth
|
||||
def api_device_config_get():
|
||||
"""Get device configuration for the authenticated device.
|
||||
|
||||
Pi calls this to fetch config from server (connection-driven sync).
|
||||
Returns owner_name, car_model, device_name, avatar_path, config_version.
|
||||
"""
|
||||
config = device_config.get_device_config(g.device_id)
|
||||
if not config:
|
||||
return jsonify(error="device not found"), 404
|
||||
return jsonify(config)
|
||||
|
||||
|
||||
@app.post("/api/device-config")
|
||||
@require_login
|
||||
def api_device_config_update():
|
||||
"""Update device configuration (server portal/admin only).
|
||||
|
||||
Updates owner_name, car_model, device_name, avatar_path.
|
||||
Increments config_version to signal change to Pi.
|
||||
"""
|
||||
device_id = _portal_device_id()
|
||||
if device_id is None:
|
||||
return jsonify(error="device not configured"), 404
|
||||
|
||||
body = request.get_json(silent=True) or {}
|
||||
success, errors = device_config.update_device_config(device_id, body)
|
||||
|
||||
if not success:
|
||||
return jsonify(error="Invalid device config.", fields=errors), 400
|
||||
|
||||
config = device_config.get_device_config(device_id)
|
||||
return jsonify(config)
|
||||
|
||||
|
||||
def main():
|
||||
app.run(host="0.0.0.0", port=8098)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user