Skip to content

Releases: deepan-mehta-analytics/stayops

v4.0.0 — Portfolio Polish: Auth, Theme Overhaul & Screenshots

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 02 Jun 09:29

🏠 StayOps — v4.0.0

Phase 4 portfolio polish — multi-user authentication, warm alabaster ops console theme, and full-page screenshot suite captured from the live Vercel deployment.


What's included

Authentication & Security

Feature Detail
Supabase Auth (email/password) Login page with full-width AI property banner, inline forgot-password toggle
PKCE reset-password flow Secure token exchange via /reset-password route
Route guard middleware proxy.ts protects all /dashboard, /bookings, /reconciliation, /reports routes
Row-Level Security RLS enabled on all 7 Postgres tables — anon blocked from PostgREST direct access
Sign-out button Mint default matching nav; bright red on hover

Ops Console Theme Overhaul (Theme F — Warm Alabaster)

Token Value Purpose
Page background #F4F3EF Warm alabaster — reduces eye strain vs cool blues
Table container #FFFFFF Clear card separation from page
Table header #E9ECEF Distinct but not harsh
Row divider 1px solid #E2E8F0 Replaces alternating row bands
Drop shadow 0 4px 6px -1px rgb(0 0 0 / 0.05) Subtle card lift via .table-card CSS class
Text #212529 Deep charcoal (oklch)

Applied consistently across /dashboard, /bookings, /reconciliation, /reports.

Portfolio Screenshots (1280×800, live Vercel)

File Used in
public/screenshots/landing-hero.png README ## 📊 Results + hero section
public/screenshots/dashboard.png README ## 📊 Results
public/screenshots/reconciliation.png README ## 📊 Results + hero card (replaces placeholder)
public/screenshots/bookings.png public/screenshots/ only
public/screenshots/reports.png public/screenshots/ only

Captured via Playwright MCP at 1280×800 from stayops-five.vercel.app. Hero card [ reconciliation dashboard screenshot ] placeholder replaced with real <img> tag.

Unit Tests

Suite Tests Status
classifyBookings() — Phase 1 8
AI agent tools — Phase 2 8
Weekly report format — Phase 2 7
POST /api/leads — Phase 3 4
Total 27 CI green

Roadmap

  • v4.1.0 — Playwright E2E test suite against live Vercel deployment (6-step flow: landing → lead form → dashboard → reconciliation → AI resolve → bookings/reports)
  • v5.0.0 — Multi-tenant operator accounts with per-user RLS data isolation

v3.0.0 — Growth Surface: Landing Page + PostHog Funnel

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 31 May 08:40

🏠 StayOps — v3.0.0

Phase 3 complete. The public-facing growth surface is live at the root URL — a premium marketing landing page with PostHog funnel tracking, UTM attribution, and lead capture into Supabase.


What's included

Route group architecture

  • app/(marketing)/ — public landing page at /, light-only, Poppins font, OG meta
  • app/(app)/ — ops console at /dashboard, /bookings, /reconciliation, /reports (URLs unchanged)
  • Root app/layout.tsx slimmed to bare font shell; each group has its own layout

Landing page sections

Section Component Notes
Sticky nav MarketingNav Scroll-to-anchor links, transparent overlay on dark hero
Hero Hero Dark slate/blue-950 gradient mesh, floating glassmorphic card, animated pulse dot
Metrics strip MetricsStrip IntersectionObserver count-up animation (86+ bookings, 5 conflict types, 3 channels)
Features grid FeaturesGrid 6 cards with Lucide icons, stagger entrance animation
How it works HowItWorks 3-step numbered flow with dashed connector
Social proof SocialProof Testimonial card with 5-star rating
Lead form LeadForm PostHog funnel events, honeypot spam guard, optional fields

PostHog funnel events

Event When
landing_page_viewed Auto-captured on init
form_start First focus on email field
form_submit_attempt Submit clicked
lead_created 201 response — conversion
form_error API error

Leads API

  • POST /api/leads — Zod validation, honeypot guard (silent 200), Drizzle insert
  • 4 TDD tests: valid email, honeypot, invalid email, optional field passthrough
  • Schema: property_count + channels_used added to leads table (Migration 0003)

Test suite

File Tests
lib/reconciliation.test.ts 8
lib/ai-agent.test.ts 8
lib/weekly-report.test.ts 7
lib/leads-api.test.ts 4 (new)
Total 27

CI: run 26707895559 — both jobs green.


Roadmap

  • v4.0.0 — Phase 4 portfolio polish: integration tests, Playwright E2E, README screenshots

v2.0.0 — Phase 2: Claude AI Agent + Weekly Reports + Cron Automation

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 31 May 04:40

🏠 StayOps — v2.0.0

Phase 2 ships the AI agent layer: Claude tool-calling reconciliation analysis, weekly Slack reports, turnover auto-generation, and the full server-to-client UI wiring.


What's included

Schema (Task 1)

Column Type Purpose
accepted_by text Operator who clicked Accept — audit trail
accepted_at timestamp When Accept was clicked
ai_confidence integer 0–100 Claude's probability score stored at resolve time
user_feedback varchar(20) "correct" / "wrong" / null — Phase 3 ML training label

AI Agent (lib/ai-agent.ts) (Task 2)

  • RECONCILIATION_TOOLS — 3 tools: get_booking_details, get_property_info, propose_resolution (required: action, confidence, reasoning_summary)
  • CHANNEL_PRIORITY["airbnb", "direct", "booking_com", "vrbo"]
  • Full multi-turn agentic loop via streamAnalysis() — emits NDJSON events: text, tool_call_start, proposal, done
  • resolveFlag() — writes status, resolution, resolvedAt, acceptedBy, acceptedAt

Weekly Report (lib/weekly-report.ts) (Task 3)

  • getCurrentIsoWeek() — ISO 8601 Thursday-anchoring, returns YYYY-Www
  • formatWeeklyReport() — pure Markdown formatter
  • buildWeeklyReport() — assembles live DB stats + formats report

API Routes (Task 4)

Route Method Purpose
/api/ai/analyze POST Stream analysis from Claude agent
/api/ai/resolve POST Accept a proposed resolution
/api/ai/feedback POST Record 👍/👎 feedback without resolving
/api/cron/weekly-report POST Generate + deliver weekly Markdown report
/api/cron/generate-turnovers POST Idempotent nightly turnover task creation

ConflictSlideOver component (Task 5)

  • 3 states: idle (conflict detail), analysing (streaming tokens), resolved (confirmation)
  • Glassmorphism panel: rgba(255,255,255,0.92) + backdrop-filter: blur(16px)
  • Feature-flagged: NEXT_PUBLIC_ENABLE_AI_AGENT=true gates the Analyze button
  • Confidence badge colours: ≥90 violet · ≥70 amber · <70 red

ReconciliationClient + page refactor (Task 6)

  • "use client" boundary with selectedFlag state and violet row highlight
  • key={selectedFlag.id} forces slide-over remount on row switch
  • Server component serialises Date → ISO string before passing to client

Vercel Cron (Task 7)

Cron Schedule
/api/cron/weekly-report Mondays 08:00 UTC
/api/cron/generate-turnovers Daily midnight UTC

Tests (Task 8)

Suite Tests
lib/reconciliation.test.ts 8
lib/ai-agent.test.ts 8
lib/weekly-report.test.ts 7
Total 23

Roadmap

  • v3.0.0 — Phase 3 growth surface (direct-booking landing page + PostHog funnel + lead capture + AI listing copy)

v1.2.0 — Conflicts/Opportunities Split + First Unit-Test Suite

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 30 May 14:09

🏠 StayOps — v1.2.0

Reclassifies reconciliation flags by business meaning — urgent conflicts isolated from revenue opportunities — and ships the project's first unit-test suite.


What's included

Reconciliation engine reclassification

Category Flag types UI treatment
Conflicts duplicate, double_book, price_mismatch Top section, severity-ordered (double-book first)
Opportunities gap (2–3 nights) Second section, per-row ~$ estimate
Orphan nights orphan_night (1 night, unsellable) Transparency footnote count only
Intentional vacancy 4+ night gap Not flagged

Dollar-value opportunity estimates

  • estimated_value column added to reconciliation_flags (Drizzle migration applied)
  • Engine computes gap × base_rate for each opportunity; page header sums to "~$X recoverable"
  • Drizzle numeric-string footgun guarded: Number(estimatedValue) before summing

Dashboard fix

  • "Open Flags" card → "Conflicts" card using new getOpenConflictCount query
  • Card is green when zero real conflicts exist (gaps/orphan nights never redden the dashboard)

First unit-test suite

Fixture Tests
double_book overlap 1
duplicate from two channels 1
1-night orphan (no estimatedValue) 1
2-night gap with correct estimatedValue 1
4-night gap → no flag (boundary pin) 1
Multi-property opportunity sum (numeric-string guard) 1
price_mismatch >25% deviation 1
Back-to-back clean bookings → no flags 1

CI

  • New parallel Unit Tests job in .github/workflows/ci.yml
  • Both Lint & Typecheck and Unit Tests required green on every push

Pure classifyBookings refactor

  • Detection logic extracted from runReconciliation into a pure function (bookings in → flags out, no I/O)
  • runReconciliation is now a thin orchestrator: fetch → classify → filter (idempotency) → insert

Roadmap

  • v2.0.0 — AI agent layer: Claude tool-calling reconciliation agent, weekly ops summary → Slack, turnover auto-generation via Cron
  • v3.0.0 — Growth surface: direct-booking landing page, PostHog funnel analytics, lead capture

v1.1.0 — Vega Theme, Dark Mode & Repo Topics

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 30 May 09:31

🏠 StayOps — v1.1.0

Polish release applying the Vega/Green/Blue shadcn preset, adding a system-aware light/dark toggle to the nav, and wiring 14 GitHub repo topics for discoverability.


What's included

Theme — shadcn Vega/Green/Blue preset (b3ZMmbVHcm)

  • globals.css: replaced default neutral palette with green primary (oklch(0.527 0.154 150.069)) and blue chart spectrum (--chart-1--chart-5)
  • components.json: style updated from base-novavega

Light / Dark Mode

  • Installed next-themes; components/theme-provider.tsx wraps the layout
  • app/layout.tsx: ThemeProvider with defaultTheme="system" — OS preference respected on first load
  • components/nav.tsx: Sun/Moon toggle button (top-right); nav colours migrated to CSS variables

Repository & docs

  • 14 GitHub repo topics added: nextjs typescript tailwindcss shadcn-ui drizzle-orm supabase postgresql property-management vacation-rental hospitality operations-dashboard booking-management data-engineering next-themes
  • README: Quick Summary rewritten as bullet lists + roadmap table; all staleness swept (Phase 1 metrics, component statuses, Known Limitations, version checklist)
Check Result
Build ✅ Clean (next build Turbopack, 9s)
CI ✅ Green (lint + typecheck, Node 24)
Theme toggle ✅ Persists across page navigation (localStorage)
Dark mode ✅ Verified live on Vercel across all 4 routes

Roadmap

  • v2.0.0 — Claude tool-calling reconciliation agent · weekly AI ops report → Slack · turnover auto-generation via Vercel Cron
  • v3.0.0 — Direct-booking landing page · PostHog funnel · lead capture with UTM attribution

v1.0.0 — MVP: Reconciliation Engine + KPI Dashboard

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 30 May 07:25

🏠 StayOps — v1.0.0

Full MVP — property operations dashboard with automated booking reconciliation, CSV/Sheets import, and a live KPI dashboard backed by Supabase Postgres.


What's included

Reconciliation Engine

  • Rule-based engine (lib/reconciliation.ts) detects 4 conflict types: duplicate, double_book, gap, price_mismatch
  • Idempotent flag creation — SHA-256 flagKey(type, sortedIds) prevents duplicate flags on re-run
  • Auto-triggers on first visit to /reconciliation if table is empty

KPI Dashboard (/)

  • Occupancy %, Average Daily Rate, Gross Revenue (rolling 30-day window)
  • Revenue by property table with nights + ADR breakdown
  • Upcoming turnovers (next 7 days) for cleaning schedule
  • Open flags card — red/green link to reconciliation page

Booking Import

Source Endpoint Method
CSV upload /api/import/csv multipart/form-data via papaparse
Google Sheets /api/import/sheets service account JSON, A1:Z1000 range
  • Dedup via source_row_hash (SHA-256 of guest|property|dates|channel)
  • Reconciliation auto-runs after every import batch

Reports Page (/reports)

  • All-time revenue by channel and by property
  • ADR per night and revenue share % per segment

Infrastructure

Item Detail
Database Supabase Postgres, 7-table Drizzle schema
Deploy Vercel (auto-deploy on push)
CI GitHub Actions — ESLint + TypeScript typecheck (Node 24)
Rendering All data pages force-dynamic — no stale static pre-renders

Roadmap

  • v2.0.0 — AI agent layer: Claude tool-calling reconciliation, weekly ops report → Slack, turnover auto-generation
  • v3.0.0 — Growth surface: direct-booking landing page, PostHog funnel analytics, lead capture

v0.1.0 — Phase 0 Scaffold Deployed

Choose a tag to compare

@deepan-mehta-analytics deepan-mehta-analytics released this 30 May 06:02

🏠 StayOps — v0.1.0

Phase 0 complete: full Next.js scaffold live on Vercel with GitHub CI wired up.


What's included

App scaffold

Item Detail
Framework Next.js 16 (App Router, TypeScript, Tailwind)
UI shadcn/ui — base layout + persistent top nav
Live URL https://stayops-five.vercel.app
GitHub https://github.com/deepan-mehta-analytics/stayops

Data layer

Item Detail
ORM Drizzle ORM + drizzle-kit
Schema 7 tables: properties, channels, bookings, reconciliation_flags, turnover_tasks, leads, reports
DB Supabase (Postgres) — connection pending next session

Seed script (npm run seed)

Conflict type Instances Properties
duplicate 2 Lakeview Cottage, Downtown Studio
double_book 2 Beach House, Mountain Cabin
gap 2 Downtown Studio (1-night), Lakeview Cottage (2-night)
price_mismatch 2 Lakeview Cottage (+50%), Beach House (-45%)

CI

  • GitHub Actions: lint + typecheck on every push to main
  • Node 24, 4/4 runs green

Roadmap

  • v0.2.0 — Phase 0 complete (Supabase connected + seed running against live DB)
  • v1.0.0 — MVP: Phase 1 reconciliation engine + KPI dashboard
  • v2.0.0 — Phase 2 AI agent layer (Claude tool-calling reconciliation)
  • v3.0.0 — Phase 3 growth surface (landing page + PostHog)