DIM 9000 analytics stack from zero
The brief
DIM 9000 is a property management SaaS covering residential buildings and apartments. When I joined as an intern in June 2025, analytics meant manual SQL queries, spreadsheets, and reports built on request. No warehouse, no defined metrics, no alerting.
By October 2025 I had taken full ownership of the analytics direction as the sole analytics engineer. The job: build everything from scratch and make it reliable enough that the team could actually depend on it.
What I built
Real-time ETL pipeline
Replaced a legacy daily batch process with a Python Cloud Functions pipeline syncing production PostgreSQL to BigQuery every 15 minutes. The shift from 24-hour to 15-minute data latency unlocked operational use cases that weren’t possible before — real-time building performance monitoring, same-day financial visibility.
Star Schema data warehouse
Designed a Star Schema in BigQuery with a small set of conformed dimensions:
dim_llc,dim_space,dim_building— the entities the business cares aboutfact_billing,fact_debt,fact_payments— the events and balances
One source of truth across departments. Every dashboard and report reads from the same definitions.
Operational and product dashboards
Shipped v1.0 dashboards for:
- Building/apartment performance — occupancy, financial KPIs, operational status across the portfolio
- CRM feature adoption — tracking which modules teams actually use and where the bottlenecks are
Fully replaced manual reporting workflows.
Automated Slack alerting
Built a custom anomaly detection pipeline: BigQuery → Cloud Scheduler → Cloud Function → Slack Webhook. Migrated the original Google Apps Script implementation to Python Cloud Functions v2 for reliability and scalability.
Designed to be quiet by default — alerts fire when something is actually wrong, not on every data point that moves.
SLA monitoring (“Sniper”) and daily digest
Two additional alerting layers on top:
- Sniper: instant Slack alert for critical support tickets stuck 60+ minutes without an assignee
- Daily heartbeat: automated management digest covering stale backlog (14+ days), overdue deadlines, and ticket volume per building complex
What I’d do differently
The first warehouse modeling pass had too many implicit assumptions baked into the SQL — things that made sense in the moment but required explanation later. The second iteration was deliberately more explicit: named columns, documented grain, no clever coalesces. It’s easier to read and easier to hand off.
- PostgreSQL
- BigQuery
- Python
- Cloud Functions
- Cloud Scheduler
- Slack API