RV Market Intelligence Dashboard Setup
This skill helps you work with the RV Market Intelligence Dashboard project, a FastAPI + React analytics platform with dual backend modes (Delta Lake and GraphQL).
What This Skill Does
Sets up and starts the backend (FastAPI) and frontend (React) serversSwitches between Delta Lake (fast, full data) and GraphQL (legacy) modesNavigates the project structure and key filesApplies Thor Industries branding and style guideManages multi-select filters and cross-filtering in the Sales PlatformExplains architecture decisions and performance characteristicsArchitecture Overview
The project has two main applications:
1. **Sales Platform** (main) at `/` - Territory management, dealer directory, competitive intelligence
2. **Analytics Dashboard** (legacy) at `/analytics` - Data visualizations with A/B/C/M versions
The backend supports two modes:
**Delta Lake Mode**: ~50 second startup, 1.1 GB memory, full 187K inventory (RECOMMENDED)**GraphQL Mode**: 20-25 min startup, 400 MB memory, 100K inventory limit (legacy)Step-by-Step Instructions
1. Starting the Development Environment
When the user asks to start the servers or run the application:
1. **Check if you're in the project root** by looking for `api/` and `mobile-app/` directories
2. **Start the backend** in Delta Lake mode (recommended):
```bash
cd api && USE_DELTALAKE=true python -m uvicorn main:app --port 8000
```
- For GraphQL mode (legacy), omit `USE_DELTALAKE=true`
- Backend will be available at `http://localhost:8000`
- Wait for "Application startup complete" message
3. **Start the frontend** in a separate terminal:
```bash
cd mobile-app && npm run dev -- --port 5175
```
- Frontend will be available at `http://localhost:5175`
4. **Inform the user** about the routes:
- `/` or `/sales/*` - Sales Platform (main entry point)
- `/analytics` - Analytics Dashboard with A/B/C/M versions
2. Switching Backend Modes
When the user wants to change backend modes:
**To enable Delta Lake mode:**
Set environment variable: `USE_DELTALAKE=true`Requires Azure CLI authentication: `az login`Startup time: ~50 secondsFull 187K inventory records**To enable GraphQL mode:**
Remove `USE_DELTALAKE` environment variable or set to falseNo Azure authentication requiredStartup time: 20-25 minutesLimited to 100K inventory records3. Working with the Sales Platform
When the user asks about filters, dealer directory, or sales features:
**Key files to reference:**
`mobile-app/src/pages/SalesPlatform/index.tsx` - Main shell`mobile-app/src/components/sales/FilterPanel.tsx` - Multi-select filters`mobile-app/src/context/SalesContext.tsx` - State management`mobile-app/src/hooks/useSalesData.ts` - API data hooks**Multi-select filters:**
Dealer Group, Manufacturer, and Model support multiple selectionsSelected values are stored as arrays in SalesContextArrays are converted to comma-separated strings for API callsBackend uses `.isin()` for filtering multiple values4. Working with Analytics Dashboard
When the user asks about charts, visualizations, or cross-filtering:
**Four versions available:**
**Version A**: Recharts (original)**Version B**: Tremor library**Version C**: ECharts with Thor Industries branding (dark mode)**Version M**: Mobile-optimized (touch-friendly, vertical layout)**Cross-filtering:**
1. User clicks a chart element
2. `CrossFilterContext` stores the filter
3. All charts re-fetch data with filter params
4. API returns filtered aggregations
**Key files:**
`mobile-app/src/pages/Dashboard.tsx` - Version toggle`mobile-app/src/components/analytics/AnalyticsTab*.tsx` - Each version`mobile-app/src/context/CrossFilterContext.tsx` - Filter state5. Applying Thor Industries Branding
When the user asks about styling, colors, or design:
**Thor Industries color palette:**
Charcoal: `#181817` (primary dark)Sage Green: `#495737` (primary accent)Gold/Amber: `#a46807` (actions, warnings)Steel Blue: `#577d91` (info, secondary)Off-White: `#fffdfa` (light backgrounds)**Typography:**
Headings: Montserrat (700-800 weight)Body: Open Sans (400-600 weight)Labels: Montserrat uppercase with 0.1em tracking**Key files:**
`mobile-app/src/styles/thorTheme.ts` - TypeScript constants`mobile-app/src/index.css` - CSS custom properties and utility classes**Usage in components:**
```typescript
import { THOR_COLORS } from '../styles/thorTheme'
className="text-[var(--thor-sage)] card-thor btn-thor-sage"
```
6. Working with the Database
When the user asks about schema, data, or database operations:
**Schema files:**
`parquet_test/SCHEMA.md` - Complete schema documentationBackend uses in-memory caches (no direct DB queries at request time)**Delta Lake tables:**
`dim_product_model` - 29,437 product models`dim_product` - 153,913 floorplans`dim_dealership` - 12,368 dealers`fact_inventory_current` - 187,600 inventory records`fact_inventory_sales` - 562,754 sales transactions**Performance note:**
Unfiltered `/inventory/aggregated` requests: ~300-400ms (pre-computed)Filtered requests: ~3+ seconds (computed on-demand)7. Troubleshooting
**Backend won't start:**
Check if port 8000 is already in useVerify `az login` if using Delta Lake modeCheck Python dependencies: `pip install -r requirements.txt`**Frontend won't start:**
Check if port 5175 is already in useRun `npm install` if dependencies are missingClear cache: `rm -rf node_modules/.vite`**Slow API responses:**
Check if backend is in GraphQL mode (slow)Switch to Delta Lake mode for better performanceReview Issue #25 for aggregation performance details**Authentication errors:**
Run `az login` for Delta Lake modeCheck `.env` file for GraphQL credentialsExamples
**Example 1: Starting the application**
```
User: "Start the RV dashboard"
Assistant: I'll start both the backend and frontend servers.
[Use Bash tool to start backend with Delta Lake mode]
[Use Bash tool to start frontend]
The servers are now running:
Backend: http://localhost:8000 (Delta Lake mode, ~50 sec startup)Frontend: http://localhost:5175Main routes:
/ - Sales Platform/analytics - Analytics Dashboard```
**Example 2: Explaining filters**
```
User: "How do the multi-select filters work?"
Assistant: The Sales Platform uses multi-select filters for Dealer Group, Manufacturer, and Model.
Here's the flow:
1. FilterPanel.tsx stores selected values as arrays in SalesContext
2. useSalesData.ts converts arrays to comma-separated strings
3. API receives: ?manufacturer=Thor,Forest River,Winnebago
4. Backend (deltalake_adapter.py) splits the string and uses .isin()
[Read FilterPanel.tsx to show implementation details]
```
**Example 3: Applying Thor branding**
```
User: "Add a new button with Thor styling"
Assistant: I'll create a button using Thor Industries' sage green accent color.
[Read thorTheme.ts to get color constants]
[Show example using btn-thor-sage class or var(--thor-sage)]
The Thor style guide uses:
Sage green (#495737) for primary actionsGold (#a46807) for warnings/pricesMontserrat font for buttons (700 weight)```
Important Notes
**Always use Delta Lake mode** unless the user specifically requests GraphQL**Pre-computed aggregations** are only available for unfiltered requests (see Issue #25)**Multi-select filters** require comma-separated string handling in the API layer**Thor branding** should be consistent across all new components (use thorTheme.ts constants)**Mobile version (M)** is optimized for screens < 640px width**Cross-filtering** triggers full data refetch from the API (not client-side filtering)