Skip to content

Repository files navigation

PropSight Analytics

A synthetic property-management analytics platform built on the Databricks Lakehouse: a seeded data generator feeds a governed bronze → silver → gold medallion pipeline and a star schema that answers three executive questions in one place —

Are we full? (occupancy) · Are we getting paid? (collections & arrears) · Is anything about to break? (maintenance & sensor telemetry)

Everything here is reproducible from a fixed seed and rebuilds with a single databricks bundle run.

PropSight executive dashboard: a one-page Power BI report with six KPI cards (physical occupancy 93.5%, collection rate 94.1%, arrears balance $3.1M, open work-order backlog 16.1%, sensor anomalies 5K, data-quality pass rate 96.4%), an occupancy-and-collection trend line, an arrears-by-asset-class bar chart, a ranked exception table, and the data-quality scorecard with the one WARN check on top.

The one-page executive dashboard, built in Power BI on the Databricks gold layer. It answers the three questions above at a glance and surfaces the data-quality scorecard as a first-class panel. Reproduce it from the measures in powerbi/measures_web.dax by following powerbi/dashboard_build_guide.md.


The business problem

A property operator's data lives in separate systems that don't talk to each other — a leasing CRM, a rent ledger, a work-order system, and building sensors. Leadership can't answer basic questions across them. This project centralises those sources into one governed model and surfaces a single executive view, with data quality as a first-class, auditable deliverable — not an afterthought.

Architecture

Five scattered property systems feed one automated pipeline that brings the data together, cleans it, organizes it and checks its quality, producing one executive dashboard.

The layer-by-layer detail behind that picture:

Layer What it holds Notes
Source 12 Parquet extracts (~1.4M rows) Five simulated systems: asset master, leasing CRM, accounting, maintenance, building IoT
Bronze 12 raw tables, dirt intact +_ingested_at, +_source_file; nothing cleaned
Silver 12 conformed + 3 quarantine Typed, deduped, dates & currency parsed, statuses standardised, bad rows quarantined (never dropped)
Gold 8 dimensions + 5 facts Kimball star: IDENTITY surrogate keys, PK/FK constraints (renders an ER diagram), SCD2 dim_tenant, generated dim_date, derived fct_occupancy_daily
Quality gold.dq_check_results 28 checks per run, append log, dashboard-ready

The data-quality story — what we injected vs. what the pipeline caught

The bronze layer is deliberately dirty (the client specifically asked about validation gates and data accuracy). Injection rates live in generator/config.yaml; the pipeline's response is verifiable in the silver quarantine tables and dq_check_results.

Injected on purpose Where / rate What the pipeline did
Duplicate rows ~2% (ledger, work orders, telemetry) Deduplicated in silver via QUALIFY row_number() — ~6,700 removed
Nulls in required fields ~1% Quarantined with a reason — never silently dropped
Mixed date formats (2026-01-01, 03/01/2025, epoch 1767225600) every date column Parsed to DATE/TIMESTAMP (parse_date / parse_ts)
Currency as text ($1,250.00, (500.00)) every money column Parsed to DECIMAL(12,2) (parse_money)
Orphaned foreign keys ~0.5% of transactions Quarantined; gold facts never carry a dangling key
Whitespace + inconsistent casing names, status codes Trimmed & standardised to a controlled vocabulary

Result: ~1,950 rows quarantined (each tagged with why, and queryable), ~6,700 duplicates removed, 0 referential-integrity failures in gold (independently verified across all 19 fact→dimension foreign keys), and a 27 PASS / 1 WARN / 0 FAIL data-quality scorecard. The single warning is the telemetry anomaly flag — out-of-range sensor readings surfaced as early maintenance warnings, which is signal, not corruption.

Executive KPIs (and how they're defined)

KPI Definition Current
Physical occupancy occupied unit-days ÷ total unit-days ~93% (stable)
Economic occupancy Σ contracted rent ÷ Σ market rent (occupied + vacant) ~94%
Collection rate payments ÷ charges 94%
Lead → lease conversion leased leads ÷ total leads 17%
Work-order backlog open work orders ÷ all work orders 16%
Telemetry anomalies readings outside a device's physical range 4,803 (flagged)
Data-quality pass rate passing checks ÷ total checks (latest run) 96.4%

How to run

# 1 — Generate the synthetic source data (local, reproducible, no network)
python3 -m venv .venv && ./.venv/bin/pip install -r requirements.txt
./.venv/bin/python -m generator.generate                 # add --profile small for a fast loop

# 2 — Authenticate the Databricks CLI (once)
databricks auth login --host https://<your-workspace>    # creates a profile

# 3 — Deploy the pipeline (uploads notebooks, creates the Job)
databricks bundle deploy -t dev -p <profile>

# 4 — One-time: land the raw files in the Unity Catalog volume
databricks fs cp -r --overwrite data/raw dbfs:/Volumes/propsight/bronze/landing -p <profile>

# 5 — Rebuild the entire warehouse with one command
databricks bundle run propsight_pipeline -t dev -p <profile>

Output: propsight.bronze (12 tables) → propsight.silver (12 + 3 quarantine) → propsight.gold (8 dims + 5 facts + dq_check_results), all reconciling to the generator config.

Tech & engineering practices

  • Databricks Free Edition — serverless compute only, Unity Catalog, no external cloud services.
  • Reproducible — fixed seed, committed; the whole 1.4M-row warehouse regenerates byte-for-byte.
  • Databricks-native best practices — managed Delta tables, Liquid Clustering (not partitioning), DECIMAL for money, IDENTITY surrogate keys with RELY PK constraints, predictive optimization, SCD2 via window functions, and an Asset Bundle so the pipeline is version-controlled infra-as-code.
  • Verified, not asserted — the gold star was checked by an independent multi-agent review across reconciliation, referential integrity, SCD2 point-in-time correctness, and derived-measure correctness.

Repository layout

Repository map: generator produces the synthetic source data, notebooks 00 to 06 build the pipeline, databricks.yml and resources define the job, powerbi holds the dashboard layer, and docs holds the written detail.
generator/            seeded, config-driven data generator (Python)
  config.yaml         volumes, seed, distributions, injected-dirt rates — no magic numbers in code
  generate.py         CLI entry point
notebooks/            the medallion pipeline (run in order)
  00_setup_catalog    catalog + schemas + predictive optimization
  01_landing_volume   UC volume for raw files
  02_bronze_ingest    raw Parquet -> bronze tables (dirt preserved)
  03_silver_clean     type, dedup, conform, quarantine
  04_gold_dimensions  8 dims, IDENTITY keys, SCD2 dim_tenant
  05_gold_facts       5 facts, FK constraints, SCD2 point-in-time joins
  06_quality_checks   the DQ framework -> gold.dq_check_results
resources/            Asset Bundle job definition
databricks.yml        Asset Bundle root config
docs/                 architecture.md, data_dictionary.md, img/ (README diagrams)
PLAN.md · CLAUDE.md   build plan and engineering guardrails

Documentation

All data is synthetic. No real company, tenant, or property is represented.

About

Synthetic property-management analytics on the Databricks Lakehouse: seeded generator, bronze/silver/gold medallion, star schema, data-quality framework, and Asset Bundle.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages