Skip to content

Add vehicle_crew supporting table - #246

Open
chrisyamas wants to merge 8 commits into
developfrom
feature/issue-220-vehicle-crew
Open

Add vehicle_crew supporting table#246
chrisyamas wants to merge 8 commits into
developfrom
feature/issue-220-vehicle-crew

Conversation

@chrisyamas

@chrisyamas chrisyamas commented Dec 29, 2025

Copy link
Copy Markdown
Contributor

Summary

Adds new vehicle_crew table to support multiple crew members per vehicle/trip, including mid-trip reliefs. This addresses the limitation where trips_performed.operator_id could only reference a single operator.

Resolves #220

Changes

  • spec/vehicle_crew.schema.json (new) defines the vehicle_crew table with:
    • Primary key: [service_date, trip_id_performed, crew_id, start_time]
    • Required fields: service_date, vehicle_id, crew_id, start_time
    • Optional fields: trip_id_performed (for vehicle-level assignments), crew_role, end_time
    • crew_role enum: operator, conductor, fare_inspector, other (uses snake_case consistent with 🐛📄 – Improve event_type naming convention in passenger_events #235)
    • Foreign references to trips_performed, vehicles, and operators
  • samples/template/TIDES/vehicle_crew.csv (new) provides header-only template
  • spec/trips_performed.schema.json updated operator_id description to clarify optional usage and reference to vehicle_crew table for multi-operator scenarios
  • spec/tides-datapackage-profile.json added vehicle_crew to tides-table enum
  • samples/template/TIDES/datapackage.json added vehicle_crew resource entry
  • CHANGELOG.md added entries under [Unreleased] for new table and description change

Reason for this change

Rail systems commonly have multiple crew members (operators, conductors) on a single trip, and operator reliefs mid-trip are standard practice. The current trips_performed.operator_id field can only reference one operator, forcing agencies to either lose crew data or pick an arbitrary operator to record.

The new vehicle_crew table allows agencies to capture complete crew assignment history while keeping the existing operator_id field for simple single-operator cases.

- See related discussion in Issue #220 and Fall 2025 TIDES Issues Working Group notes from December 1 and December 10.

Review checklist

Per change management policy, the following must be met before feature branch changes can merge to develop branch:

  • All JSON files validate
  • Reviewed and approved by 2+ contributors or board members

Community review status (updated August 27, 2026)

How community review works: Per the TIDES Change Management Policy, a proposal moves forward once at least three TIDES Contributors outside the originating working group publicly comment with a score: Accepted, Accepted with minor changes, or Substantially revised. A few sentences with your read of the proposal is a complete review.

Originating working group (Fall 2025 Issues Working Group, December 1 and 10, 2025 sessions): Christopher Yamas, Gabriel Sánchez Martínez, Ian Thistle, Jay Gordon, John Levin, Joey Reid, Spenser Sutinen. Their work is reflected in the proposal itself; community review comes from Contributors beyond this group.

Review so far: Laurie Merrell (@laurie-jarvus) and @jabhij have posted scored reviews (Accepted; Accepted with minor changes, with clarifications answered in the thread). One more review from a Contributor outside the working group completes community review.

Community review remains open, and reviews are welcome while we finalize v2.0. If you have not yet weighed in, a short comment closing with where you land (Accepted / Accepted with minor changes / Substantially revised) is all we need.

@chrisyamas chrisyamas added this to the v2.0 milestone Dec 29, 2025
@chrisyamas chrisyamas self-assigned this Dec 29, 2025
@chrisyamas chrisyamas added the 🚀 feature Adds a new feature - to spec or code label Dec 29, 2025
@chrisyamas
chrisyamas requested a review from a team as a code owner December 29, 2025 16:14
@chrisyamas chrisyamas added the 📄 spec Pertains to the specification itself label Dec 29, 2025
@chrisyamas
chrisyamas requested a review from a team as a code owner December 29, 2025 16:14
@chrisyamas chrisyamas added restructuring For issues such as adding or removing tables, making significant chages to a table, etc. 🔄 normative change A normative change requires approval of TIDES Board labels Dec 29, 2025
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

Data Validation Report

Sample Status
./samples/template/TIDES ⚠️

@github-actions

Copy link
Copy Markdown
Contributor

Data Validation Report

Sample Status
./samples/template/TIDES ⚠️

@chrisyamas

Copy link
Copy Markdown
Contributor Author

Data Validation Report

Sample Status
./samples/template/TIDES ⚠️

This warning is because the frictionless validation check can't find the vehicle_crew.schema.json since it checks against main branch and the schema for the new table doesn't exist on main branch yet. But this should resolve automatically once the PR is merged.

@chrisyamas
chrisyamas changed the base branch from main to develop January 2, 2026 16:04

@botanize botanize left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe this meets the needs discussed in the issue. However, it looks like this PR accidentally removes trip_id_performed from the trips_performed table. I also suspect that trip_id_performed should be required if it's part of the primary key. Though to be fair, it doesn't strictly need to be, service_date, crew_id and start_time should be sufficient for the primary key. Including trip_id_performed just makes it easier to use.

  • undo removal of trips_performed.trip_id_performed

Comment thread spec/trips_performed.schema.json
Comment thread spec/vehicle_crew.schema.json Outdated
Comment thread CHANGELOG.md Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Data Validation Report

Sample Status
./samples/template/TIDES ⚠️

@chrisyamas chrisyamas mentioned this pull request Jul 30, 2026
2 tasks

@laurie-jarvus laurie-jarvus left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Accepted

@jabhij

jabhij commented Aug 27, 2026

Copy link
Copy Markdown

Accepted with minor changes

I think this is a useful addition and addresses the core limitation identified in #220: trips_performed.operator_id cannot adequately represent multiple crew members or mid-trip reliefs. The use of start_time/end_time also gives the model the temporal granularity needed for relief scenarios.

I have a few points that I think are worth clarifying before finalizing the schema:

  1. crew_id vs. operators -- crew_role allows operator, conductor, fare_inspector, and other, but crew_id currently references operators.operator_id, while the operators table is defined specifically as personnel who operate vehicles. If vehicle_crew is intended to represent all crew, should the referenced entity be broader than operators, or should the specification explicitly require all crew members to be represented in operators regardless of role?

  2. Vehicle/trip consistency -- because both vehicle_id and (service_date, trip_id_performed) are stored, the schema can theoretically contain a vehicle_crew record whose vehicle_id differs from trips_performed.vehicle_id. If that is intentional to support vehicle changes during a trip, I think the documentation should state that explicitly. If not, it would be useful to define the expected consistency relationship.

  3. Temporal semantics -- since mid-trip relief is a primary use case, I would recommend documenting the expected temporal rules for start_time/end_time, particularly whether end_time is exclusive, whether end_time >= start_time is required, and how overlapping crew assignments should be interpreted.

(Kindly consider these mostly as semantic/integrity clarifications rather than objections to the overall approach.)

@jlstpaul

Copy link
Copy Markdown
Contributor

Thank you @jabhij for the great comments/questions. Here are my thoughts:

  • crew_id vs. operators -- crew_role allows operator, conductor, fare_inspector, and other, but crew_id currently references operators.operator_id, while the operators table is defined specifically as personnel who operate vehicles. If vehicle_crew is intended to represent all crew, should the referenced entity be broader than operators, or should the specification explicitly require all crew members to be represented in operators regardless of role?

We should probably update the name of the operators table to crew table. And we should add a crew_type field to that table. I appreciate others' thoughts on that. (And it will probably require start_date and end_date fields so that individual crew members can change roles over time but retain the same identifier.). To be honest, the current operators table has really just been a placeholder that we knew was going to be expanded upon eventually.

  • Vehicle/trip consistency -- because both vehicle_id and (service_date, trip_id_performed) are stored, the schema can theoretically contain a vehicle_crew record whose vehicle_id differs from trips_performed.vehicle_id. If that is intentional to support vehicle changes during a trip, I think the documentation should state that explicitly. If not, it would be useful to define the expected consistency relationship.

My understanding is that a trip that is performed by multiple vehicles (e.g., vehicle switch or doubled up) should be represented by multiple trips_performed records. In that case, there should be a rule that trips_performed.vehicle_id is the same as vehicle_crew.vehicle_id for the same trips or trip segments.

  • Temporal semantics -- since mid-trip relief is a primary use case, I would recommend documenting the expected temporal rules for start_time/end_time, particularly whether end_time is exclusive, whether end_time >= start_time is required, and how overlapping crew assignments should be interpreted.

I don't have an opinion on whether end_time is exclusive. My assumption would be that it is. I do think that end_time should be >= start_time.

Does overlapping crew assignments mean that same crew_id is found on two different vehicles at the same time? That probably shouldn't be allowed...

@jabhij

jabhij commented Aug 27, 2026

Copy link
Copy Markdown

Thank you @jlstpaul for the thoughtful response. I agree with the direction, especially treating operators as a placeholder that can evolve into a broader crew entity.

A few follow-up thoughts:

  1. For the proposed crew_type in the broader crew table, I think it may be useful to distinguish that from vehicle_crew.crew_role. My interpretation would be that crew_type describes the person's classification/role in the crew master data, while crew_role describes the role they performed for that particular vehicle/trip assignment. If that distinction is intended, documenting it could help avoid ambiguity and potential redundancy.

  2. I agree with representing a vehicle switch/doubling as separate trips_performed records. In that case, it may be useful to explicitly document the integrity relationship that vehicle_crew.vehicle_id must match the corresponding trips_performed.vehicle_id for the same performed trip/segment. It would also be helpful to clarify whether trip_id_performed is intended to uniquely identify that vehicle-specific performed trip/segment.

  3. On the temporal side, I agree that end_time >= start_time should be required, and I would also lean toward treating end_time as exclusive. For overlapping assignments, I think the rule may need to be defined at the crew_id level. For example, the same crew member should generally not be assigned to two different vehicles during overlapping intervals, whereas overlapping records for the same vehicle may be legitimate depending on the crew roles. Clarifying this distinction would make the temporal behavior easier for implementers to interpret consistently.

Overall, I think these clarifications would make the intended relationships and temporal semantics much clearer without changing the core approach.

@mpaine-act

Copy link
Copy Markdown

I noticed the use of the word crew while TODS uses employee. Does this make any difference to the spec?

@gabriel-korbato

Copy link
Copy Markdown
Contributor

@mpaine-act We considered "employee" and other words, but settled for "crew" because (1) it is shorter, (2) it is more specific to employees that perform functions in vehicles and stations (not administration), and (3) it could include contractors that are technically not employees.

@jlstpaul

Copy link
Copy Markdown
Contributor
  1. For the proposed crew_type in the broader crew table, I think it may be useful to distinguish that from vehicle_crew.crew_role. My interpretation would be that crew_type describes the person's classification/role in the crew master data, while crew_role describes the role they performed for that particular vehicle/trip assignment. If that distinction is intended, documenting it could help avoid ambiguity and potential redundancy.

@jabhij It was not my intent to differentiate crew_type from crew_role, so I would prefer to use the same crew_role field name if we do create a crew table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 feature Adds a new feature - to spec or code 🔄 normative change A normative change requires approval of TIDES Board restructuring For issues such as adding or removing tables, making significant chages to a table, etc. 📄 spec Pertains to the specification itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛📄 – TODS and TIDES Alignment: Mid-Trip Reliefs

8 participants