Skip to content

Commit e44130c

Browse files
authored
Merge pull request #1570 from cityofaustin/v2.2.0
v2.2.0
2 parents 8dd7efd + f579a2e commit e44130c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+572
-3319
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ RR_DATABASE=""
3838
3. Start the DB
3939

4040
```shell
41-
$ vision-zero replicate-db
41+
./vision-zero replicate-db
4242
```
4343

4444
This command will:
4545

4646
- Download a snapshot of the production database
47-
- Store the file in `./atd-vzd/snapshots/visionzero-{date}-{with|without}-change-log.sql
47+
- Store the file in `./database/snapshots/visionzero-{date}-{with|without}-change-log.sql
4848
- Drop local `atd_vz_data` database
4949
- Create and repopulate the database from the snapshot
5050

@@ -53,7 +53,7 @@ Note: the `-f / --filename` flag can be optionally used to point to a specific d
5353
4. Start the Vision Zero Editor
5454

5555
```shell
56-
$ vision-zero vze-up
56+
vision-zero vze-up
5757
```
5858

5959
See [here](docs/local_dev.md) for in-depth documentation about the `vision-zero` helper.
@@ -64,8 +64,8 @@ See [here](docs/local_dev.md) for in-depth documentation about the `vision-zero`
6464
- [Vision Zero Editor (VZE)](./editor/README.md) - web application which enables City staff to browse and edit crash data
6565
- [Vision Zero Viewer (VZV)](./viewer/README.md) - public dashboard which provides key metrics and insights about
6666
- [atd-cr3-api](./atd-cr3-api/README.md) - our API that securely downloads a private file from S3
67-
- [atd-etl](./etl/README.md) - integration scripts for bringing data in the Vision Zero Database
68-
- [atd-toolbox](./toolbox/README.md) - collection of utilities and scripts designed for ad-hoc maintenance tasks
67+
- [etl](./etl/README.md) - integration scripts for bringing data in the Vision Zero Database
68+
- [toolbox](./toolbox/README.md) - collection of utilities and scripts designed for ad-hoc maintenance tasks
6969

7070
## License
7171

database/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
FROM frankinaustin/postgis-multiarch:14-3.3
22
RUN apt-get update
3-
RUN apt-get install -y aptitude magic-wormhole vim
3+
RUN apt-get install -y aptitude vim

database/README.md

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
The Vision Zero Database (VZD) is a Postgresql database that serves as the central repository of Austin's traffic crash data. The database is fronted with a GraphQL API, powered by [Hasura](https://github.com/hasura/graphql-engine), which is also used to manage schema migrations.
44

5-
The design supports an editing environment which enables Vision Zero program staff to edit and enrich crash data, while also allowing record updates to flow into the database from upstream sources, such as the TxDOT Crash Information System (CRIS).
5+
The design supports an editing environment which enables Vision Zero program staff to edit and enrich crash data, while also allowing record updates to flow into the database from upstream sources, such as the TxDOT Crash Records Information System (CRIS).
66

77
![vision zero data flow](../docs/images/data_flow.png)
88

@@ -19,7 +19,7 @@ The design supports an editing environment which enables Vision Zero program sta
1919
- [Audit fields](#audit-fields)
2020
- [Change logs](#change-logs)
2121
- [Austin Fire Department (AFD) and Travis County Emergency Medical Services (EMS) (todo)](#austin-fire-department-afd-and-travis-county-emergency-medical-services-ems-todo)
22-
- [Geospatial layers (todo)](#geospatial-layers-todo)
22+
- [Geospatial layers](#geospatial-layers)
2323
- [Common maintenance tasks](#common-maintenance-tasks)
2424
- [Add a new CRIS-managed column to `crashes`, `units`, or `people`](#add-a-new-cris-managed-column-to-crashes-units-or-people)
2525
- [Add a custom column to `crashes`, `units`, or `people`](#add-a-custom-column-to-crashes-units-or-people)
@@ -75,7 +75,41 @@ The process for updating `units` and `people` behaves in the same manner as `cra
7575

7676
#### CRIS Extract configuration and accounts
7777

78-
TODO. See https://app.gitbook.com/o/-LzDQOVGhTudbKRDGpUA/s/-M4Ul-hSBiM-3KkOynqS/vision-zero-crash-database/visionzero-sftp-etl#getting-extracts-manually
78+
The team maintains multiple CRIS login accounts to manage the delivery of CRIS data to our AWS S3 ingest bucket. See the [CRIS import ETL documentation](../etl/cris_import/README.md) for more information on how CRIS data is delivered to S3 and imported into our database.
79+
80+
The credentials for our CRIS logins are in the password store, including a note in the title indicating each login's purpose:
81+
82+
- **Production extract account**: this is the account which is configured for daily delivery of extracts to S3 production.
83+
- **Dev/testing extract account**: this account should be used for requesting ad-hoc CRIS extracts for delivery via S3 or manual download.
84+
- **Query & analyze account**: this account can be used for the CRIS query interface, that enables querying and access to individual crash records.
85+
86+
Additional information about CRIS access can be found on the [TxDOT website](https://www.txdot.gov/data-maps/crash-reports-records/crash-data-analysis-statistics.html).
87+
88+
Follow these steps to configure a new extract delivery:
89+
90+
1. Login to CRIS using the appropriate account (see above): https://cris.dot.state.tx.us/
91+
92+
2. From the **My Extract Requests** page, click **Add**, and follow the extract request wizard
93+
94+
- **Extract Type**: Standard
95+
- **Extract Format**: CSV
96+
- **Include CR-3 Crash Report files in Extract**: Yes (checked)
97+
98+
![CRIS extract config - page 1](../docs/images/extract_config_1.png)
99+
100+
- **Include Crash Reports From**: Specific Counties: `Hays`, `Travis`, and `Williamson`
101+
102+
- **Include Crash Reports From**: Process Date range
103+
- If you are backfilling, include a day before your target day as a buffer.
104+
- If you request a process date of today, the extract will not deliver until the next day.
105+
- To set up a recurring request, add a range of dates that ends in the future.
106+
107+
Any part of the range that falls in the past will be delivered in single zip that is separate from the zips that will deliver in the future. The includes - all records with process dates available including today.
108+
109+
Any part of the range that is in the future will create daily zips that include each day available going forward. For example, on 4/19/2024, you make a request for Process Begin Date = 01/01/2024 and Process End Date = 12/31/2024 The would receive two zips: One containing all records with process date from 01/01/2024 to 04/18/2024, and one containing all records with process date from 04/19/2024 to 04/19/2024. Going forward, you will receive one zip per day for each process date that passes
110+
111+
- **Extract password**: the password called `EXTRACT_PASSWORD` from Vision Zero CRIS Import 1Password item
112+
- **Delivery**: How you want to receive it. Typically you would use the pre-configured AWS option, specifiyng the `dev`, `staging`, or `prod` inbox subdirectory. See the CRIS import ETL readme for more details.
79113

80114
#### CRIS data processing
81115

@@ -121,7 +155,7 @@ For example, consider the `lookups.injry_sev` table, which includes a custom val
121155
| 99 | KILLED (NON-ATD) | vz |
122156
```
123157

124-
The original migration for this table is [here](https://github.com/cityofaustin/atd-vz-data/blob/e56e3c6bc654a21f667142ce53232bad44cff7e5/database/migrations/default/1715960018005_lookup_table_seeds/up.sql#L11054-L11056).
158+
The original migration for this table is [here](https://github.com/cityofaustin/vision-zero/blob/e56e3c6bc654a21f667142ce53232bad44cff7e5/atd-vzd/migrations/default/1715960018005_lookup_table_seeds/up.sql#L11054-L11056).
125159

126160
Because the table has a custom value, it is configured with a check constraint ([PostgreSQL docs](https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS)) to ensure that future updates to this lookup table do not result in an ID collision:
127161

@@ -199,19 +233,23 @@ The view `crashes_change_log_view` provides a unioned view of the unified table
199233

200234
### Austin Fire Department (AFD) and Travis County Emergency Medical Services (EMS) (todo)
201235

202-
### Geospatial layers (todo)
236+
### Geospatial layers
237+
238+
We have a number of tables which function as geospatial layers which are referenced by crashes and various other records. At the Vision Zero team's request, our team is actively working to expand the number of layers available in the database as well as add new attribute columns to crash records which will be populated based on their intersection with these layers.
203239

204-
- Council districts
205-
- Jurisdiction
206-
- Area Engineer areas
207-
- Non-COA roadways
208-
- Location polygons
240+
| Table | Geometry type | description | owner/source |
241+
| --------------------- | ------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
242+
| `council_districts` | polygon | City of Austin council districts | ArcGIS Online authoritative layer owned by CTM GIS |
243+
| `atd_jurisdictions` | polygon | City of Austin jurisdictions | ArcGIS Online authoritative layer owned by CTM GIS |
244+
| `engineering_areas` | polygon | TPW traffic engineering areas | ArcGIS Online authoritative layer owned by DTS GIS |
245+
| `non_coa_roadways` | polygon | Polygon layer covering roadways which are not maintained by the City of Austin | ArcGIS Online authoritative layer maintained by Vision Zero GIS team |
246+
| `atd_txdot_locations` | polygon | Aka, "location polygons", these shapes are used to group crashes based on an intersection or road segment | ArcGIS Online authoritative layer maintained by Vision Zero GIS team |
209247

210248
## Common maintenance tasks
211249

212250
### Add a new CRIS-managed column to `crashes`, `units`, or `people`
213251

214-
Follow these steps to add a new column to the database that will be sourced from CRIS. See [PR #1546](https://github.com/cityofaustin/atd-vz-data/pull/1546) as an example.
252+
Follow these steps to add a new column to the database that will be sourced from CRIS. See [PR #1546](https://github.com/cityofaustin/vision-zero/pull/1546) as an example.
215253

216254
1. Remember that all database operations should be deployed through migrations. See the [development and deployment](#development-and-deployment) docs.
217255
2. Add the new column to all three tables of the given record type. For example, if this is a crash-level column, add the column to the `crashes_cris`, `crashes_edits`, and `crashes` tables.
@@ -229,7 +267,7 @@ values ('drvr_lic_type_id', 'people', true);
229267

230268
```shell
231269
# ./database
232-
$ hasura metadata apply
270+
hasura metadata apply
233271
```
234272

235273
7. You are now ready to test your new column using the CRIS import ETL. If you need to backfill this new column for old records, you will need to manually request the necessary CRIS extract zip files so that they can be processed by an ad-hoc run of the CRIS import ETL.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
table:
2+
name: view_crash_narratives_ocr_todo
3+
schema: public

database/metadata/databases/default/tables/tables.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@
8686
- "!include public_units.yaml"
8787
- "!include public_units_cris.yaml"
8888
- "!include public_units_edits.yaml"
89+
- "!include public_view_crash_narratives_ocr_todo.yaml"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
drop view if exists view_crash_narratives_ocr_todo;
2+
3+
alter table crashes_edits
4+
drop column investigator_narrative_ocr_processed_at;
5+
6+
alter table crashes
7+
drop column investigator_narrative_ocr_processed_at;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
alter table crashes_edits
2+
add column investigator_narrative_ocr_processed_at timestamp with time zone;
3+
4+
alter table crashes
5+
add column investigator_narrative_ocr_processed_at timestamp with time zone;
6+
7+
comment on column crashes_edits.investigator_narrative_ocr_processed_at is 'The most recent
8+
timestamp at which the OCR process attempted to extract the investigator narrative. If null,
9+
indicates that the OCR narrative extract has never been attempted. This value should be set
10+
via ETL process.';
11+
12+
comment on column crashes.investigator_narrative_ocr_processed_at is 'The most recent
13+
timestamp at which the OCR process attempted to extract the investigator narrative. If null,
14+
indicates that the OCR narrative extract has never been attempted. This value should be set
15+
via ETL process on the crashes_edits table.';
16+
17+
create or replace view view_crash_narratives_ocr_todo as (
18+
select
19+
id,
20+
cris_crash_id
21+
from
22+
crashes
23+
where
24+
cr3_stored_fl = TRUE
25+
and investigator_narrative is NULL
26+
and (
27+
investigator_narrative_ocr_processed_at is NULL
28+
or cr3_processed_at >= investigator_narrative_ocr_processed_at
29+
)
30+
-- this issue started in Sep 2024
31+
-- we do not OCR very old crashes
32+
and updated_at > '2024-09-01'
33+
order by
34+
cr3_processed_at asc,
35+
id asc
36+
);
37+
38+
comment on view view_crash_narratives_ocr_todo is 'View which lists crashes which need to
39+
be processed by the OCR narrative extraction ETL'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
drop trigger if exists
2+
crashes_cris_preserve_investigator_narrative_on_update on crashes_cris;
3+
4+
drop function if exists
5+
public.crashes_cris_set_old_investigator_narrative;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
create or replace function public.crashes_cris_set_old_investigator_narrative()
2+
returns trigger
3+
language plpgsql
4+
as $function$
5+
begin
6+
new.investigator_narrative = old.investigator_narrative;
7+
return new;
8+
end;
9+
$function$;
10+
11+
create or replace trigger crashes_cris_preserve_investigator_narrative_on_update
12+
before update on public.crashes_cris
13+
for each row
14+
when (
15+
new.investigator_narrative is null and old.investigator_narrative is not null
16+
)
17+
execute procedure public.crashes_cris_set_old_investigator_narrative();
18+
19+
comment on function public.crashes_cris_set_old_investigator_narrative is 'Sets the
20+
investigator_narrative to its previous value if the updated value is null. This
21+
trigger function addresses a known CRIS bug in which updated crash records are
22+
missing the invesitgator narrative. It is tracked via DTS issue
23+
https://github.com/cityofaustin/atd-data-tech/issues/18971 and CRIS ticket #854366';
24+
25+
--
26+
-- backfill narratives which have been erased
27+
-- run this manually to prevent migration timeout
28+
--
29+
30+
-- update
31+
-- crashes_cris
32+
-- set
33+
-- investigator_narrative = updates_todo.investigator_narrative_old
34+
-- from (select
35+
-- record_id as crash_pk,
36+
-- crashes.investigator_narrative as investigator_narrative_new,
37+
-- record_json -> 'old' ->> 'investigator_narrative' as investigator_narrative_old
38+
-- from
39+
-- change_log_crashes_cris as changes
40+
-- left join crashes on changes.record_id = crashes.id
41+
-- where
42+
-- record_json -> 'old' ->> 'investigator_narrative' is not null
43+
-- and record_json -> 'new' ->> 'investigator_narrative' is null
44+
-- and operation_type = 'UPDATE'
45+
-- and changes.created_at > '2024-09-09'
46+
-- and changes.created_by = 'cris'
47+
-- order by
48+
-- changes.id asc) as updates_todo
49+
-- where
50+
-- crashes_cris.id = updates_todo.crash_pk;

docker-compose-docker-volume.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ services:
66
- .env
77
volumes:
88
- visionzero_postgis_pgdata:/var/lib/postgresql/data
9+
- ./database/snapshots:/snapshots
910
ports:
1011
- 5432:5432
1112

0 commit comments

Comments
 (0)