Case study

A full hospitality analytics SaaS, end to end. Deployed at Marriott properties.

Edifice runs a hotel marketplace retail intelligence platform for in-hotel grab-and-go retail spaces. Muscled built the entire product across three repos: a Flask/Streamlit prototype, a production Python API ingesting sensor and POS CSV exports via AWS S3, and a Remix/React/Prisma operator dashboard at insights.edifice.ai. Two Marriott properties live: Spring Hill Suites (Pleasanton CA) and Fairfield Inn & Suites (Nashville TN).

By the numbers

The numbers speak for themselves

Vault-backed numbers. No presentation-grade estimates. Each one is reconcilable to the founder's own reporting.

Repos shipped
3

Three-tier SaaS architecture: a Flask/Streamlit prototype proving the data shape, a production Flask/Pandas API ingesting CSV exports from hotel sensor hardware via AWS S3, and a Remix/React/Prisma operator dashboard. Roughly 700 combined commits between Oct 2024 and May 2026.

SRC: Vault projects/1-hospitality-analytics-platform.yaml, 2026-05-16

Analytics endpoints live in the production API
13

Thirteen REST endpoints on the Python production API covering weekday, shift, hourly, monthly, and weekday-shift breakdowns of conversion and utilization, plus per-UA-ID dwell time, asset-level utilization, property-level retail sales, and the S3 file listing endpoint.

SRC: Vault technical companion, 2026-05-16

Marriott-brand property deployments confirmed
2

Spring Hill Suites (Pleasanton CA, ZIP 94588) and Fairfield Inn & Suites (Nashville TN, ZIP 37203). Both addresses are wired through the production Python API, the property selector in the Remix dashboard, and the per-property UA ID asset tables.

SRC: Vault notes.md, frontend code confirmation, 2026-05-16

Edifice monthly revenue

Post-rebuild growth
Desktop & Mobile

The full homepage, shown two ways

Two side-by-side screenshots of the long homepage. Hover the desktop card to slowly scroll the screenshot top to bottom, so visitors see the entire page without leaving this one.

  • Desktop · full homepage after rebuild
    3 repos
    Full SaaS stack delivered (676 mo)
    /mo at peak
  • Mobile-first after rebuild
    Mobile traffic share
    676 mo
    Engagement length
The work

How the engagement unfolded

  1. Prototype: Flask + Streamlit + Pandas proof-of-concept

    Oct 2024

    Earliest layer of the build, in the edifice-ai repo. Flask + Streamlit + Pandas, with the legacy OpenAI 0.28 SDK pulled in for early exploration of AI-assisted data interpretation. Processed uploaded CSV files locally and served summary endpoints for conversion, bounce, utilization, and restocking. Three commits over two days proved the data shape before the production API was built.

    • Flask prototype
    • Streamlit data exploration
    • Pandas processing
    • OpenAI 0.28 SDK
  2. Production Python API: CSV ingestion + S3 + 13 analytics endpoints

    Oct 2024 – Feb 2025

    edifice-ai-production repo. 211 commits. Flask v3 + Pandas + AWS S3 (aioboto3), deployed to Heroku via heroku.yml and a gunicorn Procfile. Built a DataProcessor base class plus WeekdayBasedSummary, ShiftBasedSummary, HourlyBasedSummary, MonthlyBasedSummary, WeekdayShiftBasedSummary, UtilizationDataProcessor, and PropertyDataProcessor. Thirteen REST endpoints serving the frontend. America/New_York timezone normalization on every load. S3 integration lets Edifice upload new sensor exports without redeploying.

    • Flask + Pandas
    • AWS S3 ingestion
    • Timezone normalization
    • Per-UA-ID utilization
    • Property-level revenue
    • Heroku + gunicorn
  3. Remix frontend dashboard: auth, multi-property, draggable chart grid

    Oct 2024 – May 2026

    Edifice frontend repo. 490 commits. Remix v2 + React 18 + Tailwind CSS v3 + Prisma v6 against PostgreSQL, deployed to Heroku in Docker. JWT sign-in / sign-up with bcryptjs password hashing. Shared DateRangeContext across every chart panel. Property selector flips between Spring Hill Suites and Fairfield Inn & Suites. Eight D3-driven chart components (Bounce, ConversionBounceSales, ConversionBounceTurnout, MarketplaceAssets, Turnout, UtilizationChartNine, UtilizationGuestTurnout, UtilizationMarketplaceTurnout). react-dnd for drag-to-reorder dashboard panels. PapaParse + xlsx for CSV export and jsPDF + html2canvas for PDF export.

    • Remix v2
    • React 18
    • Tailwind v3
    • D3 charts
    • react-dnd reordering
    • JWT auth + bcryptjs
    • Prisma + PostgreSQL
    • CSV + PDF export
  4. Dual-property launch on insights.edifice.ai

    2025 – 2026

    Production deployment of the operator dashboard at insights.edifice.ai, with two Marriott properties wired end-to-end: Spring Hill Suites at 7270 Johnson Drive (Pleasanton CA 94588) and Fairfield Inn & Suites at 901 Division Street (Nashville TN 37203). The frontend hard-codes the brand label per property slug. Per-property UA ID tables map Refrigerators, Snacks, Alcohol, Checkout, Island, and the full marketplace down to the sensor system's individual unit identifiers. Frontend iteration continued through May 2026.

    • insights.edifice.ai
    • Spring Hill Suites (CA)
    • Fairfield Inn & Suites (TN)
    • Per-property UA ID mapping
    • Marriott deployments
Project overview

What we built

Edifice is a SaaS company building a hospitality retail analytics platform. The product helps hotel operators understand how guests use the in-hotel marketplace: how many entered, how many converted at the front desk versus the self-checkout kiosk, how many bounced without purchasing, which display units attracted dwell time, and what the property's total retail revenue was. Not a Shopify project. A standalone SaaS application built entirely outside the Shopify ecosystem.

Muscled built the platform across three repos. The earliest layer was a Flask + Streamlit prototype that proved the data shape. The production layer is a Flask + Pandas API on Heroku with 13 REST endpoints, AWS S3 ingestion for the sensor and POS CSV exports, and timezone normalization to America/New_York. The product layer is a Remix v2 + React 18 + Tailwind dashboard with JWT auth against PostgreSQL via Prisma, eight D3-driven chart components, a react-dnd drag-to-reorder grid, and CSV / PDF export. Roughly 700 combined commits between October 2024 and May 2026.

In their own words

(Testimonial TBD. Vault primary contact is open; public-OK confirmed but contact_name not yet captured.)

Edifice is a SaaS company building a hospitality retail analytics platform for hotel operators. The product tracks in-hotel marketplace performance (grab-and-go retail spaces with refrigerators, snack displays, alcohol bays, and self-checkout kiosks) across guest turnout, conversion by checkout type, bounce, per-asset utilization, and revenue. Confirmed deployments at Marriott-brand properties: Spring Hill Suites in Pleasanton CA and Fairfield Inn & Suites in Nashville TN. Muscled built the platform across three repos: a Flask/Streamlit prototype, a Python production API for data ingestion and analytics, and a Remix/React/Prisma operator dashboard. The platform lives at insights.edifice.ai.

Edifice teamFounder / operations
The challenge

What was holding them back?

Hotel marketplace performance sits at the intersection of foot-traffic sensors, split-tender POS, per-display-unit dwell time, and shift patterns. No off-the-shelf retail analytics tool covers that surface. The data also arrives as CSV exports rather than a live feed, and the same asset class has different sensor IDs at different properties. The work was the full stack: model the metrics, ingest the files, normalize timezones, map per-property UA IDs, and ship a dashboard that hotel operators actually want to use.

  1. 01

    Off-the-shelf retail analytics tools do not handle hotel marketplaces

    Hotel marketplace performance lives at the intersection of foot-traffic sensor data, split-tender POS (front desk and self-checkout), per-display-unit dwell time, and shift patterns. No retail analytics tool covers this surface out of the box. The metrics hotel operators actually care about (turnout, bounce, conversion by checkout type, per-UA-ID utilization, restocking cadence) had to be modelled from scratch.

  2. 02

    Sensor and POS data arrives as CSV exports, not a live feed

    The data pipeline starts at hotel-installed sensor cameras and POS / self-checkout systems that emit CSV exports rather than a streaming feed. The system needed an ingestion layer that handled file upload, versioning, timezone normalization (America/New_York), and consistent schemas across conversion_bounce, utilization, restocking, and property files. Without that, no two reports compared cleanly.

  3. 03

    Multi-property breakdowns require per-property UA ID mapping

    Each hotel's sensor system assigns its own unit asset identifiers (UA IDs) to display units. Spring Hill Suites' Snacks unit is marketplace-snacks-3; Fairfield Inn & Suites' Snacks unit is marketplace-snacks-1. Without an explicit mapping table per property, comparing the same asset class across properties produces nonsense. The frontend property selector and the Python processors both needed this mapping baked in.

  4. 04

    Operators want to rearrange their dashboard, export everything, and slice by date

    Hotel operators don't all care about the same metrics in the same order. They need a dashboard they can rearrange, a date range filter that propagates through every chart, CSV export of every dataset for their own reporting, and PDF snapshots for stakeholder updates. That's a stack of frontend concerns (drag-and-drop, shared state, export pipelines) on top of the data work.

Before / After

Before and after

Before

After

Funnel collapse: we removed a full page from the path to purchase.

Solutions

What we built to fix it

Each fix maps to a specific lift in the funnel.

  • Custom Python analytics API modelled to the hospitality retail surface

    Built a Flask + Pandas production API with a DataProcessor base class and dedicated processors for weekday, shift, hourly, monthly, and weekday-shift breakdowns, plus a UtilizationDataProcessor for per-UA-ID dwell time and a PropertyDataProcessor for property-level retail sales. Thirteen REST endpoints expose conversion (front desk and self-checkout), bounce, total sales, turnout, dwell time, asset utilization, and the S3 file listing. America/New_York timezone normalization applied on every load.

  • S3-backed CSV ingestion with a file upload UI for the operator

    Sensor and POS CSV exports land in an AWS S3 bucket via aioboto3. The dashboard exposes a file upload interface so Edifice can drop in new sensor exports without redeploying the API. The Python layer reads files on demand, normalizes timezones, and reshapes the data into consistent schemas across conversion_bounce, utilization, restocking, and property files.

  • Remix dashboard with multi-property selector and per-property UA ID tables

    Remix v2 + React 18 + Tailwind dashboard at insights.edifice.ai. A property selector switches between Spring Hill Suites and Fairfield Inn & Suites. Per-property UA ID tables map the asset labels operators see (Refrigerators, Snacks, Alcohol, Checkout, Island, full Marketplace) to the underlying sensor identifiers. Eight D3-driven chart components cover bounce, conversion-vs-turnout, asset utilization, and guest turnout. JWT auth with bcryptjs password hashing against PostgreSQL via Prisma.

  • Drag-to-reorder chart grid, date range context, CSV and PDF export

    react-dnd lets operators reorder dashboard panels and the layout persists. A shared DateRangeContext propagates the active range through every chart and KPI tile (Revenue, Conversion %, Avg Bounce). PapaParse + xlsx for CSV / spreadsheet export per dataset. jsPDF + html2canvas snapshot the dashboard to PDF for stakeholder updates.

The stack

What it was built on

Tools picked for the job, not for the resume.

  • Remix v2 + React 18
    Frontend framework
  • Tailwind CSS v3
    Styling
  • D3.js v7
    Charting
  • react-dnd v16
    Dashboard UX
  • Prisma v6 + PostgreSQL
    ORM + database
  • Flask v3 + Pandas + NumPy
    Python analytics API
  • AWS S3 (aioboto3)
    File ingestion
  • Heroku + Docker
    Deployment
  • JWT + bcryptjs
    Authentication
  • PapaParse + jsPDF + html2canvas
    CSV / PDF export
How we engineer performance

Speed is a revenue lever, not a vanity score

Every Muscled build is engineered to the same standard. The numbers below are the published industry benchmarks we design against, not stand-ins for any one client's figures.

conversions per 0.1s of load-time improvement on ecommerce sites.

+8.4%

SRC: DELOITTE / GOOGLE

conversion rate for stores loading under 2s, vs the ~1.4% Shopify average.

2.4%

SRC: SHOPIFY PERFORMANCE DATA

conversion lift per 1s of mobile load-time gained, where 90% of traffic lives.

+10-20%

SRC: SHOPIFY MOBILE BENCHMARKS

// OUR PERFORMANCE GATE we don't ship unless field Core Web Vitals hold: LCP ≤ 2.5s · INP ≤ 200ms · CLS < 0.1 (p75, mobile)

Capability surface

The techniques behind a build like this

Data pipeline & analytics API

  • Flask + Pandas production API
  • AWS S3 CSV ingestion
  • 13 REST endpoints
  • DataProcessor base class
  • Weekday / Shift / Hourly / Monthly summaries
  • WeekdayShiftBasedSummary
  • UtilizationDataProcessor
  • PropertyDataProcessor
  • America/New_York timezone normalization
  • Per-property UA ID mapping
  • aioboto3 async S3
  • gunicorn production server

Operator dashboard UX

  • Drag-to-reorder chart grid (react-dnd)
  • Shared DateRangeContext
  • Multi-property selector
  • KPI summary tiles (Revenue / Conversion % / Avg Bounce)
  • Custom date range picker
  • 8 D3 chart components
  • InvokeBounceChart
  • InvokeConversionBounceSales
  • InvokeConversionBounceTurnout
  • InvokeMarketplaceAssets
  • InvokeUtilizationChartNine
  • InvokeUtilizationGuestTurnout
  • InvokeUtilizationMarketplaceTurnout

Auth, export, integrations

  • JWT + bcryptjs auth
  • CSV export (PapaParse + xlsx)
  • PDF export (jsPDF + html2canvas)
  • Prisma v6 + PostgreSQL user model
  • Sign-in / sign-up flow
  • File upload UI for sensor CSVs
  • Per-chart CSV export
  • Dashboard snapshot to PDF
  • Date-diff aware filters

Build & deployment

  • Heroku + Docker
  • insights.edifice.ai
  • 3-repo architecture
  • heroku.yml + Procfile (Python API)
  • Dockerfile (Remix frontend)
  • Node.js ≥ 20
  • Express.js v4 backend
  • CORS-locked production domain
  • ~700 combined commits
  • Oct 2024 – May 2026 build window
Storefronts

One build. Multiple markets.

Same theme code across markets, with localized pricing, currency, and region-specific content routed automatically.

  • Spring Hill Suites — Pleasanton CA

    Marriott property · 7270 Johnson Drive, ZIP 94588
    • Marriott brand
    • marketplace-refrigerator-3
    • marketplace-snacks-3
    • marketplace-alcohol-1
    • marketplace-checkout-1
    • marketplace-island-1
    • marketplace-4 (full space)
    Spring Hill Suites — Pleasanton CA screenshot
    Served from the same Shopify Markets build. Dedicated capture not included.
  • Fairfield Inn & Suites — Nashville TN

    Marriott property · 901 Division Street, ZIP 37203
    • Marriott brand
    • marketplace-refrigerator-3
    • marketplace-snacks-1
    • marketplace-alcohol-1
    • marketplace-checkout-1
    • marketplace-island-1
    • marketplace-1 (full space)
    Fairfield Inn & Suites — Nashville TN screenshot
    Served from the same Shopify Markets build. Dedicated capture not included.
Full build · sections

Every section, built mobile-first

The full build is many numbered sections, each designed for the phone first. The rail below shows a sample. Scroll horizontally to step through.

The results

What the work delivered

Each number is reconcilable to the founder's own reporting.

Repos shipped
3

Three-tier SaaS architecture: a Flask/Streamlit prototype proving the data shape, a production Flask/Pandas API ingesting CSV exports from hotel sensor hardware via AWS S3, and a Remix/React/Prisma operator dashboard. Roughly 700 combined commits between Oct 2024 and May 2026.

SRC: Vault projects/1-hospitality-analytics-platform.yaml, 2026-05-16

Analytics endpoints live in the production API
13

Thirteen REST endpoints on the Python production API covering weekday, shift, hourly, monthly, and weekday-shift breakdowns of conversion and utilization, plus per-UA-ID dwell time, asset-level utilization, property-level retail sales, and the S3 file listing endpoint.

SRC: Vault technical companion, 2026-05-16

Marriott-brand property deployments confirmed
2

Spring Hill Suites (Pleasanton CA, ZIP 94588) and Fairfield Inn & Suites (Nashville TN, ZIP 37203). Both addresses are wired through the production Python API, the property selector in the Remix dashboard, and the per-property UA ID asset tables.

SRC: Vault notes.md, frontend code confirmation, 2026-05-16

Ready to ship yours?

Let's talk about what you want to ship.

A full three-tier SaaS analytics product, end to end. Prototype, production Python API, and Remix operator dashboard, with two Marriott-brand property deployments live at insights.edifice.ai. Enterprise-grade hospitality SaaS built outside the Shopify ecosystem.

30 minutes. No deck.