Jonathan Contreras homepageJonathan Contreras
HomeAboutProjectsBlogUsesServicesContact

Jonathan Contreras

Full-Stack Developer & CS Student passionate about creating meaningful digital experiences through code.

Quick Links

HomeAboutProjectsBlogUsesServicesContact

Get in Touch

[email protected]

Houston, TX

GitHubLinkedInRSSResume

© 2026 Jonathan Contreras. All rights reserved.

Back to Projects

At A Glance Page

Built the public At-A-Glance Statistics webpage, transforming crime data into a responsive and accessible UI. Designed secure API routes and a hybrid data-ingestion pipeline to fetch, aggregate, and cache data from internal systems and vetted public feeds, enabling low-latency updates while safeguarding sensitive information.

Next.jsTailwind CSSJavaScriptPythonSQL
Live Demo
At A Glance Page
<2s
Page Load Time
2
Data Sources
Daily
Update Frequency

The Problem

Crime data is complex, scattered across multiple sources, and often inaccessible to the general public. Community members, researchers, and policymakers needed a way to quickly understand crime trends without navigating technical databases or requesting custom reports.

The Glenda Gordy Research Center needed a public-facing solution that could display real-time crime statistics while protecting sensitive internal data and maintaining performance under varying traffic loads.

My Approach

I designed a hybrid data-ingestion pipeline that safely bridges internal systems with public-facing displays. The architecture prioritizes security, performance, and maintainability.

The solution uses Next.js API routes as a secure gateway, implementing caching strategies to minimize database load while ensuring data freshness. Python scripts handle data aggregation from multiple sources, transforming raw crime data into user-friendly statistics.

The frontend leverages Tailwind CSS for a responsive, accessible design that works seamlessly across devices. The UI presents complex data through interactive charts and clear visualizations that make insights immediately understandable.

Visual Showcase

At A Glance Statistics Dashboard

Main dashboard showing crime statistics with interactive charts

Technical Deep Dive

Why Next.js API Routes? They provide a serverless architecture that scales automatically and keeps sensitive database credentials secure. The API layer acts as a controlled gateway, sanitizing requests and implementing rate limiting.

Why Python for Data Processing? Python's data science ecosystem (pandas, NumPy) made it ideal for complex data transformations and aggregations. The scripts run on a scheduled basis, pre-computing statistics to minimize real-time processing.

The caching strategy uses a multi-tier approach: in-memory caching for frequently accessed data, database-level caching for aggregated statistics, and CDN caching for static visualizations. This reduces API response times from seconds to milliseconds.

Security was paramount. The system implements input validation, parameterized queries to prevent SQL injection, and strict data access controls. Public endpoints expose only pre-approved, aggregated data—never raw records.

Challenges & Lessons

Initial Challenge: Balancing data freshness with performance. Real-time queries were too slow for a public-facing page. Solution: Implemented intelligent caching with configurable TTLs based on data volatility.

Data Consistency: Multiple data sources with different update schedules created synchronization challenges. I implemented a reconciliation layer that handles discrepancies and marks data staleness clearly in the UI.

Accessibility: Making complex charts accessible required significant work. I added ARIA labels, keyboard navigation, and text alternatives for all visualizations.

Key Lesson: Public data presentation requires a completely different architecture than internal tools. What works for authenticated users with patience doesn't work for the general public expecting instant insights.

If I built this again, I'd implement a GraphQL API for more flexible data queries and consider real-time updates using WebSockets for live statistics displays.

Want to see it in action?

Explore the live application or dive into the source code to see how it works.

Live Demo