├── .env.example ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .shiftrc ├── LICENSE ├── _ide_helper.php ├── _ide_helper_models.php ├── app ├── Actions │ ├── HandleExpiredGtfs.php │ └── HandleExpiredRealtimeData.php ├── CacheHasher │ └── HasherWithoutHost.php ├── CacheProfiles │ └── LocalizationProfile.php ├── Checks │ └── AgenciesUpdatedCheck.php ├── Console │ ├── Commands │ │ ├── RealtimeData │ │ │ └── Update.php │ │ ├── StaticData │ │ │ └── Update.php │ │ └── Vin │ │ │ └── DecodeVins.php │ └── Kernel.php ├── Enums │ ├── AgencyFeature.php │ ├── CongestionLevel.php │ ├── OccupancyStatus.php │ ├── ScheduleRelationship.php │ ├── TagType.php │ ├── VehicleStopStatus.php │ └── VehicleType.php ├── Events │ ├── ElectricStmVehicleUpdated.php │ ├── NotificationUserCreated.php │ ├── TagCreated.php │ ├── TagUpdated.php │ ├── VehicleCreated.php │ ├── VehicleCreating.php │ ├── VehicleForceRefAdded.php │ ├── VehicleUpdated.php │ ├── VehiclesUpdated.php │ └── Vin │ │ └── SuggestionCreated.php ├── Exceptions │ └── Handler.php ├── Filament │ ├── Resources │ │ ├── AgencyResource.php │ │ ├── AgencyResource │ │ │ ├── Pages │ │ │ │ ├── CreateAgency.php │ │ │ │ ├── EditAgency.php │ │ │ │ └── ListAgencies.php │ │ │ └── RelationManagers │ │ │ │ ├── LinksRelationManager.php │ │ │ │ └── RegionsRelationManager.php │ │ ├── AlertResource.php │ │ ├── AlertResource │ │ │ └── Pages │ │ │ │ ├── CreateAlert.php │ │ │ │ ├── EditAlert.php │ │ │ │ └── ListAlerts.php │ │ ├── LinkResource.php │ │ ├── LinkResource │ │ │ ├── Pages │ │ │ │ ├── CreateLink.php │ │ │ │ ├── EditLink.php │ │ │ │ └── ListLinks.php │ │ │ └── RelationManagers │ │ │ │ └── VehiclesRelationManager.php │ │ ├── RegionResource.php │ │ ├── RegionResource │ │ │ ├── Pages │ │ │ │ ├── CreateRegion.php │ │ │ │ ├── EditRegion.php │ │ │ │ └── ListRegions.php │ │ │ └── RelationManagers │ │ │ │ └── AgenciesRelationManager.php │ │ ├── TagResource.php │ │ ├── TagResource │ │ │ ├── Pages │ │ │ │ ├── CreateTag.php │ │ │ │ ├── EditTag.php │ │ │ │ └── ListTags.php │ │ │ └── RelationManagers │ │ │ │ ├── AgenciesRelationManager.php │ │ │ │ └── VehiclesRelationManager.php │ │ ├── UserResource.php │ │ ├── UserResource │ │ │ └── Pages │ │ │ │ ├── CreateUser.php │ │ │ │ ├── EditUser.php │ │ │ │ └── ListUsers.php │ │ ├── VehicleResource.php │ │ └── VehicleResource │ │ │ ├── Pages │ │ │ ├── EditVehicle.php │ │ │ └── ListVehicles.php │ │ │ └── RelationManagers │ │ │ └── TagsRelationManager.php │ └── Widgets │ │ ├── VehiclesWithoutOperators.php │ │ └── WelcomeAdmin.php ├── Http │ ├── Controllers │ │ ├── Admin │ │ │ ├── AgencyController.php │ │ │ └── FailedJobController.php │ │ ├── Api │ │ │ └── V2 │ │ │ │ ├── AgencyController.php │ │ │ │ ├── AlertController.php │ │ │ │ ├── BlockController.php │ │ │ │ ├── LandingController.php │ │ │ │ ├── LinkController.php │ │ │ │ ├── NotificationsController.php │ │ │ │ ├── Push │ │ │ │ ├── ProfileController.php │ │ │ │ └── ProfileVehiclesController.php │ │ │ │ ├── RegionController.php │ │ │ │ ├── ShapeController.php │ │ │ │ ├── TagController.php │ │ │ │ └── VehicleController.php │ │ ├── Controller.php │ │ └── Vin │ │ │ ├── AgencyController.php │ │ │ ├── OperatorController.php │ │ │ ├── SuggestionController.php │ │ │ └── VehicleController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Authenticate.php │ │ ├── EncryptCookies.php │ │ ├── Localization.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ ├── VerifyCsrfToken.php │ │ └── WebLocalization.php │ └── Resources │ │ └── V2 │ │ ├── AgencyResource.php │ │ ├── AgencySimpleResource.php │ │ ├── AlertResource.php │ │ ├── BlockResource.php │ │ ├── GeoJsonLandingCollection.php │ │ ├── GeoJsonLandingResource.php │ │ ├── GeoJsonLandingVehicleCollection.php │ │ ├── GeoJsonLandingVehicleResource.php │ │ ├── GeoJsonShapeLineResource.php │ │ ├── GeoJsonShapeResource.php │ │ ├── GeoJsonShapeStopResource.php │ │ ├── GeoJsonVehicleResource.php │ │ ├── GeoJsonVehiclesCollection.php │ │ ├── LinkResource.php │ │ ├── LinkSimpleResource.php │ │ ├── NotificationUserResource.php │ │ ├── RegionResource.php │ │ ├── RegionSimpleResource.php │ │ ├── TagResource.php │ │ ├── TagSimpleResource.php │ │ ├── TripResource.php │ │ ├── VehiclePushResource.php │ │ ├── VehicleResource.php │ │ └── VehiclesGeoJson │ │ ├── VehicleResource.php │ │ └── VehiclesCollection.php ├── Jobs │ ├── CleanFolders.php │ ├── RealtimeData │ │ ├── CheckTimestamps.php │ │ ├── DispatchAgency.php │ │ ├── GtfsRtHandler.php │ │ ├── JavascriptGtfsRtHandler.php │ │ └── NextbusJsonHandler.php │ ├── StaticData │ │ ├── DownloadStatic.php │ │ ├── ExtractAndDispatchStaticGtfs.php │ │ ├── ProcessGtfsRoutes.php │ │ ├── ProcessGtfsServices.php │ │ ├── ProcessGtfsShapes.php │ │ ├── ProcessGtfsStopTimes.php │ │ ├── ProcessGtfsStops.php │ │ └── ProcessGtfsTrips.php │ ├── SyncIconToMapbox.php │ ├── Tags │ │ └── SyncTagsWithFleetStats.php │ └── Vin │ │ └── DecodeVin.php ├── Listeners │ ├── AddTagIconToMapbox.php │ ├── CreateVehicleForceLabel.php │ ├── DeactivateInactiveSubscription.php │ ├── DecodeVin.php │ ├── SendElectricStmNotification.php │ ├── SendNewVehicleNotification.php │ ├── SendNewVinSuggestionNotification.php │ ├── SendUpdatedVehicleNotification.php │ └── SendWelcomeNotification.php ├── Models │ ├── Agency.php │ ├── Alert.php │ ├── FailedJob.php │ ├── Gtfs │ │ ├── Route.php │ │ ├── Service.php │ │ ├── Shape.php │ │ ├── Stop.php │ │ ├── StopTime.php │ │ └── Trip.php │ ├── Link.php │ ├── NotificationUser.php │ ├── Region.php │ ├── Stat.php │ ├── Tag.php │ ├── User.php │ ├── Vehicle.php │ └── Vin │ │ ├── Information.php │ │ └── Suggestion.php ├── Notifications │ ├── DispatchFailed.php │ ├── NewVinSuggestion.php │ ├── Push │ │ ├── ElectricStmAppearance.php │ │ ├── NewVehicle.php │ │ ├── UpdatedVehicle.php │ │ └── Welcome.php │ ├── RealtimeDataExpired.php │ ├── StaticDataUpdated.php │ └── StaticGtfsExpired.php ├── Policies │ ├── AgencyPolicy.php │ ├── AlertPolicy.php │ ├── LinkPolicy.php │ ├── RegionPolicy.php │ ├── TagPolicy.php │ ├── UserPolicy.php │ └── VehiclePolicy.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── Filament │ │ └── AdminPanelProvider.php │ ├── HorizonServiceProvider.php │ ├── LadderServiceProvider.php │ ├── RouteServiceProvider.php │ └── TelescopeServiceProvider.php ├── Rules │ └── Turnstile.php └── View │ └── Components │ ├── Button │ └── Text.php │ ├── Dialog │ └── Basic.php │ ├── IconButton │ └── Standard.php │ └── Layout.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── cors.php ├── database.php ├── filament.php ├── filesystems.php ├── gravatar.php ├── hashing.php ├── health.php ├── hooks.php ├── horizon.php ├── image.php ├── log-viewer.php ├── logging.php ├── mail.php ├── prologue │ └── alerts.php ├── queue.php ├── responsecache.php ├── sanctum.php ├── schedule-monitor.php ├── scribe.php ├── sentry.php ├── services.php ├── session.php ├── telescope.php ├── transittracker.php ├── translatable.php ├── view.php └── webpush.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2019_06_25_194911_create_transit_tracker_tables.php │ ├── 2019_06_25_195404_create_failed_jobs_table.php │ ├── 2019_07_08_193557_add_text_color_and_timestamp_to_agencies_table.php │ ├── 2019_08_20_002346_add_tags_and_active_to_agencies_table.php │ ├── 2019_09_04_000038_create_stats_table.php │ ├── 2019_10_15_204754_update_agencies_table.php │ ├── 2019_10_15_205808_create_services_table.php │ ├── 2019_10_15_231316_add_service_id_to_trips_table.php │ ├── 2019_10_25_122725_update_alert_table.php │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ ├── 2020_01_23_005154_add_index_to_trips_table.php │ ├── 2020_02_01_235733_add_regions.php │ ├── 2020_03_03_004606_add_icon_to_vehicles_table.php │ ├── 2020_05_03_151057_create_failed_jobs_histories_table.php │ ├── 2020_05_21_133049_add_indexes_to_routes_and_services_tables.php │ ├── 2020_06_03_145821_change_region_realtime_options.php │ ├── 2020_06_08_154637_create_links_table.php │ ├── 2020_06_10_160927_change_alert_translatable_fields.php │ ├── 2020_07_08_183606_add_fields_to_vehicles_table.php │ ├── 2020_07_20_085647_add_shape_to_trips_table.php │ ├── 2020_07_22_095116_add_snooze_to_failed_job_histories_table.php │ ├── 2020_08_05_132648_add_license_field_to_agency_table.php │ ├── 2020_09_29_165446_add_support_for_batch_jobs.php │ ├── 2020_11_03_201053_add_refresh_is_active_field_to_agencies_table.php │ ├── 2020_11_05_180444_add_short_name_field_to_agencies_table.php │ ├── 2020_11_05_180459_add_multiple_regions_to_agencies_table.php │ ├── 2020_11_05_180511_add_cron_schedule_field_to_agencies_table.php │ ├── 2020_11_05_180531_add_actions_fields_to_alerts_table.php │ ├── 2020_11_05_180539_add_expiration_field_to_alerts_table.php │ ├── 2020_11_05_180548_add_image_field_to_alerts_table.php │ ├── 2020_11_05_181211_add_description_field_to_regions_table.php │ ├── 2020_11_06_120200_remove_conditions_and_map_fields_from_regions_table.php │ ├── 2021_04_01_192349_add_map_center_to_regions_table.php │ ├── 2021_04_01_195411_add_image_to_regions_table.php │ ├── 2021_04_03_142021_create_schedule_monitor_tables.php │ ├── 2021_04_03_172520_add_cities_field_to_agencies_table.php │ ├── 2021_04_03_191813_add_meta_description_to_regions_table.php │ ├── 2021_04_28_131515_add_force_label_to_vehicles_table.php │ ├── 2021_05_06_105155_change_column_type_of_icon_on_alerts_table.php │ ├── 2021_05_15_075131_create_job_batches_table.php │ ├── 2021_05_23_081606_add_etag_to_agencies_table.php │ ├── 2021_07_05_073230_create_vin_suggestions_table.php │ ├── 2021_07_20_080419_make_note_column_optional_in_vin_suggestions_table.php │ ├── 2021_10_12_165641_create_push_subscriptions_table.php │ ├── 2021_10_12_165836_create_notification_users_table.php │ ├── 2021_12_25_171237_create_notifications_table.php │ ├── 2022_03_19_190522_add_is_rejected_field_to_vin_suggestions_table.php │ ├── 2022_06_21_153225_create_notification_user_vehicle_table.php │ ├── 2022_08_17_155857_create_tags_table.php │ ├── 2022_09_03_202648_add_description_column_to_tags_table.php │ ├── 2023_01_10_113851_create_information_table.php │ ├── 2023_01_11_132413_add_type_to_tags_table.php │ ├── 2023_01_12_180809_add_force_ref_to_vehicles_table.php │ ├── 2023_01_30_134933_add_headers_column_to_agencies_table.php │ ├── 2023_01_30_144842_remove_realtime_options_column_from_agencies_table.php │ ├── 2023_02_09_171511_create_stops_table.php │ ├── 2023_02_09_174714_add_block_id_column_to_trips_table.php │ ├── 2023_02_09_200714_create_stop_times_table.php │ ├── 2023_02_12_044038_add_subtitle_column_to_alerts_table.php │ ├── 2023_03_14_120145_perform_database_structure_change_part1.php │ ├── 2023_04_22_154931_create_shapes_table.php │ ├── 2023_04_26_151457_correct_index_across_the_database.php │ ├── 2023_05_06_114027_perform_database_structure_change_part2.php │ ├── 2023_05_06_165714_add_index_to_vehicles_table.php │ ├── 2023_05_17_115746_add_slug_column_to_tags_table.php │ ├── 2023_05_28_112530_add_exo_vin_fields_to_agencies_table.php │ ├── 2023_07_31_201242_add_is_archived_column_to_agencies_table.php │ ├── 2023_09_11_153329_add_last_updated_at_field_to_vehicles_table.php │ ├── 2023_09_21_112833_add_features_column_to_agencies_table.php │ └── 2024_10_17_113349_add_is_active_field_to_links_table.php ├── seeders │ ├── AgenciesTableSeeder.php │ ├── DatabaseSeeder.php │ ├── ExoAgenciesVinSeeder.php │ └── RegionsTableSeeder.php └── vin │ ├── BaseData.php │ ├── MCI.php │ ├── MCI │ └── MCI.php │ ├── Newflyer.php │ └── Novabus.php ├── package.json ├── packages └── felixinx │ └── gtfs-realtime-protobuf-php │ ├── .gitignore │ ├── .idea │ ├── gtfs-realtime-protobuf-php.iml │ ├── misc.xml │ ├── modules.xml │ └── workspace.xml │ ├── composer.json │ ├── composer.lock │ ├── gtfs-realtime.proto3 │ └── src │ ├── Alert.php │ ├── Alert │ ├── Cause.php │ └── Effect.php │ ├── EntitySelector.php │ ├── FeedEntity.php │ ├── FeedHeader.php │ ├── FeedHeader │ └── Incrementality.php │ ├── FeedMessage.php │ ├── GPBMetadata │ └── GtfsRealtime.php │ ├── Position.php │ ├── TimeRange.php │ ├── TranslatedString.php │ ├── TranslatedString │ └── Translation.php │ ├── TripDescriptor.php │ ├── TripDescriptor │ └── ScheduleRelationship.php │ ├── TripUpdate.php │ ├── TripUpdate │ ├── StopTimeEvent.php │ ├── StopTimeUpdate.php │ └── StopTimeUpdate │ │ └── ScheduleRelationship.php │ ├── VehicleDescriptor.php │ ├── VehiclePosition.php │ └── VehiclePosition │ ├── CongestionLevel.php │ ├── OccupancyStatus.php │ └── VehicleStopStatus.php ├── phpstan.neon ├── phpunit.xml ├── pint.json ├── postcss.config.js ├── public ├── .htaccess ├── favicon.ico ├── img │ ├── badge.png │ ├── demo.png │ ├── icon-192.png │ ├── icon-512.png │ ├── icon-ios-120.png │ ├── icon-ios-152.png │ ├── icon-ios-167.png │ ├── icon-ios-180.png │ ├── icon-ios-512.png │ ├── icon-mask-192.png │ ├── icon-mask-512.png │ ├── onboarding.png │ ├── open-graph.png │ └── twitter-card.png ├── index.php ├── robots.txt └── svg │ ├── 403.svg │ ├── 404.svg │ ├── 500.svg │ ├── 503.svg │ ├── icons │ ├── tt-bra-bus.svg │ ├── tt-bt-bus.svg │ ├── tt-bur-bus.svg │ ├── tt-crc-bus.svg │ ├── tt-custom-bus.svg │ ├── tt-custom-ferry.svg │ ├── tt-custom-gondola.svg │ ├── tt-custom-subway.svg │ ├── tt-custom-train.svg │ ├── tt-custom-tram.svg │ ├── tt-drt-bus.svg │ ├── tt-go-bus.svg │ ├── tt-go-train.svg │ ├── tt-grt-bus.svg │ ├── tt-grt-tram.svg │ ├── tt-gt-bus.svg │ ├── tt-hsl-bus.svg │ ├── tt-hsr-bus.svg │ ├── tt-la-bus.svg │ ├── tt-lasso-bus.svg │ ├── tt-lr-bus.svg │ ├── tt-ltc-bus.svg │ ├── tt-mrchsl-bus.svg │ ├── tt-pi-bus.svg │ ├── tt-ritc-bus.svg │ ├── tt-rous-bus.svg │ ├── tt-rtl-bus.svg │ ├── tt-sju-bus.svg │ ├── tt-so-bus.svg │ ├── tt-stcpds-bus.svg │ ├── tt-stl-bus.svg │ ├── tt-stlevis-bus.svg │ ├── tt-stm-bus-electric.svg │ ├── tt-stm-bus.svg │ ├── tt-sto-bus.svg │ ├── tt-stsag-bus.svg │ ├── tt-stsh-bus.svg │ ├── tt-sv-bus.svg │ ├── tt-tm-bus.svg │ ├── tt-trains-train.svg │ ├── tt-ttc-bus.svg │ ├── tt-ttc-tram.svg │ ├── tt-up-train.svg │ └── tt-vr-bus.svg │ ├── logo.svg │ └── regions │ ├── outaouais.svg │ ├── quebec.svg │ └── sherbrooke.svg ├── readme.md ├── resources ├── css │ └── app.css ├── js │ └── app.js ├── lang │ ├── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ ├── push.php │ │ └── validation.php │ ├── fr.json │ ├── fr │ │ ├── enums.php │ │ ├── push.php │ │ ├── transittracker.php │ │ └── validation.php │ └── vendor │ │ ├── backup │ │ └── cs │ │ │ └── notifications.php │ │ └── laravelEnum │ │ ├── en │ │ └── messages.php │ │ └── fr │ │ └── messages.php └── views │ ├── components │ ├── button │ │ ├── filled.blade.php │ │ └── text.blade.php │ ├── dialog │ │ └── basic.blade.php │ ├── icon-button │ │ └── standard.blade.php │ └── layout.blade.php │ ├── errors │ ├── 401.blade.php │ ├── 403.blade.php │ ├── 404.blade.php │ ├── 419.blade.php │ ├── 429.blade.php │ ├── 500.blade.php │ ├── 503.blade.php │ ├── illustrated-layout.blade.php │ ├── layout.blade.php │ ├── maintenance.blade.php │ └── minimal.blade.php │ ├── filament │ ├── fields-helper │ │ └── bbox.blade.php │ └── widgets │ │ └── welcome-admin.blade.php │ ├── tables │ └── columns │ │ └── tag-preview.blade.php │ ├── vendor │ └── filament │ │ └── components │ │ └── brand.blade.php │ └── vin │ ├── agency.blade.php │ ├── error.blade.php │ ├── index.blade.php │ ├── operator.blade.php │ └── show.blade.php ├── routes ├── admin.php ├── api │ └── v2.php ├── channels.php ├── console.php ├── vin.php └── web.php ├── server.php ├── storage ├── app │ ├── public │ │ ├── .gitignore │ │ └── content │ │ │ ├── alerts │ │ │ └── .gitignore │ │ │ └── regions │ │ │ └── .gitignore │ ├── realtime │ │ └── .gitignore │ └── static │ │ └── .gitignore ├── debugbar │ └── .gitignore └── framework │ ├── .gitignore │ ├── cache │ ├── .gitignore │ └── data │ │ └── .gitignore │ ├── sessions │ └── .gitignore │ ├── testing │ └── .gitignore │ └── views │ └── .gitignore ├── tailwind.config.js ├── tests ├── CreateProtobufFile.php ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php ├── vite.config.js └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /storage/app/scribe 6 | /vendor 7 | /.idea 8 | /.scribe 9 | .env 10 | .phpunit.result.cache 11 | Homestead.json 12 | Homestead.yaml 13 | npm-debug.log 14 | yarn-error.log 15 | .envdev 16 | .envprod 17 | /packages/transittracker/* 18 | /public/*.js 19 | !/public/workbox*.js 20 | !/public/service-worker.js 21 | /public/js 22 | /public/css 23 | /public/docs 24 | /public/packages 25 | /public/vendors~js 26 | /public/vendor 27 | /public/mix-manifest.json 28 | .php_cs.cache 29 | .php_cs 30 | .phpstorm.meta.php 31 | .editorconfig 32 | /invoker 33 | /resources/views/scribe 34 | /storage/logs 35 | /data.ms 36 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .scribe 2 | packages 3 | public/docs 4 | public/storage 5 | public/vendor 6 | storage 7 | vendor -------------------------------------------------------------------------------- /.shiftrc: -------------------------------------------------------------------------------- 1 | [shift] 2 | excluded_paths="packages/felixinx/gtfs-realtime-protobuf-php/src" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Félix Desjardins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/CacheHasher/HasherWithoutHost.php: -------------------------------------------------------------------------------- 1 | getCacheNameSuffix($request); 20 | 21 | return 'responsecache-'.md5( 22 | "{$request->getRequestUri()}-{$request->getMethod()}/$cacheNameSuffix" 23 | ); 24 | } 25 | 26 | protected function getCacheNameSuffix(Request $request) 27 | { 28 | if ($request->attributes->has('responsecache.cacheNameSuffix')) { 29 | return $request->attributes->get('responsecache.cacheNameSuffix'); 30 | } 31 | 32 | return $this->cacheProfile->useCacheNameSuffix($request); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/CacheProfiles/LocalizationProfile.php: -------------------------------------------------------------------------------- 1 | is('v2/*')) { 17 | return App::currentLocale(); 18 | } 19 | 20 | return ''; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Checks/AgenciesUpdatedCheck.php: -------------------------------------------------------------------------------- 1 | select(['timestamp', 'short_name'])->get(); 18 | 19 | $badAgencies = []; 20 | 21 | foreach ($agenciesToCheck as $agency) { 22 | if (now()->subMinutes(5)->isBefore(Carbon::createFromTimestamp($agency->timestamp))) { 23 | continue; 24 | } 25 | 26 | array_push($badAgencies, $agency->short_name); 27 | } 28 | 29 | if (count($badAgencies) > 0) { 30 | $joinedAgencies = implode(', ', $badAgencies); 31 | 32 | return $result->failed("Agencies {$joinedAgencies} have not been updated in the last 5 minutes."); 33 | } 34 | 35 | $result->shortSummary("{$agenciesToCheck->count()} ag."); 36 | 37 | return $result->ok(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Console/Commands/Vin/DecodeVins.php: -------------------------------------------------------------------------------- 1 | select(['vehicle_id'])->get()->chunk(50); 19 | 20 | $bar = $this->output->createProgressBar(Vehicle::exoWithVin()->count()); 21 | 22 | $bar->start(); 23 | 24 | foreach ($chunks as $chunk) { 25 | $response = Http::asForm()->post('https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/', [ 26 | 'DATA' => $chunk->pluck('vehicle_id')->join(';'), 27 | 'format' => 'JSON', 28 | ]); 29 | foreach ($response->json()['Results'] as $result) { 30 | DecodeVin::dispatchSync($result); 31 | $bar->advance(); 32 | } 33 | } 34 | 35 | $bar->finish(); 36 | 37 | return Command::SUCCESS; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Enums/AgencyFeature.php: -------------------------------------------------------------------------------- 1 | > 15 | */ 16 | protected $dontReport = [ 17 | // 18 | ]; 19 | 20 | /** 21 | * A list of the inputs that are never flashed for validation exceptions. 22 | * 23 | * @var array 24 | */ 25 | protected $dontFlash = [ 26 | 'password', 27 | 'password_confirmation', 28 | ]; 29 | 30 | /** 31 | * Register the exception handling callbacks for the application. 32 | */ 33 | public function register(): void 34 | { 35 | $this->reportable(function (Throwable $e) { 36 | Integration::captureUnhandledException($e); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Filament/Resources/AgencyResource/Pages/CreateAgency.php: -------------------------------------------------------------------------------- 1 | columns([ 20 | TextColumn::make('name'), 21 | TextColumn::make('slug'), 22 | ]) 23 | ->filters([ 24 | // 25 | ]) 26 | ->headerActions([ 27 | Tables\Actions\AttachAction::make(), 28 | ]) 29 | ->actions([ 30 | Tables\Actions\DetachAction::make(), 31 | ]) 32 | ->bulkActions([ 33 | Tables\Actions\DetachBulkAction::make(), 34 | ]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Filament/Resources/AlertResource/Pages/CreateAlert.php: -------------------------------------------------------------------------------- 1 | columns([ 19 | Tables\Columns\TextColumn::make('agency.short_name'), 20 | Tables\Columns\TextColumn::make('displayed_label'), 21 | ]) 22 | ->filters([ 23 | // 24 | ]) 25 | ->headerActions([ 26 | Tables\Actions\AssociateAction::make(), 27 | ]) 28 | ->actions([ 29 | Tables\Actions\DissociateAction::make(), 30 | ]) 31 | ->bulkActions([ 32 | Tables\Actions\DissociateBulkAction::make(), 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Filament/Resources/RegionResource/Pages/CreateRegion.php: -------------------------------------------------------------------------------- 1 | schema([ 21 | // 22 | ]); 23 | } 24 | 25 | public function table(Table $table): Table 26 | { 27 | return $table 28 | ->columns([ 29 | TextColumn::make('name'), 30 | TextColumn::make('slug'), 31 | ]) 32 | ->filters([ 33 | // 34 | ]) 35 | ->headerActions([ 36 | Tables\Actions\AttachAction::make(), 37 | ]) 38 | ->actions([ 39 | Tables\Actions\DetachAction::make(), 40 | ]) 41 | ->bulkActions([ 42 | Tables\Actions\DetachBulkAction::make(), 43 | ]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Filament/Resources/TagResource/Pages/CreateTag.php: -------------------------------------------------------------------------------- 1 | schema([ 21 | Forms\Components\TextInput::make('name') 22 | ->required() 23 | ->maxLength(255), 24 | ]); 25 | } 26 | 27 | public function table(Table $table): Table 28 | { 29 | return $table 30 | ->columns([ 31 | Tables\Columns\TextColumn::make('name'), 32 | ]) 33 | ->filters([ 34 | // 35 | ]) 36 | ->headerActions([ 37 | Tables\Actions\AttachAction::make(), 38 | ]) 39 | ->actions([ 40 | Tables\Actions\DetachAction::make(), 41 | ]) 42 | ->bulkActions([ 43 | Tables\Actions\DetachBulkAction::make(), 44 | ]); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Filament/Resources/TagResource/RelationManagers/VehiclesRelationManager.php: -------------------------------------------------------------------------------- 1 | columns([ 19 | Tables\Columns\TextColumn::make('agency.short_name'), 20 | Tables\Columns\TextColumn::make('displayed_label'), 21 | ]) 22 | ->filters([ 23 | // 24 | ]) 25 | ->headerActions([ 26 | Tables\Actions\AttachAction::make(), 27 | ]) 28 | ->actions([ 29 | Tables\Actions\DetachAction::make(), 30 | ]) 31 | ->bulkActions([ 32 | Tables\Actions\DetachBulkAction::make(), 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Filament/Resources/UserResource/Pages/CreateUser.php: -------------------------------------------------------------------------------- 1 | previousUrl ?? VehicleResource::getUrl(); 18 | } 19 | 20 | protected function getHeaderActions(): array 21 | { 22 | return [ 23 | Action::make('openInVin') 24 | ->url(route('vin.show', $this->record->ref)) 25 | ->color('gray') 26 | ->label('Open in exo VIN') 27 | ->visible($this->record->isExoVin()) 28 | ->openUrlInNewTab(), 29 | DeleteAction::make()->requiresConfirmation(), 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Filament/Resources/VehicleResource/Pages/ListVehicles.php: -------------------------------------------------------------------------------- 1 | ListRecords\Tab::make(), 17 | 'vin' => ListRecords\Tab::make('Only exo VIN') 18 | ->modifyQueryUsing(fn (Builder $query) => $query->exoWithVin()), 19 | 'zenbus' => ListRecords\Tab::make('Only Zenbus') 20 | ->modifyQueryUsing(fn (Builder $query) => $query->where('vehicle_id', 'LIKE', 'zenbus:Vehicle:%')), 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Filament/Widgets/WelcomeAdmin.php: -------------------------------------------------------------------------------- 1 | middleware('signed'); 19 | } 20 | 21 | public function update(Agency $agency) 22 | { 23 | Artisan::call('static:update', [ 24 | 'agency' => $agency->slug, 25 | ]); 26 | 27 | return redirect('/')->with('status', "Static GTFS update for {$agency->short_name} launched!"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/FailedJobController.php: -------------------------------------------------------------------------------- 1 | snooze = now()->addHours($hours); 13 | $failedJob->save(); 14 | 15 | return redirect()->route('filament.pages.dashboard'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/V2/AlertController.php: -------------------------------------------------------------------------------- 1 | count()); 23 | 24 | if (! App::environment('local')) { 25 | $this->middleware("throttle:{$totalAlerts},1,v2-alerts"); 26 | } 27 | 28 | $this->middleware('cacheResponse'); 29 | } 30 | 31 | public function index() 32 | { 33 | $alerts = Alert::active()->get(); 34 | 35 | return AlertResource::collection($alerts->filter(fn ($alert) => ! array_key_exists('only-v1', $alert->action_parameters->toArray()))); 36 | } 37 | 38 | public function show(Alert $alert) 39 | { 40 | if (! $alert->is_active or Carbon::parse($alert->expiration)->isPast()) { 41 | return response()->json(['message' => 'Alert is inactive or expired.'], 403); 42 | } 43 | 44 | return AlertResource::make($alert); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/V2/LinkController.php: -------------------------------------------------------------------------------- 1 | middleware("throttle:{$totalLinks},1,v2-links"); 25 | } 26 | 27 | $this->middleware('cacheResponse'); 28 | } 29 | 30 | public function index() 31 | { 32 | $links = Link::active()->get(); 33 | 34 | return LinkResource::collection($links); 35 | } 36 | 37 | public function show(int $linkId) 38 | { 39 | $link = Link::active()->findOrFail($linkId); 40 | 41 | return LinkResource::make($link); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/V2/NotificationsController.php: -------------------------------------------------------------------------------- 1 | ', now()->subWeek())->select(['id', 'agency_id'])->with('agency:id,slug')->get())->groupBy('agency.slug')->map(function ($vehicles) { 13 | return $vehicles->count(); 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/V2/ShapeController.php: -------------------------------------------------------------------------------- 1 | middleware('throttle:45,1,v2-shapes'); 16 | } 17 | 18 | // One week, shapes should not change very often 19 | $this->middleware('cacheResponse:604800'); 20 | } 21 | 22 | public function show(Agency $agency, string $shapeId) 23 | { 24 | return GeoJsonShapeResource::make( 25 | Shape::query() 26 | ->where(['agency_id' => $agency->id, 'gtfs_shape_id' => $shapeId]) 27 | ->select(['agency_id', 'gtfs_shape_id', 'shape']) 28 | ->with([ 29 | 'firstTrip:id,trips.agency_id,gtfs_trip_id,trips.gtfs_shape_id', 30 | 'firstTrip.stopTimes:stop_times.agency_id,stop_times.gtfs_trip_id,gtfs_stop_id', 31 | 'firstTrip.stopTimes.stop:stops.agency_id,stops.gtfs_stop_id,position', 32 | ]) 33 | ->firstOrFail() 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/V2/TagController.php: -------------------------------------------------------------------------------- 1 | middleware("throttle:{$totalLinks},1,v2-tags"); 25 | } 26 | 27 | $this->middleware('cacheResponse'); 28 | } 29 | 30 | public function index() 31 | { 32 | $tags = Tag::all(); 33 | 34 | return TagResource::collection($tags); 35 | } 36 | 37 | public function show(Tag $tag) 38 | { 39 | return TagResource::make($tag); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | where('name_slug', $sector) 15 | ->select(['id', 'name', 'color', 'is_archived']) 16 | ->firstOrFail(); 17 | 18 | $vehicles = Vehicle::query() 19 | ->vin() 20 | ->where('agency_id', $agency->id) 21 | ->select(['id', 'agency_id', 'vehicle_id', 'force_vehicle_id', 'label', 'force_label', 'timestamp', 'gtfs_trip_id', 'gtfs_route_id']) 22 | ->with([ 23 | 'trip:agency_id,gtfs_trip_id,headsign', 24 | 'gtfsRoute:agency_id,gtfs_route_id,short_name', 25 | 'tags:id,label,slug', 26 | 'vinInformationOriginal:vin,make', 27 | ]) 28 | ->orderBy('force_label') 29 | ->get(); 30 | 31 | return view('vin.agency', compact('agency', 'vehicles')); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Controllers/Vin/OperatorController.php: -------------------------------------------------------------------------------- 1 | type->value !== TagType::Operator, 404); 14 | 15 | $tag->load([ 16 | 'exoVinVehicles:id,agency_id,vehicle_id,force_vehicle_id,label,force_label,timestamp,gtfs_route_id,gtfs_trip_id', 17 | 'exoVinVehicles.trip:agency_id,gtfs_trip_id,headsign', 18 | 'exoVinVehicles.gtfsRoute:agency_id,gtfs_route_id,short_name', 19 | 'exoVinVehicles.vinInformationOriginal:vin,make', 20 | 'exoVinVehicles.agency:id,name,color,text_color', 21 | ]); 22 | 23 | $agencies = $tag->exoVinVehicles->sortBy('force_label')->groupBy('agency')->sortDesc(); 24 | 25 | return view('vin.operator', compact('tag', 'agencies')); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | header('Content-Language'); 19 | 20 | if (! $locale) { 21 | $locale = config('app.locale'); 22 | } elseif ($locale === 'fr-CA') { 23 | $locale = 'fr'; 24 | } elseif ($locale === 'en-CA') { 25 | $locale = 'en'; 26 | } 27 | 28 | if (! array_key_exists($locale, config('app.supported_languages'))) { 29 | return abort(403, 'Language not supported. Try with en or fr.'); 30 | } 31 | 32 | App::setLocale($locale); 33 | 34 | $response = $next($request); 35 | $response->headers->set('Content-Language', $locale); 36 | 37 | return $response; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | check()) { 25 | return redirect(RouteServiceProvider::HOME); 26 | } 27 | } 28 | 29 | return $next($request); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class AgencyResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'id' => $this->id, 16 | 'isArchived' => $this->is_archived, 17 | 'name' => $this->name, 18 | 'shortName' => $this->short_name, 19 | 'slug' => $this->slug, 20 | 'cities' => $this->random_cities, 21 | 'defaultVehicleType' => $this->vehicles_type, 22 | 'color' => $this->color, 23 | 'textColor' => $this->text_color, 24 | 'regions' => RegionSimpleResource::collection($this->regions), 25 | 'license' => [ 26 | 'url' => array_key_exists('license_url', $this->license) ? $this->license['license_url'] : null, 27 | 'title' => array_key_exists('license_title', $this->license) ? $this->license['license_title'] : null, 28 | 'isDownloadable' => array_key_exists('is_downloadable', $this->license) ? boolval($this->license['is_downloadable']) : null, 29 | ], 30 | 'features' => $this->features ?? [], 31 | 'meta' => (object) [], 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/AgencySimpleResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class AgencySimpleResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return $this->slug; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/AlertResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class AlertResource extends JsonResource 12 | { 13 | public function toArray($request) 14 | { 15 | return [ 16 | 'id' => $this->id, 17 | 'title' => $this->title, 18 | 'subtitle' => $this->subtitle, 19 | 'body' => $this->body, 20 | 'color' => $this->color, 21 | 'icon' => $this->icon, 22 | 'action' => $this->action, 23 | 'actionParameters' => $this->action_parameters, 24 | 'image' => basename($this->image), 25 | 'canBeClosed' => $this->can_be_closed, 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/BlockResource.php: -------------------------------------------------------------------------------- 1 | $this->gtfs_trip_id, 13 | 'headsign' => $this->headsign, 14 | 'shortName' => $this->short_name, 15 | 'routeColor' => $this->route->color, 16 | 'routeTextColor' => $this->route->text_color, 17 | 'routeShortName' => $this->route->short_name, 18 | 'departure' => $this->firstDeparture->departure, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonLandingCollection.php: -------------------------------------------------------------------------------- 1 | 'FeatureCollection', 15 | 'features' => GeoJsonLandingResource::collection($this->collection), 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonLandingResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class GeoJsonLandingResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'type' => 'Feature', 16 | 'properties' => [ 17 | 'slug' => $this->slug, 18 | 'name' => $this->name, 19 | 'agencies' => $this->active_agencies_count, 20 | 'vehicles' => $this->vehicles()->count(), 21 | 'cities' => $this->cities, 22 | 'range' => 15 - $this->map_zoom, 23 | ], 24 | 'geometry' => [ 25 | 'type' => 'Point', 26 | 'coordinates' => [ 27 | $this->map_center['lon'], 28 | $this->map_center['lat'], 29 | ], 30 | ], 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonLandingVehicleCollection.php: -------------------------------------------------------------------------------- 1 | 'FeatureCollection', 15 | 'features' => GeoJsonLandingVehicleResource::collection($this->collection), 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonLandingVehicleResource.php: -------------------------------------------------------------------------------- 1 | 'Feature', 13 | 'geometry' => $this->position, 14 | ]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonShapeLineResource.php: -------------------------------------------------------------------------------- 1 | 'Feature', 14 | 'properties' => (object) [], 15 | 'geometry' => $this->shape, 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonShapeResource.php: -------------------------------------------------------------------------------- 1 | 'FeatureCollection', 16 | 'features' => [ 17 | GeoJsonShapeLineResource::make($this), 18 | ...GeoJsonShapeStopResource::collection($this->firstTrip->stopTimes), 19 | ], 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonShapeStopResource.php: -------------------------------------------------------------------------------- 1 | 'Feature', 14 | 'properties' => (object) [], 15 | 'geometry' => $this->stop->position, 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonVehicleResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class GeoJsonVehicleResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | $vehicleType = strtolower($this->vehicle_type?->key); 15 | 16 | return [ 17 | 'type' => 'Feature', 18 | 'properties' => [ 19 | 'id' => $this->id, 20 | 'label' => $this->displayed_label, 21 | 'marker-symbol' => "tt-{$this->agency->slug}-{$vehicleType}", 22 | ], 23 | 'geometry' => $this->position, 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/GeoJsonVehiclesCollection.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class GeoJsonVehiclesCollection extends ResourceCollection 11 | { 12 | public static $wrap = 'features'; 13 | 14 | public function toArray($request) 15 | { 16 | return [ 17 | 'type' => 'FeatureCollection', 18 | 'features' => GeoJsonVehicleResource::collection($this->collection), 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/LinkResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class LinkResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'id' => $this->id, 16 | 'title' => $this->title, 17 | 'description' => $this->description, 18 | 'url' => $this->link, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/LinkSimpleResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class LinkSimpleResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return $this->id; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/NotificationUserResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NotificationUserResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'isActive' => $this->is_active, 16 | 'isFrench' => $this->is_french, 17 | 'uuid' => $this->uuid, 18 | 'electricStm' => $this->subscribed_electric_stm, 19 | 'generalNews' => $this->subscribed_general_news, 20 | 'newVehicle' => [ 21 | 'agencies' => AgencySimpleResource::collection($this->agencies), 22 | ], 23 | 'favoriteVehicles' => VehiclePushResource::collection($this->vehicles), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/RegionResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class RegionResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'name' => $this->name, 16 | 'slug' => $this->slug, 17 | 'credits' => $this->credits, 18 | 'infoTitle' => '', 19 | 'infoBody' => '', 20 | 'description' => $this->description, 21 | 'metaDescription' => $this->meta_description, 22 | 'cities' => $this->cities, 23 | 'image' => basename($this->image), 24 | 'mapBox' => $this->map_box, 25 | 'mapCenter' => $this->map_center, 26 | 'mapZoom' => $this->map_zoom, 27 | 'agencies' => AgencyResource::collection($this->activeAgencies), 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/RegionSimpleResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class RegionSimpleResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return $this->slug; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/TagResource.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TagResource extends JsonResource 11 | { 12 | public function toArray($request) 13 | { 14 | return [ 15 | 'id' => $this->id, 16 | 'label' => $this->label, 17 | 'short_label' => $this->short_label, 18 | 'description' => $this->description, 19 | 'icon' => $this->icon, 20 | 'color' => $this->color, 21 | 'dark_color' => $this->dark_color, 22 | 'text_color' => $this->text_color, 23 | 'dark_text_color' => $this->dark_text_color, 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/TagSimpleResource.php: -------------------------------------------------------------------------------- 1 | id; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/TripResource.php: -------------------------------------------------------------------------------- 1 | */ 9 | class TripResource extends JsonResource 10 | { 11 | public function toArray($request) 12 | { 13 | return [ 14 | 'id' => $this->trip?->gtfs_trip_id, 15 | 'headsign' => $this->trip?->headsign, 16 | 'shortName' => $this->trip?->short_name, 17 | 'routeColor' => $this->gtfsRoute?->color, 18 | 'routeTextColor' => $this->gtfsRoute?->text_color, 19 | 'routeShortName' => $this->gtfsRoute?->short_name, 20 | 'routeLongName' => $this->gtfsRoute?->long_name, 21 | 'shapeLink' => $this->trip?->gtfs_shape_id ? Storage::url("shapes/{$this->additional['agencySlug']}/{$this->trip?->gtfs_shape_id}.json") : null, 22 | 'shapeId' => $this->trip?->gtfs_shape_id, 23 | 'serviceId' => $this->trip?->gtfs_service_id, 24 | 'blockId' => $this->trip?->gtfs_block_id, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/VehiclePushResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'vehicleType' => $this->vehicle_type, 20 | 'label' => $this->displayed_label, 21 | 'agency' => $this->agency->slug, 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Resources/V2/VehiclesGeoJson/VehiclesCollection.php: -------------------------------------------------------------------------------- 1 | 'FeatureCollection', 16 | 'features' => VehicleResource::collection($this->collection), 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Jobs/CleanFolders.php: -------------------------------------------------------------------------------- 1 | each(function ($directory) { 39 | Storage::deleteDirectory($directory); 40 | }); 41 | 42 | $gitignore = "*\n.gitignore"; 43 | 44 | Storage::put('realtime/.gitignore', $gitignore); 45 | Storage::put('static/.gitignore', $gitignore); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Jobs/RealtimeData/CheckTimestamps.php: -------------------------------------------------------------------------------- 1 | where('is_active', true)->get(); 36 | 37 | foreach ($agenciesToCheck as $agency) { 38 | if (now()->subMinutes(5)->isBefore(Carbon::createFromTimestamp($agency->timestamp))) { 39 | continue; 40 | } 41 | 42 | $action = new HandleExpiredRealtimeData($agency); 43 | $action->execute(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Listeners/DeactivateInactiveSubscription.php: -------------------------------------------------------------------------------- 1 | subscription->subscribable->is_active = false; 16 | $event->subscription->subscribable->save(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Listeners/DecodeVin.php: -------------------------------------------------------------------------------- 1 | vehicle->isExoVin()) { 21 | return false; 22 | } 23 | 24 | DecodeVinJob::dispatchSync([$event->vehicle->force_vehicle_id ?? $event->vehicle->vehicle_id]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Listeners/SendElectricStmNotification.php: -------------------------------------------------------------------------------- 1 | where([ 23 | 'is_active' => true, 24 | 'subscribed_electric_stm' => true, 25 | ]) 26 | ->get(); 27 | 28 | Notification::send($users, new ElectricStmAppearance($event->vehicle)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Listeners/SendNewVehicleNotification.php: -------------------------------------------------------------------------------- 1 | vehicle->load(['agency.activeNotificationUsers', 'agency.regions:id,slug']); 21 | Notification::send($event->vehicle->agency->activeNotificationUsers, new NewVehicle($event->vehicle)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Listeners/SendNewVinSuggestionNotification.php: -------------------------------------------------------------------------------- 1 | suggestion)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Listeners/SendUpdatedVehicleNotification.php: -------------------------------------------------------------------------------- 1 | vehicle->load('notificationUsers'); 20 | 21 | Notification::send($event->vehicle->notification_users, new UpdatedVehicle($event->vehicle)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Listeners/SendWelcomeNotification.php: -------------------------------------------------------------------------------- 1 | notificationUser->notify((new Welcome())->delay(now()->addMinute())); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Models/FailedJob.php: -------------------------------------------------------------------------------- 1 | belongsTo(Agency::class); 22 | } 23 | 24 | public function prunable(): Builder 25 | { 26 | return static::where('created_at', '<=', now()->subMonth()); 27 | } 28 | 29 | public function signedSnoozeUrl(int $hours): string 30 | { 31 | return URL::temporarySignedRoute('internal.failed-jobs.snooze', now()->addHours(5), [ 32 | 'failedJob' => $this, 33 | 'hours' => $hours, 34 | ]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Models/Gtfs/Route.php: -------------------------------------------------------------------------------- 1 | belongsTo(Agency::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Models/Gtfs/Service.php: -------------------------------------------------------------------------------- 1 | belongsTo(Agency::class); 19 | } 20 | 21 | public function trips(): HasMany 22 | { 23 | return $this->hasMany(Trip::class, ['agency_id', 'gtfs_service_id'], ['agency_id', 'gtfs_service_id']); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/Gtfs/Stop.php: -------------------------------------------------------------------------------- 1 | Point::class, 22 | ]; 23 | 24 | public function agency(): BelongsTo 25 | { 26 | return $this->belongsTo(Agency::class); 27 | } 28 | 29 | public function stopTimes(): HasMany 30 | { 31 | return $this->hasMany(StopTime::class, ['agency_id', 'gtfs_trip_id'], ['agency_id', 'gtfs_trip_id']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Models/Gtfs/StopTime.php: -------------------------------------------------------------------------------- 1 | belongsTo(Trip::class, ['agency_id', 'trip_id'], ['agency_id', 'gtfs_trip_id']); 15 | } 16 | 17 | public function stop(): BelongsTo 18 | { 19 | return $this->belongsTo(Stop::class, ['agency_id', 'gtfs_stop_id'], ['agency_id', 'gtfs_stop_id']); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Models/Stat.php: -------------------------------------------------------------------------------- 1 | 'object', 14 | ]; 15 | 16 | public function region(): BelongsTo 17 | { 18 | return $this->belongsTo(Region::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Models/User.php: -------------------------------------------------------------------------------- 1 | 'datetime', 26 | ]; 27 | 28 | public function routeNotificationForSlack(): string 29 | { 30 | return config('transittracker.slack_webhook_url'); 31 | } 32 | 33 | public function canAccessPanel(Panel $panel): bool 34 | { 35 | return true; 36 | } 37 | 38 | // Super admin 39 | public function isAdmin(): bool 40 | { 41 | return $this->email === config('transittracker.admin_email'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Models/Vin/Information.php: -------------------------------------------------------------------------------- 1 | AsCollection::class, 24 | ]; 25 | 26 | public function vehicles() 27 | { 28 | return $this->hasMany(Vehicle::class, 'vehicle', 'vin'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Models/Vin/Suggestion.php: -------------------------------------------------------------------------------- 1 | 'boolean', 21 | ]; 22 | 23 | public function vehicles(): HasMany 24 | { 25 | return $this->hasMany(Vehicle::class, 'vehicle_id', 'vin'); 26 | } 27 | 28 | protected $dispatchesEvents = [ 29 | 'created' => SuggestionCreated::class, 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Notifications/NewVinSuggestion.php: -------------------------------------------------------------------------------- 1 | info() 29 | ->content("New VIN suggestion for {$this->suggestion->vin}") 30 | ->attachment(function (SlackAttachment $attachment) { 31 | $attachment->action('View suggestion', route('vin.show', ['vin' => $this->suggestion->vin])); 32 | }); 33 | } 34 | 35 | public function viaQueues() 36 | { 37 | return [ 38 | 'slack' => 'notifications', 39 | ]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Notifications/Push/Welcome.php: -------------------------------------------------------------------------------- 1 | 'notifications', 29 | ]; 30 | } 31 | 32 | public function toWebPush() 33 | { 34 | return (new WebPushMessage) 35 | ->icon('https://api.transittracker.ca/img/icon-192.png') 36 | ->badge('https://api.transittracker.ca/img/badge.png') 37 | ->title(__('push.welcome.title', [])) 38 | ->body(__('push.welcome.body', [])); 39 | } 40 | 41 | public function toArray() 42 | { 43 | return [ 44 | 'title' => __('push.welcome.title', []), 45 | 'body' => __('push.welcome.body', []), 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Notifications/RealtimeDataExpired.php: -------------------------------------------------------------------------------- 1 | agency->timestamp))->diffForHumans(); 28 | 29 | return (new SlackMessage) 30 | ->warning() 31 | ->content("The realtime data for {$this->agency->short_name} has expired {$timeSince}.") 32 | ->attachment(function (SlackAttachment $attachment) { 33 | $attachment->action('Open Horizon', route('horizon.index')); 34 | }); 35 | } 36 | 37 | public function toArray($notifiable) 38 | { 39 | return [ 40 | // 41 | ]; 42 | } 43 | 44 | public function viaQueues() 45 | { 46 | return [ 47 | 'slack' => 'notifications', 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/Notifications/StaticGtfsExpired.php: -------------------------------------------------------------------------------- 1 | agency->signedUpdateGtfsUrl(); 27 | 28 | return (new SlackMessage) 29 | ->warning() 30 | ->content("The GTFS data for {$this->agency->short_name} might be expired.") 31 | ->attachment(function (SlackAttachment $attachment) use ($url) { 32 | $attachment->action('Update static data', $url); 33 | }); 34 | } 35 | 36 | public function toArray($notifiable) 37 | { 38 | return [ 39 | // 40 | ]; 41 | } 42 | 43 | public function viaQueues() 44 | { 45 | return [ 46 | 'slack' => 'notifications', 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | protected $policies = []; 17 | 18 | /** 19 | * Register any authentication / authorization services. 20 | */ 21 | public function boot(): void 22 | { 23 | Gate::before(function (User $user) { 24 | return $user->isAdmin() ? true : null; 25 | }); 26 | 27 | Gate::define('viewLogViewer', fn (User $user) => $user->isAdmin()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | $user->isAdmin()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Providers/LadderServiceProvider.php: -------------------------------------------------------------------------------- 1 | configurePermissions(); 24 | } 25 | 26 | /** 27 | * Configure the permissions that are available within the application. 28 | */ 29 | protected function configurePermissions(): void 30 | { 31 | Ladder::role('vin-editor', 'exo VIN editor', [ 32 | 'vin:edit', 33 | ]); 34 | 35 | Ladder::role('zenbus-editor', 'Zenbus editor', [ 36 | 'zenbus:edit', 37 | ]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/View/Components/Button/Text.php: -------------------------------------------------------------------------------- 1 | Cache::remember('exoSectors', 86400, function () { 30 | return Agency::exo()->select(['short_name', 'color', 'name_slug', 'is_archived'])->withCount('exoWithVin')->orderBy('is_archived')->orderBy('exo_order_id')->get(); 31 | }), 32 | 'operators' => Cache::remember('exoOperators', 86400, function () { 33 | return Tag::ofType(TagType::Operator)->select(['label', 'slug', 'color', 'text_color'])->withCount('exoVinVehicles')->get()->sortByDesc('exo_vin_vehicles_count'); 34 | }), 35 | ]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /config/filament.php: -------------------------------------------------------------------------------- 1 | [ 18 | 19 | // 'echo' => [ 20 | // 'broadcaster' => 'pusher', 21 | // 'key' => env('VITE_PUSHER_APP_KEY'), 22 | // 'cluster' => env('VITE_PUSHER_APP_CLUSTER'), 23 | // 'forceTLS' => true, 24 | // ], 25 | 26 | ], 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Default Filesystem Disk 31 | |-------------------------------------------------------------------------- 32 | | 33 | | This is the storage disk Filament will use to put media. You may use any 34 | | of the disks defined in the `config/filesystems.php`. 35 | | 36 | */ 37 | 38 | 'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DISK', 'public'), 39 | 40 | ]; 41 | -------------------------------------------------------------------------------- /config/hooks.php: -------------------------------------------------------------------------------- 1 | env('HOOKS_ENABLED', true), 6 | 7 | ]; 8 | -------------------------------------------------------------------------------- /config/image.php: -------------------------------------------------------------------------------- 1 | 'gd', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /config/prologue/alerts.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'info', 22 | 'warning', 23 | 'error', 24 | 'success', 25 | ], 26 | 27 | /* 28 | |-------------------------------------------------------------------------- 29 | | Session Key 30 | |-------------------------------------------------------------------------- 31 | | 32 | | The session key which is used to store flashed messages into the current 33 | | session. This can be changed if it conflicts with another key. 34 | | 35 | */ 36 | 37 | 'session_key' => 'alert_messages', 38 | 39 | ]; 40 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'ses' => [ 24 | 'key' => env('SES_KEY'), 25 | 'secret' => env('SES_SECRET'), 26 | 'region' => env('SES_REGION', 'us-east-1'), 27 | ], 28 | 29 | 'sparkpost' => [ 30 | 'secret' => env('SPARKPOST_SECRET'), 31 | ], 32 | 33 | 'stripe' => [ 34 | 'model' => App\Models\User::class, 35 | 'key' => env('STRIPE_KEY'), 36 | 'secret' => env('STRIPE_SECRET'), 37 | 'webhook' => [ 38 | 'secret' => env('STRIPE_WEBHOOK_SECRET'), 39 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), 40 | ], 41 | ], 42 | 43 | ]; 44 | -------------------------------------------------------------------------------- /config/transittracker.php: -------------------------------------------------------------------------------- 1 | env('APP_API_KEY', null), 5 | 'admin_email' => env('MAIL_TO', ''), 6 | 'slack_webhook_url' => env('SLACK_WEBHOOK_URL'), 7 | 'turnstile' => [ 8 | 'site_key' => env('TURNSTILE_SITE_KEY'), 9 | 'secret' => env('TURNSTILE_SECRET_KEY'), 10 | ], 11 | 'mapbox' => [ 12 | 'secret_key' => env('MAPBOX_SECRET_KEY'), 13 | 'light_style' => env('MAPBOX_LIGHT_STYLE'), 14 | 'dark_style' => env('MAPBOX_DARK_STYLE'), 15 | 'satellite_style' => env('MAPBOX_SATELLITE_STYLE'), 16 | ], 17 | 'print_gtfs_rt_bin' => env('PRINT_GTFS_RT_BIN'), 18 | 'domain' => [ 19 | 'web' => env('WEB_DOMAIN', null), 20 | 'api' => env('API_DOMAIN', null), 21 | 'vin' => env('VIN_DOMAIN', null), 22 | 'filament' => env('FILAMENT_DOMAIN', null), 23 | ], 24 | 'path' => [ 25 | 'vin' => env('VIN_PATH', 'vin'), 26 | 'filament' => env('FILAMENT_PATH', 'admin'), 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /config/translatable.php: -------------------------------------------------------------------------------- 1 | 'en', 9 | ]; 10 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->name, 27 | 'email' => $this->faker->unique()->safeEmail, 28 | 'email_verified_at' => now(), 29 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 30 | 'remember_token' => Str::random(10), 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2019_06_25_195404_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2019_07_08_193557_add_text_color_and_timestamp_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | bigInteger('timestamp')->default(time()); 18 | $table->string('text_color')->default('#FFFFFF'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('agencies', function (Blueprint $table) { 30 | $table->dropColumn(['timestamp', 'text_color']); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2019_08_20_002346_add_tags_and_active_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | string('tags')->nullable(); 18 | $table->boolean('is_active')->default(false); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('agencies', function (Blueprint $table) { 30 | $table->dropColumn(['tags', 'is_active']); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2019_09_04_000038_create_stats_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('type'); 19 | $table->string('data'); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('stats'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2019_10_15_204754_update_agencies_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('gtfs_id'); 18 | $table->string('static_gtfs_url')->nullable(); 19 | $table->string('realtime_url')->nullable(); 20 | $table->string('realtime_type')->nullable(); 21 | $table->json('realtime_options')->nullable(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::table('agencies', function (Blueprint $table) { 33 | $table->dropColumn(['static_gtfs_url', 'realtime_url', 'realtime_type', 'realtime_options']); 34 | $table->string('gtfs_id'); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2019_10_15_205808_create_services_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->string('service_id'); 19 | $table->date('start_date'); 20 | $table->date('end_date'); 21 | $table->unsignedInteger('agency_id'); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('services'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2019_10_15_231316_add_service_id_to_trips_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('service_id')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('trips', function (Blueprint $table) { 29 | $table->dropColumn('service_id'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2019_10_25_122725_update_alert_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('colour'); 18 | $table->dropColumn('expiration'); 19 | $table->boolean('is_active')->default(false); 20 | $table->string('icon')->nullable(); 21 | $table->string('color')->default('primary'); 22 | $table->boolean('can_be_closed')->default(true); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::table('alerts', function (Blueprint $table) { 34 | $table->dropColumn(['is_active', 'icon', 'color', 'can_be_closed']); 35 | $table->string('colour')->nullable(); 36 | $table->dateTime('expiration')->nullable(); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->morphs('tokenable'); 17 | $table->string('name'); 18 | $table->string('token', 64)->unique(); 19 | $table->text('abilities')->nullable(); 20 | $table->timestamp('last_used_at')->nullable(); 21 | $table->timestamp('expires_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | */ 29 | public function down(): void 30 | { 31 | Schema::dropIfExists('personal_access_tokens'); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /database/migrations/2020_01_23_005154_add_index_to_trips_table.php: -------------------------------------------------------------------------------- 1 | index(['agency_id', 'trip_id']); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('trips', function (Blueprint $table) { 29 | $table->dropIndex(['agency_id', 'trip_id']); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_03_03_004606_add_icon_to_vehicles_table.php: -------------------------------------------------------------------------------- 1 | string('icon')->default('bus'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('vehicles', function (Blueprint $table) { 29 | $table->dropColumn('icon'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_05_03_151057_create_failed_jobs_histories_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->unsignedInteger('agency_id')->nullable(); 20 | $table->string('exception'); 21 | $table->dateTime('last_failed'); 22 | $table->index(['name', 'exception']); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs_histories'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2020_05_21_133049_add_indexes_to_routes_and_services_tables.php: -------------------------------------------------------------------------------- 1 | index(['agency_id', 'route_id']); 18 | }); 19 | Schema::table('services', function (Blueprint $table) { 20 | $table->index(['agency_id', 'service_id']); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::table('routes', function (Blueprint $table) { 32 | $table->dropIndex(['agency_id', 'route_id']); 33 | }); 34 | Schema::table('services', function (Blueprint $table) { 35 | $table->dropIndex(['agency_id', 'service_id']); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2020_07_20_085647_add_shape_to_trips_table.php: -------------------------------------------------------------------------------- 1 | string('shape')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('trips', function (Blueprint $table) { 29 | $table->dropColumn('shape'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_07_22_095116_add_snooze_to_failed_job_histories_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('last_failed'); 18 | $table->dateTime('snooze')->default(now()); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('failed_jobs_histories', function (Blueprint $table) { 30 | $table->dropColumn('snooze'); 31 | $table->dateTime('last_failed')->default(now()); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2020_08_05_132648_add_license_field_to_agency_table.php: -------------------------------------------------------------------------------- 1 | json('license')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('license'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_09_29_165446_add_support_for_batch_jobs.php: -------------------------------------------------------------------------------- 1 | string('uuid')->after('id')->nullable()->unique(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('failed_jobs', function (Blueprint $table) { 29 | $table->dropColumn(); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_03_201053_add_refresh_is_active_field_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | boolean('refresh_is_active')->default(true); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('refresh_is_active'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_180444_add_short_name_field_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | string('short_name')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('short_name'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_180511_add_cron_schedule_field_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | string('cron_schedule')->default('* * * * *'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('cron_schedule'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_180531_add_actions_fields_to_alerts_table.php: -------------------------------------------------------------------------------- 1 | string('action')->nullable(); 18 | $table->json('action_parameters')->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('alerts', function (Blueprint $table) { 30 | $table->dropColumn(['action', 'action_parameters']); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_180539_add_expiration_field_to_alerts_table.php: -------------------------------------------------------------------------------- 1 | dateTime('expiration')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('alerts', function (Blueprint $table) { 29 | $table->dropColumn('expiration'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_180548_add_image_field_to_alerts_table.php: -------------------------------------------------------------------------------- 1 | string('image')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('alerts', function (Blueprint $table) { 29 | $table->dropColumn('image'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_05_181211_add_description_field_to_regions_table.php: -------------------------------------------------------------------------------- 1 | json('description'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('regions', function (Blueprint $table) { 29 | $table->dropColumn('description'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_11_06_120200_remove_conditions_and_map_fields_from_regions_table.php: -------------------------------------------------------------------------------- 1 | dropColumn(['conditions', 'map']); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('regions', function (Blueprint $table) { 29 | $table->text('conditions'); 30 | $table->text('map'); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2021_04_01_192349_add_map_center_to_regions_table.php: -------------------------------------------------------------------------------- 1 | json('map_center')->after('map_box'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('regions', function (Blueprint $table) { 29 | $table->dropColumn('map_center'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_04_01_195411_add_image_to_regions_table.php: -------------------------------------------------------------------------------- 1 | string('image')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('regions', function (Blueprint $table) { 29 | $table->dropColumn('image'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_04_03_172520_add_cities_field_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | json('cities')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('cities'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_04_03_191813_add_meta_description_to_regions_table.php: -------------------------------------------------------------------------------- 1 | json('meta_description')->after('description')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('regions', function (Blueprint $table) { 29 | $table->dropColumn('meta_description'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_04_28_131515_add_force_label_to_vehicles_table.php: -------------------------------------------------------------------------------- 1 | string('force_label')->after('label')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('vehicles', function (Blueprint $table) { 29 | $table->removeColumn('force_label'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_05_06_105155_change_column_type_of_icon_on_alerts_table.php: -------------------------------------------------------------------------------- 1 | text('icon')->change(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | // No down 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2021_05_15_075131_create_job_batches_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 18 | $table->string('name'); 19 | $table->integer('total_jobs'); 20 | $table->integer('pending_jobs'); 21 | $table->integer('failed_jobs'); 22 | $table->text('failed_job_ids'); 23 | $table->mediumText('options')->nullable(); 24 | $table->integer('cancelled_at')->nullable(); 25 | $table->integer('created_at'); 26 | $table->integer('finished_at')->nullable(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('job_batches'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /database/migrations/2021_05_23_081606_add_etag_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | text('static_etag')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->removeColumn('static_etag'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_07_05_073230_create_vin_suggestions_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('vin'); 19 | $table->string('label'); 20 | $table->string('note'); 21 | $table->integer('upvotes')->default(0); 22 | $table->timestamps(); 23 | $table->index('vin'); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('vin_suggestions'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2021_07_20_080419_make_note_column_optional_in_vin_suggestions_table.php: -------------------------------------------------------------------------------- 1 | string('note')->nullable()->change(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('vin_suggestions', function (Blueprint $table) { 29 | // Keep in nullable! 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2021_10_12_165641_create_push_subscriptions_table.php: -------------------------------------------------------------------------------- 1 | create(config('webpush.table_name'), function (Blueprint $table) { 17 | $table->bigIncrements('id'); 18 | $table->morphs('subscribable'); 19 | $table->string('endpoint', 500)->unique(); 20 | $table->string('public_key')->nullable(); 21 | $table->string('auth_token')->nullable(); 22 | $table->string('content_encoding')->nullable(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::connection(config('webpush.database_connection'))->dropIfExists(config('webpush.table_name')); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2021_12_25_171237_create_notifications_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('type'); 19 | $table->morphs('notifiable'); 20 | $table->text('data'); 21 | $table->timestamp('read_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('notifications'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2022_03_19_190522_add_is_rejected_field_to_vin_suggestions_table.php: -------------------------------------------------------------------------------- 1 | boolean('is_rejected')->default(false); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('vin_suggestions', function (Blueprint $table) { 29 | $table->dropColumn('is_rejected'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2022_06_21_153225_create_notification_user_vehicle_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('notification_user_id'); 18 | $table->unsignedInteger('vehicle_id'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::dropIfExists('notification_user_vehicle'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/migrations/2022_08_17_155857_create_tags_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->json('label'); 19 | $table->json('short_label')->nullable(); 20 | $table->text('icon')->nullable(); 21 | $table->string('color'); 22 | $table->string('dark_color'); 23 | $table->string('text_color'); 24 | $table->string('dark_text_color'); 25 | $table->boolean('show_on_map'); 26 | $table->timestamps(); 27 | }); 28 | 29 | Schema::create('taggables', function (Blueprint $table) { 30 | $table->unsignedInteger('tag_id'); 31 | $table->unsignedInteger('taggable_id'); 32 | $table->string('taggable_type'); 33 | }); 34 | } 35 | 36 | /** 37 | * Reverse the migrations. 38 | * 39 | * @return void 40 | */ 41 | public function down() 42 | { 43 | Schema::dropIfExists('tags'); 44 | Schema::dropIfExists('taggables'); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /database/migrations/2022_09_03_202648_add_description_column_to_tags_table.php: -------------------------------------------------------------------------------- 1 | json('description')->nullable()->after('short_label'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('tags', function (Blueprint $table) { 29 | $table->dropColumn('description'); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_01_10_113851_create_information_table.php: -------------------------------------------------------------------------------- 1 | string('vin', 17)->primary()->unique(); 18 | $table->string('make'); 19 | $table->string('model'); 20 | $table->unsignedInteger('year'); 21 | $table->unsignedInteger('length')->nullable(); 22 | $table->string('engine')->nullable(); 23 | $table->string('assembly')->nullable(); 24 | $table->string('fuel')->nullable(); 25 | $table->string('sequence')->nullable(); 26 | $table->json('others')->nullable(); 27 | $table->timestamps(); 28 | $table->index('make'); 29 | $table->index('model'); 30 | $table->index(['make', 'model']); 31 | }); 32 | } 33 | 34 | /** 35 | * Reverse the migrations. 36 | * 37 | * @return void 38 | */ 39 | public function down() 40 | { 41 | Schema::dropIfExists('information'); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /database/migrations/2023_01_11_132413_add_type_to_tags_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('type')->after('short_label')->default(0); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('tags', function (Blueprint $table) { 29 | $table->dropColumn('type'); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_01_12_180809_add_force_ref_to_vehicles_table.php: -------------------------------------------------------------------------------- 1 | string('force_ref')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('vehicles', function (Blueprint $table) { 29 | $table->dropColumn('force_ref'); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_01_30_134933_add_headers_column_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | json('headers')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->dropColumn('headers'); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_01_30_144842_remove_realtime_options_column_from_agencies_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('realtime_options'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('agencies', function (Blueprint $table) { 29 | $table->json('realtime_options')->nullable(); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_02_09_171511_create_stops_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->unsignedInteger('agency_id'); 19 | $table->string('gtfs_stop_id'); 20 | $table->string('code')->nullable(); 21 | $table->string('name')->nullable(); 22 | $table->point('position')->nullable(); 23 | $table->index(['agency_id', 'gtfs_stop_id']); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('stops'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2023_02_09_174714_add_block_id_column_to_trips_table.php: -------------------------------------------------------------------------------- 1 | string('gtfs_block_id')->after('trip_id')->nullable(); 18 | $table->index(['agency_id', 'gtfs_block_id']); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('trips', function (Blueprint $table) { 30 | $table->dropColumn('gtfs_block_id'); 31 | $table->dropIndex(['agency_id', 'gtfs_block_id']); 32 | }); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /database/migrations/2023_02_09_200714_create_stop_times_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->unsignedInteger('agency_id'); 19 | $table->string('gtfs_trip_id'); 20 | $table->string('gtfs_stop_id'); 21 | $table->time('departure'); 22 | $table->unsignedInteger('sequence'); 23 | $table->index(['agency_id', 'gtfs_trip_id']); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('stop_times'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2023_02_12_044038_add_subtitle_column_to_alerts_table.php: -------------------------------------------------------------------------------- 1 | json('subtitle')->after('title'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('alerts', function (Blueprint $table) { 29 | $table->dropColumn('subtitle'); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_04_22_154931_create_shapes_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->unsignedInteger('agency_id'); 17 | $table->string('gtfs_shape_id'); 18 | $table->lineString('shape'); 19 | $table->unsignedFloat('total_distance')->nullable(); 20 | $table->unique(['agency_id', 'gtfs_shape_id']); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('shapes'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_05_06_165714_add_index_to_vehicles_table.php: -------------------------------------------------------------------------------- 1 | index(['agency_id', 'is_active']); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('vehicles', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_05_17_115746_add_slug_column_to_tags_table.php: -------------------------------------------------------------------------------- 1 | string('slug')->nullable(); 16 | $table->unique('slug'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('tags', function (Blueprint $table) { 26 | $table->dropUnique('slug'); 27 | $table->dropColumn('slug'); 28 | }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /database/migrations/2023_05_28_112530_add_exo_vin_fields_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('exo_order_id')->nullable()->after('slug'); 16 | $table->string('name_slug')->unique()->nullable()->after('slug'); 17 | $table->longText('area_path')->nullable()->after('slug'); 18 | $table->boolean('is_exo_sector')->default(false)->after('slug'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down(): void 26 | { 27 | Schema::table('agencies', function (Blueprint $table) { 28 | $table->dropColumn(['exo_order_id', 'name_slug', 'area_path', 'is_exo_sector']); 29 | }); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /database/migrations/2023_07_31_201242_add_is_archived_column_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | boolean('is_archived')->default(false)->after('is_active'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('agencies', function (Blueprint $table) { 25 | $table->dropColumn('is_archived'); 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_09_11_153329_add_last_updated_at_field_to_vehicles_table.php: -------------------------------------------------------------------------------- 1 | dateTime('last_seen_at')->nullable()->after('updated_at'); 17 | }); 18 | 19 | Vehicle::whereNotNull('timestamp') 20 | ->select(['id']) 21 | ->update([ 22 | 'last_seen_at' => DB::raw('FROM_UNIXTIME(timestamp)'), 23 | ]); 24 | 25 | Vehicle::whereNull('timestamp') 26 | ->select(['id']) 27 | ->update([ 28 | 'last_seen_at' => DB::raw('updated_at'), 29 | ]); 30 | } 31 | 32 | /** 33 | * Reverse the migrations. 34 | */ 35 | public function down(): void 36 | { 37 | Schema::table('vehicles', function (Blueprint $table) { 38 | $table->dropColumn('last_seen_at'); 39 | }); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /database/migrations/2023_09_21_112833_add_features_column_to_agencies_table.php: -------------------------------------------------------------------------------- 1 | json('features')->nullable(); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('agencies', function (Blueprint $table) { 25 | $table->dropColumn('features'); 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2024_10_17_113349_add_is_active_field_to_links_table.php: -------------------------------------------------------------------------------- 1 | boolean('is_active')->default(true); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('links', function (Blueprint $table) { 25 | $table->dropColumn('is_active'); 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(RegionsTableSeeder::class); 17 | $this->call(AgenciesTableSeeder::class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /database/vin/MCI/MCI.php: -------------------------------------------------------------------------------- 1 | 'J3500/J4500', 7 | '2' => 'D4000/D4500', 8 | '3' => 'D4000 ISTV', 9 | '4' => 'D40/D45 CRT LE', 10 | '5' => 'D4020/D4520', 11 | '6' => 'D4020 ISTV', 12 | '7' => 'D4005/D4505', 13 | ]; 14 | 15 | const PROPULSION = [ 16 | 'B' => 'Battery Electric', 17 | 'C' => 'Compressed Natual Gas', 18 | 'D' => 'Diesel', 19 | 'H' => 'Hybrid-Electric', 20 | ]; 21 | 22 | const LENGTH = [ 23 | 'F' => 40, 24 | 'K' => 35, 25 | 'W' => 45, 26 | ]; 27 | 28 | const ENGINE = [ 29 | '2' => 'Cummins ISL 8.9 & 9L Hybrid-Electric, 330 HP, 6 Cyls., Diesel', 30 | '3' => 'Cummins ISX12-G, 400 HP, 6 Cyls., 11.9L, CNG', 31 | '4' => 'Cummins ISL 8.9 & 9L, 380 HP, 6 Cyls., Diesel', 32 | '5' => 'Cummins ISX 11.9 & 12L, 385/425 HP, 6 Cyls., Diesel', 33 | '6' => 'Cummins ISL-G 8.9 & 9L, 320 HP, 6 Cyls., CNG', 34 | '8' => 'Detroit Diesel DD13 12.7L, 410/450 HP, 6 Cyls., Diesel', 35 | '9' => 'Cummins X12 410/455 HP, 6 Cyls, 11.8L, Diesel', 36 | 'E' => 'Cummins L9 350HP, 6 Cyls., 8.9L, Diesel', 37 | 'F' => 'Cummins ISX12-N, 400 HP, 6 Cyls., 11.9L, CNG', 38 | 'H' => 'Siemens PEM 750V, 320KW moto', 39 | ]; 40 | 41 | const ASSEMBLY = [ 42 | 'C' => 'Crookston, MN', 43 | 'P' => 'Pembina, ND', 44 | 'W' => 'Winnipeg, MB', 45 | ]; 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "transit-tracker-backend", 3 | "author": "Félix Desjardins", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build" 8 | }, 9 | "devDependencies": { 10 | "@alpinejs/collapse": "^3.12.3", 11 | "@tailwindcss/forms": "^0.4.0", 12 | "@tailwindcss/typography": "^0.5.9", 13 | "alpinejs": "^3.12.3", 14 | "autoprefixer": "^10.4.8", 15 | "laravel-vite-plugin": "^0.6.1", 16 | "postcss": "^8.3.5", 17 | "prettier": "2.3.1", 18 | "prettier-plugin-tailwindcss": "^0.2.7", 19 | "tailwind-m3-colors": "^0.0.6-git", 20 | "tailwindcss": "^3", 21 | "vite": "^3.1.8" 22 | }, 23 | "dependencies": { 24 | "@fontsource/figtree": "^4.5.1", 25 | "@fontsource/inter": "^4.5.13", 26 | "print-gtfs-rt-cli": "^3.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/.idea/gtfs-realtime-protobuf-php.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "felixinx/gtfs-realtime-protobuf-php", 3 | "description": "GTFS Realtime binding using protobuf-php", 4 | "version": "0.1.0", 5 | "authors": [ 6 | { 7 | "name": "Félix Desjardins" 8 | } 9 | ], 10 | "require": { 11 | "protobuf-php/protobuf": "^0.1.3", 12 | "google/protobuf": "^3.15" 13 | }, 14 | "require-dev": { 15 | "protobuf-php/protobuf-plugin": "^0.1.3" 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "FelixINX\\TransitRealtime\\": "src/" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/src/FeedHeader/Incrementality.php: -------------------------------------------------------------------------------- 1 | FelixINX.TransitRealtime.FeedHeader.Incrementality 15 | */ 16 | class Incrementality 17 | { 18 | /** 19 | * Generated from protobuf enum FULL_DATASET = 0; 20 | */ 21 | const FULL_DATASET = 0; 22 | /** 23 | * Generated from protobuf enum DIFFERENTIAL = 1; 24 | */ 25 | const DIFFERENTIAL = 1; 26 | } 27 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/src/VehiclePosition/CongestionLevel.php: -------------------------------------------------------------------------------- 1 | FelixINX.TransitRealtime.VehiclePosition.CongestionLevel 11 | */ 12 | class CongestionLevel 13 | { 14 | /** 15 | * Generated from protobuf enum UNKNOWN_CONGESTION_LEVEL = 0; 16 | */ 17 | const UNKNOWN_CONGESTION_LEVEL = 0; 18 | /** 19 | * Generated from protobuf enum RUNNING_SMOOTHLY = 1; 20 | */ 21 | const RUNNING_SMOOTHLY = 1; 22 | /** 23 | * Generated from protobuf enum STOP_AND_GO = 2; 24 | */ 25 | const STOP_AND_GO = 2; 26 | /** 27 | * Generated from protobuf enum CONGESTION = 3; 28 | */ 29 | const CONGESTION = 3; 30 | /** 31 | * People leaving their cars. 32 | * 33 | * Generated from protobuf enum SEVERE_CONGESTION = 4; 34 | */ 35 | const SEVERE_CONGESTION = 4; 36 | } 37 | -------------------------------------------------------------------------------- /packages/felixinx/gtfs-realtime-protobuf-php/src/VehiclePosition/VehicleStopStatus.php: -------------------------------------------------------------------------------- 1 | FelixINX.TransitRealtime.VehiclePosition.VehicleStopStatus 9 | */ 10 | class VehicleStopStatus 11 | { 12 | /** 13 | * The vehicle is just about to arrive at the stop (on a stop 14 | * display, the vehicle symbol typically flashes). 15 | * 16 | * Generated from protobuf enum INCOMING_AT = 0; 17 | */ 18 | const INCOMING_AT = 0; 19 | /** 20 | * The vehicle is standing at the stop. 21 | * 22 | * Generated from protobuf enum STOPPED_AT = 1; 23 | */ 24 | const STOPPED_AT = 1; 25 | /** 26 | * The vehicle has departed and is in transit to the next stop. 27 | * 28 | * Generated from protobuf enum IN_TRANSIT_TO = 2; 29 | */ 30 | const IN_TRANSIT_TO = 2; 31 | } 32 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/larastan/larastan/extension.neon 3 | - vendor/bensampo/laravel-enum/extension.neon 4 | 5 | parameters: 6 | 7 | paths: 8 | - app 9 | 10 | # The level 9 is the highest level 11 | level: 5 12 | 13 | ignoreErrors: 14 | - '#Call to an undefined method Spatie[a-zA-Z0-9\\_]+::forUrls\(\)#' 15 | 16 | excludePaths: 17 | - *Http/Resources/* 18 | 19 | checkMissingIterableValueType: false 20 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["packages"] 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/favicon.ico -------------------------------------------------------------------------------- /public/img/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/badge.png -------------------------------------------------------------------------------- /public/img/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/demo.png -------------------------------------------------------------------------------- /public/img/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-192.png -------------------------------------------------------------------------------- /public/img/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-512.png -------------------------------------------------------------------------------- /public/img/icon-ios-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-ios-120.png -------------------------------------------------------------------------------- /public/img/icon-ios-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-ios-152.png -------------------------------------------------------------------------------- /public/img/icon-ios-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-ios-167.png -------------------------------------------------------------------------------- /public/img/icon-ios-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-ios-180.png -------------------------------------------------------------------------------- /public/img/icon-ios-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-ios-512.png -------------------------------------------------------------------------------- /public/img/icon-mask-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-mask-192.png -------------------------------------------------------------------------------- /public/img/icon-mask-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/icon-mask-512.png -------------------------------------------------------------------------------- /public/img/onboarding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/onboarding.png -------------------------------------------------------------------------------- /public/img/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/open-graph.png -------------------------------------------------------------------------------- /public/img/twitter-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/public/img/twitter-card.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/svg/icons/tt-custom-ferry.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/icons/tt-custom-gondola.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/icons/tt-custom-subway.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/icons/tt-custom-tram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/icons/tt-grt-tram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/icons/tt-ttc-tram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | -------------------------------------------------------------------------------- /resources/css/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | import "@fontsource/inter/400.css"; 2 | import "@fontsource/inter/500.css"; 3 | import "@fontsource/inter/600.css"; 4 | import "@fontsource/inter/700.css"; 5 | import "@fontsource/figtree/700.css"; 6 | 7 | import Alpine from 'alpinejs' 8 | import collapse from '@alpinejs/collapse' 9 | 10 | Alpine.plugin(collapse) 11 | 12 | window.Alpine = Alpine 13 | Alpine.start() 14 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 5 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 6 | ]; 7 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | 'Next »', 5 | 'previous' => '« Previous', 6 | ]; 7 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 5 | 'reset' => 'Your password has been reset!', 6 | 'sent' => 'We have e-mailed your password reset link!', 7 | 'token' => 'This password reset token is invalid.', 8 | 'user' => 'We can\'t find a user with that e-mail address.', 9 | ]; 10 | -------------------------------------------------------------------------------- /resources/lang/en/push.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'action_gtfstools' => '⏭️ Departures', 6 | 'action_track' => '📍 Track', 7 | 'body' => ':label made his first appearance today, on route :route', 8 | 'title' => '⚡ :label is on route :headsign!', 9 | ], 10 | 'new_vehicle' => [ 11 | 'action' => '📍 Track in the app', 12 | 'body' => ':label has appeared for this first time, on route :route', 13 | 'title' => ':emoji New :type! :label | :agency', 14 | ], 15 | 'updated_vehicle' => [ 16 | 'action_track' => '📍 Track', 17 | 'body' => ':label made his first appearance today', 18 | 'title' => ':emoji :label is on route :route!', 19 | ], 20 | 'welcome' => [ 21 | 'body' => 'You can change your subscriptions or unsubscribe at any time in the notification centre.', 22 | 'title' => 'Subscription activated for Transit Tracker!', 23 | ], 24 | ]; 25 | -------------------------------------------------------------------------------- /resources/lang/fr/enums.php: -------------------------------------------------------------------------------- 1 | [ 5 | '0' => 'Niveau de congestion inconnu', 6 | '1' => 'Aucune congestion', 7 | '2' => 'Faible congestion', 8 | '3' => 'Congestion', 9 | '4' => 'Congestion sévère', 10 | ], 11 | 'App\\Enums\\OccupancyStatus' => [ 12 | '0' => 'Vide', 13 | '1' => 'Plusieurs sièges disponibles', 14 | '2' => 'Quelques sièges disponibles', 15 | '3' => 'Places debout seulement', 16 | '4' => 'Quelques places debout seulement', 17 | '5' => 'Plein', 18 | '6' => 'N\'accepte plus de passagers', 19 | '7' => 'Pas de données disponibles', 20 | '8' => 'Embarquement interdit', 21 | ], 22 | 'App\\Enums\\ScheduleRelationship' => [ 23 | '0' => 'Prévu', 24 | '1' => 'Ajouté', 25 | '2' => 'Non prévu', 26 | '3' => 'Annulé', 27 | ], 28 | 'App\\Enums\\TagType' => [ 29 | '0' => 'Non spécifié', 30 | '1' => 'Centre de transport de la STM', 31 | '2' => 'Opérateur', 32 | ], 33 | 'App\\Enums\\VehicleStopStatus' => [ 34 | '0' => 'Arrive au prochain arrêt', 35 | '1' => 'À l\'arrêt', 36 | '2' => 'En déplacement', 37 | ], 38 | ]; 39 | -------------------------------------------------------------------------------- /resources/lang/fr/push.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'action_gtfstools' => '⏭️ Départs', 6 | 'action_track' => '📍 Suivre', 7 | 'body' => ':label a fait sa première apparition aujourd\'hui, sur la route :route', 8 | 'title' => '⚡ :label est sur la route :headsign!', 9 | ], 10 | 'new_vehicle' => [ 11 | 'action' => '📍 Suivre', 12 | 'body' => ':label est apparu pour la première fois, sur la route :route', 13 | 'title' => ':emoji Nouveau :type! :label | :agency', 14 | ], 15 | 'updated_vehicle' => [ 16 | 'action_track' => '📍 Suivre', 17 | 'body' => ':label a fait sa première apparition aujourd\'hui', 18 | 'title' => ':emoji :label est sur la route :route!', 19 | ], 20 | 'welcome' => [ 21 | 'body' => 'Vous pouvez modifier vos abonnements ou vous désabonner à tout moment via le centre de notification.', 22 | 'title' => 'Abonnement activé pour Transit Tracker!', 23 | ], 24 | ]; 25 | -------------------------------------------------------------------------------- /resources/lang/fr/transittracker.php: -------------------------------------------------------------------------------- 1 | '', 5 | ]; 6 | -------------------------------------------------------------------------------- /resources/lang/vendor/laravelEnum/en/messages.php: -------------------------------------------------------------------------------- 1 | __('The value you have provided is not a valid enum instance.'), 5 | 'enum_value' => __('The value you have entered is invalid.'), 6 | 'enum_key' => __('The key you have entered is invalid.'), 7 | ]; -------------------------------------------------------------------------------- /resources/lang/vendor/laravelEnum/fr/messages.php: -------------------------------------------------------------------------------- 1 | __("La valeur que vous avez fournie n'est pas une instance d'énumération valide."), 5 | 'enum_value' => __("La valeur que vous avez saisie n'est pas valide."), 6 | 'enum_key' => __("La clé que vous avez saisie n'est pas valide."), 7 | ]; -------------------------------------------------------------------------------- /resources/views/components/button/filled.blade.php: -------------------------------------------------------------------------------- 1 | class(['group relative flex h-10 items-center justify-center gap-2 overflow-hidden rounded-full text-sm font-medium leading-5 bg-primary-40 dark:bg-primary-80 text-white dark:text-primary-20', 'pl-4 pr-6' => $hasLeftIcon, 'px-5' => !$hasLeftIcon && !$hasRightIcon, 'pr-4 pl-6' => $hasRightIcon]) }}> 2 |
4 |
5 | {{ $slot }} 6 |
7 | -------------------------------------------------------------------------------- /resources/views/components/button/text.blade.php: -------------------------------------------------------------------------------- 1 | class(['group relative flex h-10 items-center justify-center gap-2 overflow-hidden rounded-full text-sm font-medium leading-5 text-primary-40 dark:text-primary-80', 'pl-4 pr-6' => $hasIcon, 'px-5' => !$hasIcon]) }}> 2 |
4 |
5 | {{ $slot }} 6 |
7 | -------------------------------------------------------------------------------- /resources/views/components/icon-button/standard.blade.php: -------------------------------------------------------------------------------- 1 | class(['group relative h-10 w-10 overflow-hidden rounded-full text-neutralVariant-30 dark:text-neutralVariant-80 p-2']) }}> 2 |
4 |
5 | {{ $slot }} 6 |
7 | -------------------------------------------------------------------------------- /resources/views/errors/401.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Unauthorized')) 4 | @section('code', '401') 5 | @section('message', __('Unauthorized')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Forbidden')) 4 | @section('code', '403') 5 | @section('message', __($exception->getMessage() ?: 'Forbidden')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::illustrated-layout') 2 | 3 | @section('title', __('Not Found')) 4 | @section('code', '404') 5 | @section('message', __('Not Found')) 6 | @section('image') 7 |
8 | @endsection 9 | -------------------------------------------------------------------------------- /resources/views/errors/419.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Page Expired')) 4 | @section('code', '419') 5 | @section('message', __('Page Expired')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/429.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Too Many Requests')) 4 | @section('code', '429') 5 | @section('message', __('Too Many Requests')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/500.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Server Error')) 4 | @section('code', '500') 5 | @section('message', __('Server Error')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Service Unavailable')) 4 | @section('code', '503') 5 | @section('message', __($exception->getMessage() ?: 'Service Unavailable')) 6 | -------------------------------------------------------------------------------- /resources/views/errors/maintenance.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Transit Tracker | Maintenance mode 8 | 9 | 10 | 27 | 28 | -------------------------------------------------------------------------------- /resources/views/filament/fields-helper/bbox.blade.php: -------------------------------------------------------------------------------- 1 |

2 | Format: minLongitude,minLatitude,maxLongitude,maxLatitude
3 | Use bboxfinder and copy Box. 4 |

-------------------------------------------------------------------------------- /resources/views/filament/widgets/welcome-admin.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | New feature : edit from the app 5 | 6 | 7 | 8 | To make modifications easier, you can now activate a new button that will appear in the list or when selecting a vehicle on the map. 9 | 10 | 16 | Activate this feature 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /resources/views/tables/columns/tag-preview.blade.php: -------------------------------------------------------------------------------- 1 |
2 | @if($getRecord()->icon) 3 | 4 | 5 | 6 | @endif 7 | {{ $getRecord()->label }} 8 |
9 | 10 | 16 | -------------------------------------------------------------------------------- /resources/views/vin/error.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |

6 | {{ __('This VIN does not exist in the database.') }} 7 | {{ __('Return to home page') }}. 8 |

9 |
10 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /routes/admin.php: -------------------------------------------------------------------------------- 1 | middleware('signed')->group(function () { 8 | Route::get('agencies/{agency}/update', [AgencyController::class, 'update'])->name('internal.agencies.static-update'); 9 | Route::get('failed-job/{failedJob}/snooze/{hours}', [FailedJobController::class, 'snooze'])->name('internal.failed-jobs.snooze'); 10 | }); 11 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /routes/vin.php: -------------------------------------------------------------------------------- 1 | back(); 18 | })->name('locale'); 19 | 20 | // VIN routes 21 | Route::get('', [SuggestionController::class, 'index'])->name('vin.index'); 22 | Route::get('{vin}', [VehicleController::class, 'show'])->name('vin.show'); 23 | Route::post('{vin}', [SuggestionController::class, 'store'])->name('vin.store'); 24 | Route::get('sector/{sector}', [AgencyController::class, 'show'])->name('vin.agency.show'); 25 | Route::get('operator/{tagSlug}', [OperatorController::class, 'show'])->name('vin.operator.show'); 26 | Route::post('vin/{suggestion}/vote', [SuggestionController::class, 'vote'])->name('vin.vote'); 27 | Route::post('vin/{suggestion}/approve/{agency?}', [SuggestionController::class, 'approve'])->middleware('auth')->name('vin.approve'); 28 | Route::post('vin/{suggestion}/reject', [SuggestionController::class, 'reject'])->middleware('auth')->name('vin.reject'); 29 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | segment(1) === 'vin') { 5 | return redirect(route('vin.index'))->with('from-api', true); 6 | } 7 | 8 | return redirect()->route('scribe'); 9 | }); 10 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | $uri = urldecode( 9 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 10 | ); 11 | 12 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 13 | // built-in PHP web server. This provides a convenient way to test a Laravel 14 | // application without having installed a "real" web server software here. 15 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 16 | return false; 17 | } 18 | 19 | require_once __DIR__.'/public/index.php'; 20 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !content 3 | !content/alerts 4 | !content/regions 5 | !shapes 6 | !.gitignore 7 | -------------------------------------------------------------------------------- /storage/app/public/content/alerts/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/public/content/regions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/realtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/static/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/tests/Feature/ExampleTest.php -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/tests/TestCase.php -------------------------------------------------------------------------------- /tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitTracker/backend/e7f386a1750a795b50f0302f1c55e2ea6ea8530d/tests/Unit/ExampleTest.php -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import laravel from "laravel-vite-plugin"; 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel({ 7 | input: ["resources/css/app.css", "resources/js/app.js"], 8 | }), 9 | ], 10 | }); 11 | --------------------------------------------------------------------------------