Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions API_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Check back here regularly to stay ahead of removals.

| Announced | What? | Safe until | PR |
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|---------------------------------------------------------------|
| 2026-04-01 | `DepartureResource.stop.*` is deprecated → use `DepartureResource.station` instead | 2026-09-30 | [#4663](https://github.com/Traewelling/traewelling/pull/4663) |
| 2026-04-07 | `OperatorResource.id` is deprecated as integer: will become a UUID after 2026-09-30. prefer `uuid` instead while migration-period | 2026-09-30 | [#4676](https://github.com/Traewelling/traewelling/pull/4676) |
| 2026-05-14 | `POST /api/v1/trains/checkin` 409 response: `message.status_id` and `message.lineName` are deprecated. Use `data.conflicts` (full `StatusResource` array) instead | 2026-10-31 | [#4677](https://github.com/Traewelling/traewelling/pull/4677) |
| 2026-07-19 | `StopoverResource.id` is deprecated as station ID: it currently holds the station ID (not unique within a trip). Use `station` for station details. After the safe-until date `id` is repurposed to the unique stopover ID | 2026-11-30 | [#4959](https://github.com/Traewelling/traewelling/pull/4959) |
Expand All @@ -34,7 +33,8 @@ Removed the following deprecated fields, announced in 2026-03 and 2026-04:
- `DepartureResource.destination`: use `direction` instead
- `DepartureResource.line.productName`: use `line.name` instead
- `DepartureResource.provenance`, `remarks`, `origin`, `currentTripPosition`, `loadFactor` and `line.operator`: were always `null`
- `DepartureResource.stop.products`, `line.public` and `line.adminCode`: were always placeholder values
- `DepartureResource.line.public` and `line.adminCode`: were always placeholder values
- `DepartureResource.stop`: use `station` instead
- `CheckinSuccessResource.points.additional` (`POST /trains/checkin`): was always `null`
- `WebhookResource.clientId` (`/webhooks`): use `client.id` instead
- `WebhookResource.userId` (`/webhooks`): use `user.id` instead
Expand Down
36 changes: 1 addition & 35 deletions app/Http/Resources/DepartureResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,15 @@
namespace App\Http\Resources;

use App\Dto\Internal\Departure;
use App\Enum\StationIdentifierType;
use Illuminate\Http\Resources\Json\JsonResource;
use OpenApi\Attributes as OA;

#[OA\Schema(
title: 'Departure',
description: 'A single departure at a station',
required: ['tripId', 'stop', 'when', 'plannedWhen', 'platform', 'plannedPlatform', 'direction', 'line', 'cancelled', 'station'],
required: ['tripId', 'when', 'plannedWhen', 'platform', 'plannedPlatform', 'direction', 'line', 'cancelled', 'station'],
properties: [
new OA\Property(property: 'tripId', description: 'Unique trip identifier', type: 'string', example: '1|200513|0|81|6012023'),
new OA\Property(
property: 'stop',
description: 'The stop at which this departure occurs',
properties: [
new OA\Property(property: 'type', type: 'string', example: 'stop', deprecated: true),
new OA\Property(property: 'id', description: 'Träwelling internal station ID', type: 'integer', example: 5181, deprecated: true),
new OA\Property(property: 'name', type: 'string', example: 'Karlsruhe Hbf', deprecated: true),
new OA\Property(
property: 'location',
properties: [
new OA\Property(property: 'type', type: 'string', example: 'location', deprecated: true),
new OA\Property(property: 'id', description: 'IBNR identifier (if available)', type: 'string', example: '8000191', nullable: true, deprecated: true),
new OA\Property(property: 'latitude', type: 'number', format: 'float', example: 48.993207, deprecated: true),
new OA\Property(property: 'longitude', type: 'number', format: 'float', example: 8.400977, deprecated: true),
],
type: 'object',
deprecated: true,
),
],
type: 'object',
deprecated: true,
),
new OA\Property(property: 'when', description: 'Actual departure time (null if no realtime data)', type: 'string', format: 'date-time', example: '2023-01-06T13:49:00+01:00', nullable: true),
new OA\Property(property: 'plannedWhen', description: 'Scheduled departure time', type: 'string', format: 'date-time', example: '2023-01-06T13:49:00+01:00'),
new OA\Property(property: 'platform', description: 'Actual platform (null if no realtime data)', type: 'string', example: '3a', nullable: true),
Expand Down Expand Up @@ -69,17 +46,6 @@ public function toArray($request): array
{
return [
'tripId' => $this->resource->trip->tripId,
'stop' => [ // @deprecated - remove after 2026-09-30, use station instead
'type' => 'stop',
'id' => $this->resource->station->id,
'name' => $this->resource->station->name,
'location' => [
'type' => 'location',
'id' => $this->resource->station->getIdentifier(StationIdentifierType::DE_DB_IBNR)?->identifier,
'latitude' => $this->resource->station->latitude,
'longitude' => $this->resource->station->longitude,
],
],
'when' => $this->resource->realDeparture?->toIso8601String(),
'plannedWhen' => $this->resource->plannedDeparture->toIso8601String(),
'platform' => $this->resource->realPlatform,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ const platform = computed((): string | null => props.item.platform ?? props.item
{{ item.direction }}
</p>
<p
v-if="stationName && item.stop?.name && item.stop.name !== stationName"
v-if="stationName && item.station?.name && item.station.name !== stationName"
class="text-xs text-base-content/50 italic truncate"
>
{{ trans('stationboard.dep') }} {{ item.stop.name }}
{{ trans('stationboard.dep') }} {{ item.station.name }}
</p>
</div>

Expand Down
22 changes: 11 additions & 11 deletions resources/tailwind-app/pages/Stationboard/Stationboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,20 @@ function fetchNext(): void {
fetchDepartures(next ?? fetchTime.value.plus({ minutes: 15 }).toISO() ?? undefined);
}

function openLineRun(train: DepartureResource): void {
function openLineRun(departure: DepartureResource): void {
router.push({
name: 'line-run',
query: {
tripId: train.tripId,
lineName: train.line?.name ?? train.line?.fahrtNr,
startId: train.stop?.id,
plannedWhen: train.plannedWhen,
direction: train.direction,
originName: train.stop?.name,
product: train.line?.product ?? undefined,
mode: train.line?.mode ?? undefined,
color: train.line?.color ?? undefined,
textColor: train.line?.textColor ?? undefined,
tripId: departure.tripId,
lineName: departure.line?.name ?? departure.line?.fahrtNr,
startId: departure.station?.id,
plannedWhen: departure.plannedWhen,
direction: departure.direction,
originName: departure.station?.name,
product: departure.line?.product ?? undefined,
mode: departure.line?.mode ?? undefined,
color: departure.line?.color ?? undefined,
textColor: departure.line?.textColor ?? undefined,
},
});
}
Expand Down
48 changes: 0 additions & 48 deletions resources/types/Api.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1302,54 +1302,6 @@ export interface DepartureResource {
* @example "1|200513|0|81|6012023"
*/
tripId: string;
/**
* The stop at which this departure occurs
* @deprecated
*/
stop: {
/**
* @deprecated
* @example "stop"
*/
type?: string;
/**
* Träwelling internal station ID
* @deprecated
* @example 5181
*/
id?: number;
/**
* @deprecated
* @example "Karlsruhe Hbf"
*/
name?: string;
/** @deprecated */
location?: {
/**
* @deprecated
* @example "location"
*/
type?: string;
/**
* IBNR identifier (if available)
* @deprecated
* @example "8000191"
*/
id?: string | null;
/**
* @deprecated
* @format float
* @example 48.993207
*/
latitude?: number;
/**
* @deprecated
* @format float
* @example 8.400977
*/
longitude?: number;
};
};
/**
* Actual departure time (null if no realtime data)
* @format date-time
Expand Down
25 changes: 0 additions & 25 deletions resources/types/Departure.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export type departureEntry = {
tripId: string;
stop: HafasStop;
when: string | null;
plannedWhen: string | null;
platform: string | null;
Expand Down Expand Up @@ -31,27 +30,3 @@ export type HafasLine = {
mode: any; // eslint-disable-line @typescript-eslint/no-explicit-any
product: any; // eslint-disable-line @typescript-eslint/no-explicit-any
};

export type HafasStop = {
type: string;
id: string;
name: string;
location: HafasLocation;
station: HafasStation;
};
export type HafasStation = {
type: string;
id: string;
name: string;
location: HafasLocation;
products: {
[key: string]: boolean;
};
};

export type HafasLocation = {
type: string;
id: string;
latitude: number;
longitude: number;
};
10 changes: 5 additions & 5 deletions resources/vue/components/Checkin/CheckinInterface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
type: Object,
required: true,
},
selectedTrain: {
selectedDeparture: {
type: Object,
required: true,
},
Expand Down Expand Up @@ -93,11 +93,11 @@ export default {
visibility: this.visibility,
business: this.business,
ibnr: false,
tripId: this.selectedTrain.tripId,
lineName: this.selectedTrain.line.name ?? this.selectedTrain.line.fahrtNr,
start: this.selectedTrain.stop.id,
tripId: this.selectedDeparture.tripId,
lineName: this.selectedDeparture.line.name ?? this.selectedDeparture.line.fahrtNr,
start: this.selectedDeparture.station.id,
destination: this.selectedDestination.id,
departure: DateTime.fromISO(this.selectedTrain.plannedWhen).setZone('UTC').toISO(),
departure: DateTime.fromISO(this.selectedDeparture.plannedWhen).setZone('UTC').toISO(),
arrival: DateTime.fromISO(this.selectedDestination.arrivalPlanned).setZone('UTC').toISO(),
force: this.collision,
eventId: this.selectedEvent ? this.selectedEvent.id : null,
Expand Down
4 changes: 2 additions & 2 deletions resources/vue/components/Checkin/StationBoardEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ function normalizeLineName(name: string | null): string {
<div>
<span class="fw-bold fs-6">{{ item.direction }}</span
><br />
<span v-if="item.stop.name !== station.name" class="text-muted small font-italic">
{{ trans('stationboard.dep') }} {{ item.stop.name }}
<span v-if="item.station.name !== station.name" class="text-muted small font-italic">
{{ trans('stationboard.dep') }} {{ item.station.name }}
</span>
</div>
</div>
Expand Down
14 changes: 7 additions & 7 deletions resources/vue/components/CheckinLineRun.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default {
name: 'CheckinLineRun',
components: { LoadingSkeletonRows },
props: {
selectedTrain: {
selectedDeparture: {
type: Object,
required: true,
},
Expand All @@ -32,7 +32,7 @@ export default {
};
},
watch: {
selectedTrain() {
selectedDeparture() {
this.getLineRun();
},
},
Expand All @@ -48,9 +48,9 @@ export default {
this.loading = true;

const params = new URLSearchParams({
hafasTripId: this.$props.selectedTrain.tripId,
lineName: this.$props.selectedTrain.line.name,
start: this.$props.selectedTrain.stop.id,
hafasTripId: this.$props.selectedDeparture.tripId,
lineName: this.$props.selectedDeparture.line.name,
start: this.$props.selectedDeparture.station.id,
});
fetch(`/api/v1/trains/trip?${params.toString()}`)
.then((response) => {
Expand All @@ -61,9 +61,9 @@ export default {
}
response.json().then((result) => {
this.lineRun = result.data;
const givenDeparture = DateTime.fromISO(this.$props.selectedTrain.plannedWhen);
const givenDeparture = DateTime.fromISO(this.$props.selectedDeparture.plannedWhen);
const startIndex = this.lineRun.stopovers.findIndex((item) => {
if (Number(item.id) !== Number(this.$props.selectedTrain.stop.id)) {
if (Number(item.id) !== Number(this.$props.selectedDeparture.station.id)) {
return false;
}
const dep = item.departurePlanned
Expand Down
Loading
Loading