Schema and reusable cleanup
I inspected the CrimeData schema, then created cleaned_incidents to standardize field names and expose the start and end values as usable date-time fields without repeating cleanup logic.
Personal project · Public data + SQL · October — November 2025
An independent dashboard that converts Boise State’s public crime log into searchable records, trend charts, filters, and an approximate campus heatmap, with a companion BigQuery analysis.

Overview
The source log is authoritative but difficult to scan and compare. The project preserves the published fields while adding search, sorting, filtering, pagination, aggregation, and export.
Built the Cheerio scraper, data-cleaning path, derived categorization, and Next.js dashboard.
Implemented search, sorting, filtering, pagination, charts, CSV export, a MapLibre campus heatmap, mobile layouts, and reduced-motion behavior.
Imported a 197-record snapshot into Google BigQuery and wrote reusable GoogleSQL views and queries for cleanup, monthly aggregation, duration calculations, and category joins.
Kept the official public log as the source of truth and commits new JSON only when the scraped dataset changes.
Kept the public dashboard on a static dataset to reduce deployment complexity, while using BigQuery as a separate, reproducible analysis workflow rather than implying that it powers the live site.
Labels the project as unofficial and documents that categories are derived, coordinates are approximate, and updates can lag the source.
Refreshes the public dataset every 12 hours with GitHub Actions and avoids empty commits when nothing changed.
Makes source records easier to inspect through a searchable table, derived views, charts, and filtered CSV downloads.
Demonstrates web scraping, scheduled automation, visualization, responsive design, and SQL analysis with schemas, reusable views, aggregations, joins, date handling, and calculated fields.
BigQuery analysis
As a companion to the dashboard, I imported a 197-record snapshot of the public incident log into Google BigQuery for a small, reproducible analysis exercise. The GoogleSQL work covers aggregations, joins, date handling, calculated fields, and exploratory analysis; it is not presented as production-scale data warehousing.
I inspected the CrimeData schema, then created cleaned_incidents to standardize field names and expose the start and end values as usable date-time fields without repeating cleanup logic.
I created monthly_incident_summary as a reusable view and used DATE_TRUNC, COUNT, grouping, ordering, and other date handling to analyze reported incidents by month.
Additional GoogleSQL queries calculated incident duration in minutes and joined incidents to a keyword lookup table for broader category analysis, using distinct case counts to limit duplicate matches.