Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface alerts from trip informed entities #140

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
37 changes: 22 additions & 15 deletions api/public.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
The public API is Transiter's main API and
is used to query transit data from Transiter.
It's a read-only API and designed to be reachable from the internet.

Transiter's other API is the private [admin API](admin.md) which is used to manage the Transiter deployment.

The public API is based on the following resource hierarchy:

```
System
|- Agency
Expand All @@ -19,23 +19,23 @@
|- Transfer
|- Vehicle
```

For each resource there is a protobuf message type, a list endpoint, and a get endpoint.
In the HTTP API, the structure of the response is based on the protobuf message type.

The URLs in the HTTP API are determined by the resource hierarchy; thus:

- List all systems has URL `/systems`,
- Get system with ID `<system_id>` has URL `/systems/<system_id>`,
- List all routes in the system has URL `/systems/<system_id>/routes`,
- Get route has URL `/systems/<system_id>/routes/<route_id>`,

and so on.

The following table summarizes all of the resources and their types.
The right-most column describes the _source_ of the resource.
The public API is a read-only API so all of the resources come from somewhere else.

| Resource | List endpoint | Get endpoint | Source |
| --------------------- | --------------------------------------------------- | ----------------------------------------------- |----------------------|
| [Agency](#agency) | [ListAgencies](public_endpoints.md#list-agencies) | [GetAgency](public_endpoints.md#get-agency) | GTFS static |
Expand All @@ -48,7 +48,7 @@
| [Transfer](#transfer) | [ListTransfers](public_endpoints.md#list-transfers) | [GetTransfer](public_endpoints.md#get-transfer) | GTFS static |
| [Trip](#trip) | [ListTrips](public_endpoints.md#list-trips) | [GetTrip](public_endpoints.md#get-trip) | GTFS realtime |
| [Vehicle](#vehicle) | [ListVehicles](public_endpoints.md#list-vehicles) | [GetVehicle](public_endpoints.md#get-vehicle) | GTFS realtime |

Many resources refer to other resources across the hierarchy.
For example, each route has an agency it is attached to.
Each stop has a list of service maps, and each service map contains a set of routes.
Expand All @@ -59,7 +59,7 @@
However they also contain additional information that is considered generally useful.
For example, the [Stop.Reference](#stopreference) message contains the stop's name.
What counts as "considered generally" is obviously subjective and open to change.

*/
syntax = "proto3";

Expand Down Expand Up @@ -274,7 +274,7 @@ message EntrypointReply {
// Message containing version information about a Transiter binary.
message TransiterDetails {
reserved 2;

// The version of the Transiter binary this instance is running.
string version = 1;
// URL of the Transiter GitHub repository.
Expand All @@ -283,7 +283,7 @@ message EntrypointReply {
// Message containing information about a specific Transiter CI build.
message Build {
reserved 7;

// The GitHub build number.
string number = 3;
// Time the binary was built, in the form of a human readable string.
Expand Down Expand Up @@ -377,7 +377,7 @@ message ListStopsRequest {

// If true, only return stops whose types are specified in the repeated `type` field.
bool filter_by_type = 16;
// Types to filter by if `filter_by_type` is set to true.
// Types to filter by if `filter_by_type` is set to true.
// It is an error to populate this field if `filter_by_id` is false.
repeated Stop.Type type = 17;

Expand Down Expand Up @@ -988,6 +988,13 @@ message Trip {
// Shape of the trip.
optional Shape.Reference shape = 8;

// Active alerts for this trip.
//
// These are determined using the `informed_entity` field in
// the [GTFS realtime alerts
// message](https://gtfs.org/realtime/feed-entities/service-alerts/#service-alerts).
repeated Alert.Reference alerts = 9;

// Reference type for the trip resource.
message Reference {
// Same as the parent message.
Expand Down Expand Up @@ -1236,10 +1243,10 @@ message Feed {

// Unix milliseconds timestamp of when the last successful update of this feed finished.
optional int64 last_successful_update_ms = 5;

// Unix milliseconds timestamp of when the last skipped update of this feed finished.
optional int64 last_skipped_update_ms = 6;

// Unix milliseconds timestamp of when the last failed update of this feed finished.
optional int64 last_failed_update_ms = 7;

Expand Down
24 changes: 22 additions & 2 deletions db/queries/alert_queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ INSERT INTO alert_stop (alert_pk, stop_pk) VALUES (sqlc.arg(alert_pk), sqlc.arg(
INSERT INTO alert_route (alert_pk, route_pk) VALUES (sqlc.arg(alert_pk), sqlc.arg(route_pk));

-- name: InsertAlertTrip :exec
INSERT INTO alert_trip (alert_pk, trip_pk, scheduled_trip_pk) VALUES (sqlc.arg(alert_pk), sqlc.narg(trip_pk), sqlc.narg(scheduled_trip_pk));
INSERT INTO alert_trip (alert_pk, trip_pk, scheduled_trip_pk, route_pk, direction_id, start_date, start_time) VALUES (sqlc.arg(alert_pk), sqlc.narg(trip_pk), sqlc.narg(scheduled_trip_pk), sqlc.narg(route_pk), sqlc.narg(direction_id), sqlc.narg(start_date), sqlc.narg(start_time));

-- name: InsertAlertRouteType :exec
INSERT INTO alert_route_type (alert_pk, route_type) VALUES (sqlc.arg(alert_pk), sqlc.arg(route_type));
Expand Down Expand Up @@ -114,6 +114,26 @@ WHERE stop.pk = ANY(sqlc.arg(stop_pks)::bigint[])
)
ORDER BY alert.id ASC;

-- name: ListActiveAlertsForTrips :many
SELECT trip.pk trip_pk, alert.pk, alert.id, alert.cause, alert.effect, alert_active_period.starts_at, alert_active_period.ends_at
FROM trip
-- TODO (1): Trip start needs to be considered when matching trips to alerts to disambigute trips that run over multiple days.
-- TODO (2): Frequency based trips are not correctly handled here.
INNER JOIN alert_trip ON alert_trip.trip_pk = trip.pk OR
(alert_trip.trip_pk IS NULL AND alert_trip.route_pk = trip.route_pk AND (alert_trip.direction_id IS NULL OR alert_trip.direction_id = trip.direction_id))
INNER JOIN alert ON alert_trip.alert_pk = alert.pk
INNER JOIN alert_active_period ON alert_active_period.alert_pk = alert.pk
WHERE trip.pk = ANY(sqlc.arg(trip_pks)::bigint[])
AND (
alert_active_period.starts_at < sqlc.arg(present_time)
OR alert_active_period.starts_at IS NULL
)
AND (
alert_active_period.ends_at > sqlc.arg(present_time)
OR alert_active_period.ends_at IS NULL
)
ORDER BY alert.id ASC;

-- name: ListAlertsWithActivePeriodsAndAllInformedEntities :many
SELECT alert.id,
alert.cause,
Expand Down Expand Up @@ -154,7 +174,7 @@ FROM alert
LEFT JOIN alert_stop ON alert.pk = alert_stop.alert_pk
LEFT JOIN stop ON alert_stop.stop_pk = stop.pk
LEFT JOIN alert_trip ON alert.pk = alert_trip.alert_pk
LEFT JOIN trip ON alert_trip.trip_pk = trip.pk
LEFT JOIN trip ON alert_trip.trip_pk = trip.pk OR (alert_trip.trip_pk IS NULL AND alert_trip.route_pk = trip.route_pk AND (alert_trip.direction_id IS NULL OR alert_trip.direction_id = trip.direction_id))
LEFT JOIN scheduled_trip ON alert_trip.scheduled_trip_pk = scheduled_trip.pk
LEFT JOIN alert_route_type ON alert.pk = alert_route_type.alert_pk
WHERE alert.system_pk = sqlc.arg(system_pk)
Expand Down
11 changes: 11 additions & 0 deletions db/schema/011_alert_trip_informed_entity_update.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ALTER TABLE alert_trip
ADD COLUMN route_pk BIGINT REFERENCES route(pk) ON DELETE SET NULL;

ALTER TABLE alert_trip
ADD COLUMN direction_id boolean;

ALTER TABLE alert_trip
ADD COLUMN start_date timestamp with time zone;

ALTER TABLE alert_trip
ADD COLUMN start_time int;
1 change: 1 addition & 0 deletions docs/src/api/public_resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ specification](https://gtfs.org/realtime/reference/#message-tripupdate).
| direction_id | bool | Direction ID of the trip.
| stop_times | [StopTime](public_resources.md#stoptime) | Stop times of the trip.
| shape | [Shape.Reference](public_resources.md#shapereference) | Shape of the trip.
| alerts | [Alert.Reference](public_resources.md#alertreference) | Active alerts for this trip.<br /><br />These are determined using the `informed_entity` field in the [GTFS realtime alerts message](https://gtfs.org/realtime/feed-entities/service-alerts/#service-alerts).



Expand Down
Loading
Loading