Skip to content

Iteration 11

Choose a tag to compare

@Niravanaa Niravanaa released this 09 Mar 03:42
· 188 commits to main since this release
e382e8b

Release Date: March 8, 2026

🎯 Overall Summary

Iteration 11 focused on simulation naming, traffic congestion visualization, metrics reporting, authentication hardening, logging improvements, and code quality refactoring. This iteration delivered end-to-end simulation naming (backend persistence, frontend modal, and simulations table display), traffic congestion data overlaid on the route visualization map, a full simulation metrics pipeline (vehicle utilization rate, metrics endpoint, and CSV download), traffic state persistence across simulation runs, and re-enabled router-level API authentication with centralized error-to-HTTP mapping. Key quality improvements include a comprehensive CamelCase-to-snake_case rename, replacement of bare logging imports, structured endpoint and driver-service logging, and a WebSocket router fix enabling live simulation streaming.

🏎️ Velocity

image

💵 Contractor Estimate

Artifact Type Level of Effort Estimated Price (CAD)
Simulation Naming & State Medium (10h) $220
Metrics & Reporting Medium (8h) $176
Authentication & Security Medium (7h) $154
Logging & Observability Medium (6h) $132
Traffic Persistence & Visualization Medium (6h) $132
Code Quality & Refactoring Low (5h) $110
Frontend Routing & UX Low (3h) $66
Total 45h $990

Notes:

  • The hours listed above represent the time specifically spent on developing the individual software artifacts. They do not reflect the total time our team has committed to Iteration 11.

🔄 Retrospective

What went well

  • Stakeholder thinks the app is pretty much done  (+1)
  • Traffic visualization finally done!
  • Task amount slowing down, were almost there!
  • TA feedback addressed (back/sim side)

What went wrong

  • Some stuff got rolled over to next sprint
  • Stakeholder / dispatchers will be unavailable sooner than expected since they are starting the season earlier. 
  • Meeting with TA and Rigby didn’t happen.  

What we can improve on

  • Last-minute PRs (+1)
  • Getting feedback on design decisions before proceeding with implementation for big tasks

🤝 Individual Contributions

@Ambrose821 - Ambrose McLaughlin [ID: 40239754]

  • Sim: Added vehicle utilization rate reporting in #794

    • Added get_vehicle_utilization_ratio(), increment_vehicle_active_time(), and increment_vehicle_idle_time() to SimulationReport; utilization = active time ÷ (active + idle time)
    • Idle time covers any period where a vehicle has no driver assigned or a driver with no tasks; active time covers all other states
    • Added metric recording logic in vehicle.py and included utilization in the payload emitted by simulator_controller.py
  • Backend: Add endpoint to retrieve simulation metrics in #819

    • Added a new GET endpoint /api/v1/simulation/{sim_id}/report returning aggregate metrics via a new SimulationReportResponse schema in back/schemas/simulation_report.py
    • Implemented get_simulation_report in SimulationService to fetch the latest persisted report metrics with permissions and error handling
  • Frontend: Add metrics download button in #818

    • Added a "Report" button to the actions column in the simulations table that calls the new metrics endpoint and downloads the result as a CSV file
    • Introduced GetSimulationReportResponse TypeScript interface in types.ts to define the expected API response shape

@briantkatch - Brian Tkatch [ID: 40191139]

  • Chore: Delete CDK in #803

    • Removed the AWS CDK infrastructure directory; the Ansible-based deployment is now current and includes observability and TLS support
    • Eliminates stale cloud configuration that no longer reflected the active deployment strategy
  • Backend: Implement sim naming in BE #773 in #804

    • Updated initialize_simulation to optionally accept a simulation name
    • Ensured the backend never returns null for a sim name, falling back to a generated name derived from the scenario name
  • Backend: Implement traffic persistence #706 in #826

    • Added traffic_csv_data (TEXT, nullable) column to sim_instances with migration 09bfae8f09b5_add_traffic_csv_data_to_sim_instances.py
    • Enhanced TrafficConfig to support template-based (traffic_level) and in-memory (traffic_csv_data) modes; TrafficParser now accepts io.StringIO for in-memory CSV parsing
    • Added traffic_config_extractor.py utility shared by JsonParseStrategy and ReplayParser; updated initialize_simulation, restore_simulation, and branch_simulation services accordingly
    • 21 tests covering in-memory CSV parsing, traffic config extraction, ReplayParser restoration, and service-layer persistence; all 1,259 tests pass

@Jpuntul - Jutipong Puntuleng [ID: 40080233]

  • Frontend: Add traffic congestion data to simulation and route visualization in #733
    • Frontend: split route lines into colored sub-features via a splitByTraffic helper in geojson-adapters.ts; worst severity wins when ranges overlap (severe > moderate > free_flow); Mapbox layers use data-driven coalesce paint expressions on color/opacity properties, defaulting to green when no traffic data is present
    • Traffic colors are trimmed automatically as drivers advance because the existing turf.js lineSlice call already trims route features from the driver's current position

@mahutt - Thomas Mahut [ID: 40249811]

  • Frontend: Optimistic task state update on assign #709 in #776

    • Fixed the multiple in-progress tasks bug: BatterySwapTask.set_assigned_driver and unassign_driver now use self.set_state instead of direct self.state = assignment, ensuring has_updated = True so the diff frame reflects the change
    • Updated client-side optimistic entity state update to set task state to "assigned" immediately on submit, preventing tasks from briefly showing as "in progress" when the sim is paused
    • Introduced a TaskState enum
  • Frontend: Add sim name to simulations table #775 in #800

    • Replaced the User ID column with a Name column in the simulations table; displays a faded "N/A" when the simulation's name attribute is null
    • Added name attribute to the Simulation TypeScript interface definition
  • Fix: Real time factor to playback speed conversion #815 in #816

    • Fixed SimulationService.get_playback_speed which returned the raw real_time_factor instead of its inverted value, causing playback speed to appear backwards
  • Frontend: Simulation name modal in #820

    • Prompts the user for a simulation name when they first press "Start Simulation"; defaults to the current scenario name and supports pressing Enter to start directly
    • Adds a loading state for simulation initialization; updates sim name type and removes the null check in the simulations table
  • Refactor: Update frontend simulation pages routing path #830 in #831

    • Updated client-side routing from simulation/ to simulations/ to comply with REST endpoint naming standards
    • Updated all internal links, redirects, and useNavigate calls; no user-facing URL changes
  • Docs: Wiki contributions in Repo Wiki

    • Updated Deployment Plan and Infrastructure documentation.
    • List of Revisions: 1

@MeSumo - Sumer Abd Alla [ID: 40247712]

  • Refactor: Rename files and variables from CamelCase to snake_case in #799

    • Renamed sim CamelCase source files such as SimulatorController, OSRMConnection, and RealTimeDriver to snake_case
    • Renamed CamelCase variables inside classes to snake_case; fixed all imports, cross-module references, and tests referencing these changes
    • Pure style refactor with no behavioral changes, validated by the existing test suite
  • Refactor: Replace Bare Logging Imports in #801

    • Replaced all import logging in the sim and scripts folders with from grafana_logging.logger import get_logger
    • Replaced all logger = logging.getLogger(__name__) with logger = get_logger(__name__) for consistency with the centralized Grafana logging setup
  • Docs: Wiki contributions in Repo Wiki

    • Updated Meeting Minutes – General documentation with iteration meeting notes.
    • Created and updated R3 Simulation Spec documentation.
    • List of Revisions: 1 | 2 | 3 | 4 | 5 | 6

@Michael-Mezzacappa - Michael Mezzacappa [ID: 40263789]

  • Backend: Add logging to driver service #784 in #835

    • Added logger.info() calls in back/services/driver_service.py for assign_task, unassign_task, reassign_task, batch_assign, and reorder_tasks
    • Each log entry includes sim ID, driver ID, task ID(s), and requesting user; uses the existing get_logger from grafana_logging.logger with no new dependencies
  • Backend: Added endpoint logs #785 in #834

    • Registered log_request from grafana_logging/logger.py as an @app.middleware("http") in main.py, logging HTTP method, path, status code, and response time for every request
    • Excludes the /api/v1/metric/metrics Prometheus scrape endpoint to avoid log noise; does not log request bodies or sensitive headers

@Niravanaa - Nirav Patel [ID: 40248940]

  • Backend: Add simpy dependency for simulation support #786 in #791

    • Added simpy>=4.0.0 to back/requirements.txt and to [project.dependencies] in back/pyproject.toml
  • CI: Add check for in-branch merge commits in PRs #790 in #796

    • Added a Check for in-branch merge commits step in .github/workflows/branch-naming-check.yml after Validate commit messages
    • For each commit in the PR range (base.sha..head.sha), counts parents via git cat-file -p; fails with rebase instructions if any commit has more than one parent
    • Leverages the existing fetch-depth: 0 checkout configuration — no additional setup required
  • Backend: Implement async dependency for raw request body access in #795

    • Added get_raw_body async dependency in back/api/v1/scenarios.py; converted create_scenario, update_scenario, and initialize_simulation from async def to plain def, injecting raw_body: bytes = Depends(get_raw_body) instead of calling await request.body() inline
    • FastAPI now dispatches all three handlers to its thread pool, making the synchronous SQLAlchemy Session safe under concurrent load
  • Fix: Improve error handling with logging in simulation endpoints #781 in #793

    • Added get_logger from grafana_logging.logger to back/api/v1/simulation.py
    • Replaced all 12 occurrences of raise HTTPException(status_code=500, detail=str(err)) with logger.exception(...) + a generic "An unexpected error occurred." detail to avoid leaking internal exception strings
  • Fix: Add websocket router for simulation streaming in #813

    • Added a separate websocket_router in back/api/v1/simulation.py and moved the /stream/{sim_id} WebSocket endpoint onto it
    • Mounted simulation_ws_router in back/main.py without dependencies=[Depends(get_user_id)], consistent with the existing metrics_router pattern
    • No auth coverage lost: the WebSocket endpoint self-authenticates via get_user_id_over_websocket reading the bearer token from the Authorization header or cookie
  • Backend: Replace print statements with logging in RealTimeDriver in #828

    • Added import logging and logger = logging.getLogger(__name__) to real_time_driver.py
    • Replaced print("Pausing")logger.info, print("Resuming")logger.info, print("Specified Sim-time reached")logger.info, print("Simpy schedule is empty")logger.warning, config load warning → logger.warning
  • Fix: Add max seq number retrieval for simulation restoration in #825

    • Added get_max_seq_number() to SimFrameCRUD to query the highest existing sequence number for a given simulation instance
    • Added initial_frame_counter parameter to SimulatorController.__init__ and Simulator.initialize(); restore_simulation now reads the max persisted seq number and passes max_seq + 1 as the initial frame counter to prevent seq number collisions with historical rows

@Verdone - Giuliano Verdone [ID: 40252190]

  • Backend: Add centralized error-to-HTTP mapping in #792

    • Registered exception handler callbacks in main.py declared in a dedicated exception_handlers.py module, mapping domain exception classes to their appropriate HTTP status codes
    • Removed the try/except blocks from individual route handlers that existed solely to catch these domain exceptions, eliminating duplication
  • Fix: Redirect to original URL intent on auth in #787

    • In authenticated.tsx: unauthenticated access now redirects to /login?next=<pathname+search+hash> using useLocation from React Router
    • In unauthenticated.tsx: after login, reads next from the query string and redirects there; a guard accepts only /-prefixed, non-//-prefixed values, falling back to / otherwise
    • Redirects use replace: true to avoid cluttering browser history; tests updated in authenticated.test.tsx and unauthenticated.test.tsx
  • Backend: Re-enable router-level VeloSim API auth in #788

    • Applied router-level auth at back/main.py so every /api/v1 route gets an auth check; endpoint-level dependencies inside API files are still present for user_id injection
    • metrics_router remains public and is not grouped with api_router; added explicit public-endpoint tests in back/tests/test_main_public_endpoints.py
    • Disabled Loki logging in tests to fix ~2-minute blocking caused by urllib.request.urlopen timing out on each log call when Loki is not running in the test environment
  • Docs: Wiki contributions in Repo Wiki

    • Updated Meeting Minutes – General and Meeting Minutes – Backend documentation with iteration meeting notes.
    • List of Revisions: 1 | 2

@vinishamanek - Vinisha Manek [ID: 40229456]

  • Frontend: Persist sidebar state in #805

    • Added a getCookieValue helper to read values from document.cookie
    • Updated open state initialization in SidebarProvider to read the cookie value so the sidebar's open/closed state persists across page refreshes
  • Frontend: Transition to resource in selected item bar after assignment in #806

    • Added selectItem(SelectedItemType.Driver, pendingAssignment.driverId) after task assignment confirmation, scrolling to and highlighting the assigned driver's resource card
    • Merged confirmUnassignedOnly into confirmAssignment(unassignedOnly = false) to eliminate the near-duplicate method

@CarciDev - David Carciente [ID: 40247907]

  • Sim: Add traffic congestion data to simulation and route visualization in #733
    • Sim: introduced TrafficTriple data model; Route.notify_traffic_changed() rebuilds cached triples by walking all roads and translating per-road geometry indices to route-wide coordinate indices; TrafficController._notify_routes_for_road() bridges road-level events to route visualization with the existing GPS sync delay model
    • Replaced ratio-based index mapping with geographic find_nearest_index() to eliminate driver position rubber-banding when traffic changes a road's point count mid-traversal

@cmezzac - Christopher Mezzacappa [ID: 40249451]

📋 What's Changed

Full Changelog: Iteration10...Iteration11