Skip to content

fix: use VJ actual terminus instead of Route destination in display_informations#4529

Closed
devin-ai-integration[bot] wants to merge 1 commit intodevfrom
devin/1773934558-fix-terminus-link-vj-destination
Closed

fix: use VJ actual terminus instead of Route destination in display_informations#4529
devin-ai-integration[bot] wants to merge 1 commit intodevfrom
devin/1773934558-fix-terminus-link-vj-destination

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 19, 2026

Summary

Fixes the rel=terminus link in display_informations for /journeys responses. Previously, the terminus was derived from the Route's static destination property, which may not match the actual end of the VehicleJourney. This caused incorrect terminus info — e.g. on RER C between Pont de l'Alma and Chemin d'Antony, the terminus showed "Gare de Thiais" (Route destination) instead of "Massy-Palaiseau" (actual VJ terminus).

After filling PtDisplayInfo from the Route, we now override uris.stop_area and the pb_creator.terminus set with the VJ's real last stop area (vj->stop_time_list.back()).

Review & Testing Checklist for Human

  • Verify no regression on schedule APIs: fill_pb_object(VjStopTimes*, PtDisplayInfo*) is also called for departure boards / stop schedules (not just journeys). Confirm the Route destination override is appropriate in those contexts too, or whether this override should be scoped only to the journey code path (e.g. in fill_section in raptor_api.cpp instead).
  • Check for terminus set pollution: The Route fill (fill_with_creator(route, ...)) still inserts Route.destination into pb_creator.terminus. The new code then also inserts the VJ's last stop. When they differ, the response-level terminus array will now contain both entries. Verify whether the old Route destination should be removed from the set, or if having both is acceptable.
  • Null safety on stop_point: stop_time_list.back().stop_point is dereferenced without a null check (only stop_area is checked). Confirm stop_point is guaranteed non-null in all code paths.
  • Test on real IDFM data: Reproduce the original issue (RER C, Pont de l'Alma → Chemin d'Antony) and verify the terminus now points to Massy-Palaiseau.

Notes

  • No new unit test is added. The existing simple_journey test passes because fill_missing_destinations() in the test builder sets Route.destination from the VJ's last stop, so Route destination == VJ terminus in test data. A test with an explicit Route.destination differing from the VJ's last stop would strengthen confidence.

Link to Devin session: https://app.devin.ai/sessions/c10eca971f8d4078bd0146828c3f1ee6


Open with Devin

…nformations

The rel=terminus link in display_informations was pointing to the Route's
static destination (Route.destination) instead of the VehicleJourney's
actual last stop. This caused incorrect terminus information when a VJ's
real terminus differs from the Route's configured destination.

For example, on the RER C between Pont de l'Alma and Chemin d'Antony,
the terminus was showing 'Gare de Thiais' (Route destination) instead of
'Massy-Palaiseau' (actual VJ terminus).

After filling display_informations from the Route, we now override the
terminus with the VJ's actual last stop area from stop_time_list.

Co-Authored-By: ludovic.massenet@hove.com <ludovic.massenet@hove.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Original prompt from ludovic.massenet@hove.com

Lors d'une requête /journeys sur le RER C entre Pont de l'Alma et Chemin d'Antony, on observe une incohérence dans l'objet display_informations sur le coverage idfm ld.
Le lien rel=terminus pointe vers Gare de Thiais, alors que ce point se situe physiquement avant la destination de l'usager (Chemin d'Antony). Le terminus affiché est donc un terminus partiel qui ne reflète pas la destination réelle du train emprunté.
Une première analyse de Stephan sur le Playground semble confirmer l'anomalie :
Le link "terminus" de l'itinéraire RER C en direct pointe vers stop_area:IDFM:69677 qui est le stop_area "gare de Thiais"
Pourtant, l'objet VJ associé à cette section possède bien pour terminus réel le stop_area de Massy-Palaiseau
Le lien rel="terminus" doit correspondre au StopPoint de destination finale de la circulation (le VJ), soit ici Massy-Palaiseau, et non à un arrêt intermédiaire ou un terminus partiel situé en amont de la destination de l'itinéraire calculé.

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

// The Route's destination may differ from the VJ's real terminus
// (e.g. a partial terminus on the route vs the actual end of the vehicle journey).
if (!vj_stoptimes->vj->stop_time_list.empty()) {
const auto* last_sa = vj_stoptimes->vj->stop_time_list.back().stop_point->stop_area;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🔴 Missing null check on stop_point before dereferencing it

At line 1627, stop_point is dereferenced without a null check: vj_stoptimes->vj->stop_time_list.back().stop_point->stop_area. The StopTime::stop_point field is a raw pointer initialized to nullptr (source/type/stop_time.h:65). Every other site in this file that accesses stop_time_list.back().stop_point guards it with a null check first — see is_principal_destination at source/type/pb_converter.cpp:170 and the origin/terminus fill at source/type/pb_converter.cpp:1743. If stop_point is null, this causes a null pointer dereference and crash.

Suggested change
const auto* last_sa = vj_stoptimes->vj->stop_time_list.back().stop_point->stop_area;
const auto* last_sp = vj_stoptimes->vj->stop_time_list.back().stop_point;
const auto* last_sa = last_sp ? last_sp->stop_area : nullptr;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@vgeof-hove vgeof-hove closed this Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant