Skip to content

labeling node backend#65

Merged
itang06 merged 11 commits intofeature/label-nodefrom
feature/label/backend
Mar 7, 2026
Merged

labeling node backend#65
itang06 merged 11 commits intofeature/label-nodefrom
feature/label/backend

Conversation

@itang06
Copy link

@itang06 itang06 commented Mar 1, 2026

What?

Implemented backend for label node feature. It includes a new database table to store event labels and 2 new api endpoints:

  • POST /api/sessions/:session_id/time-label - stores a batch of timestamped event labels after a session ends

  • GET /api/sessions/:session_id/eeg-data?start=...&end=... - retrieves EEG data rows within a given time range for a specific session

  • this branch also includes a cherry-picked commit from a teammate that adds session_id to the eeg_data table (required to filter EEG data by session). That commit brought an export endpoint along with it (not part of this feature, just a side effect of the cherry-pick)

Additional endpoint added to get time labels:

  • GET /api/sessions/:session_id/time-label?start=...&end=... - retrieves time labels within a given time range

How?

Migration (add_time_labels.sql): creates time_labels table with id, session_id, timestamp, and label

Models added (models.rs):

  • TimeLabel (db output + used for GET response)
  • NewTimeLabel (api input)
  • EegDataRow (db output)
  • EegDataQuery (query parameters)

DB functions (db.rs):

  • added insert_time_labels() for batch insert
  • get_eeg_data_by_range() to filter by session_id and time range, ordered by time
  • added get_time_labels_by_range() to filter time labels by session_id and time range

handlers + routes (main.rs):
3 new handler functions

  • store_time_labels (POST) returns 201
  • get_eeg_data (GET) returns JSON array of EEG rows
  • get_time_labels (GET) returns JSON array of TimeLabel rows

Import cleanup:

  • Brought get_eeg_data_by_range and get_earliest_eeg_timestamp into scope via use statement, instead of using shared_logic::db:: path

Testing

  • cargo build passed with no new warnings other than pre-existing ones

Postman Testing:

get session 1. POST /api/sessions - created session with id of 2

post time label 2. POST /api/sessions/2/time-label - 201 response created, batch of labels stored

get time label 3. GET /api/sessions/2/time-label?start=...&end=... - returns the inserted labels filtered by time range

get eeg data 4. GET /api/sessions/2/eeg-data?start=...&end=... - returns eeg rows filtered by session and time range

  • note: eeg data was inserted directly via psql to verify this endpoint returned data correctly since the websocket server wasn't running


Notes

the task board specified using timestamp as a foreign key to eeg_data but we stored it as a value instead, since a hard foreign key would require exact timestamp matches but it won't actually always match. The label timestamp is used as a reference point for the GET endpoint's time range query, which would better match the actual use case

@github-actions
Copy link

github-actions bot commented Mar 1, 2026

✅ PR approval conditions satisfied (1 lead OR 2 team members approved).
[Last checked: 2026-03-05T02:20:40.017Z]



// Handler for POST /api/sessions/{session_id}/time-label
// Receives a batch of time labels from the frontend after a session ends and stores them in the DB.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a Get for the time-label as well, and similar to the get_eeg_data, allow the frontend to pass in a range

) -> Result<Json<Vec<EegDataRow>>, (StatusCode, String)> {
info!("Received request to get EEG data for session {} from {} to {}", session_id, params.start, params.end);

match shared_logic::db::get_eeg_data_by_range(&app_state.db_client, session_id, params.start, params.end).await {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a big issue, use add a use shared_logic::db::{get_earliest_eeg_timestamp,}; at the top so we don't need the shared_logic::db:: in shared_logic::db::get_eeg_data_by_range

@github-actions github-actions bot requested a review from HeisSteve March 1, 2026 20:36
@itang06 itang06 merged commit d2a9b5b into feature/label-node Mar 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants