# Building a Dashboard with Claude Code + OData

A step-by-step prompt guide for beginners. Copy/paste these prompts into Claude Code
inside VS Code to build a full-stack dashboard powered by an OData feed.

---

## Prerequisites

- **VS Code** with the [Claude Code extension](https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code) installed
- **Node.js** 18+ installed
- Open an **empty folder** in VS Code, then open Claude Code (`Cmd+Shift+P` → "Claude Code: Open")

> **Tip:** Each section below is one prompt you paste into Claude Code. Wait for it
> to finish before moving to the next. Read Claude's output — it will explain what
> it built and may ask follow-up questions.

---

## Phase 1: Project Scaffolding

### Prompt 1 — Initialize the project

```
Create a new TypeScript + Node.js project in this directory.
Use Express for the backend server on port 4000.
Set up a tsconfig.json targeting ES2022 with NodeNext modules.
Add these dependencies: express, cors, node-cron.
Add these dev dependencies: typescript, tsx, @types/node, @types/express, @types/cors.
Add a "dev" script that runs the server with tsx.
```

**What this does:** Sets up `package.json`, `tsconfig.json`, and installs
dependencies. You now have a runnable (empty) Express server.

---

## Phase 2: Connect to the OData Feed

### Prompt 2 — Create the OData client

```
Create a file src/odata-client.ts that fetches data from an OData V4 service.
The base URL is: https://services.odata.org/V4/Northwind/Northwind.svc

The function fetchEntity(entityName: string) should:
- Fetch all records from the given entity (e.g. "Products")
- Handle OData server-side paging by following @odata.nextLink
- Return an array of the raw JSON objects
```

**What this does:** Builds a reusable OData client that handles pagination
automatically. The Northwind service is free and public — no auth needed.

### Prompt 3 — Define types and config

```
Create src/config.ts that exports:
- ODATA_BASE_URL (the Northwind URL above)
- An ENTITIES array: Products, Orders, Customers, Employees, Categories, Suppliers, Order_Details
- SYNC_CRON set to every 30 minutes
- PORT set to 4000

Create src/types.ts with TypeScript interfaces for each entity matching
the Northwind OData schema (Product, Order, Customer, Employee, Category,
Supplier, OrderDetail). Include an EntityResponse<T> generic wrapper
with data: T[] and lastRefreshed: string | null.
```

**What this does:** Centralizes configuration and gives you type safety
across the whole project.

---

## Phase 3: Caching & Sync

### Prompt 4 — In-memory cache and sync engine

```
Create src/cache.ts with an in-memory Map-based cache.
It should have:
- setEntity(name, data) — stores data with a lastRefreshed timestamp
- getEntity(name) — retrieves cached data
- getStatus() — returns a summary of all cached entities with record counts

Create src/sync.ts that syncs all entities from the OData feed into the cache.
It should fetch all entities in parallel using Promise.all and log progress
to the console.
```

**What this does:** The server pulls data from OData on startup and refreshes
it on a cron schedule. All API responses come from the fast local cache.

---

## Phase 4: API Routes & Server

### Prompt 5 — Wire up Express routes

```
Create src/routes/index.ts with Express routes that serve cached entity data:
- GET /api/products
- GET /api/orders
- GET /api/customers
- GET /api/employees
- GET /api/categories
- GET /api/suppliers
- GET /api/order-details

Update src/server.ts to:
- Use CORS middleware
- Mount the routes under /api
- Add a GET /api/status endpoint
- On startup: run an initial sync, then schedule syncs with node-cron
- Listen on the configured port
```

**What this does:** You now have a working REST API. Test it:

```bash
npm run dev
# then open http://localhost:4000/api/status in a browser
```

---

## Phase 5: React Frontend

### Prompt 6 — Scaffold the React client

```
Create a React frontend in a /client subdirectory using Vite + TypeScript.
Use React Router for navigation and @tanstack/react-query for data fetching.
Set up Tailwind CSS v4 with a dark theme.
Add a Vite proxy so /api requests forward to localhost:4000.
Add a "dev:client" script to the root package.json.
```

**What this does:** Sets up a modern React app with routing, data fetching,
and dark-mode styling — all separate from the backend.

### Prompt 7 — Build reusable UI components

```
Create minimal UI components in client/src/components/ui/ using
Tailwind classes (shadcn-style). I need:
- Card (with CardHeader, CardTitle, CardContent)
- Button
- Badge
- Input
- Table (Table, TableHeader, TableRow, TableHead, TableBody, TableCell)

Keep them simple and composable. Use a dark theme color palette.
```

**What this does:** Gives you a component library to build pages with,
without pulling in a heavy UI framework.

---

## Phase 6: Dashboard Page

### Prompt 8 — Create the main dashboard

```
Create client/src/pages/Dashboard.tsx — the main dashboard page.
It should use React Query to fetch data from all API endpoints and display:

KPI cards across the top:
- Total Revenue (calculated from Order_Details: UnitPrice * Quantity * (1-Discount))
- Total Orders count
- Average Order Value
- Active Products (not discontinued) out of total

Charts (use the recharts library):
- Area chart: Revenue over time (by month)
- Horizontal bar chart: Top 12 countries by order count
- Vertical bar chart: Products per category
- Pie chart: Customers by country
- Radar chart: Employee order volume
- Bar chart: Top 10 customers by order count
- Bar chart: Inventory stock by category

Show a Data Sync Status section at the bottom with entity names,
record counts, and last-refreshed times.
```

**What this does:** This is the main event — a rich, interactive dashboard
with KPIs and multiple chart types, all powered by the OData feed.

---

## Phase 7: Data Pages

### Prompt 9 — Add entity list pages

```
Create individual pages for each entity in client/src/pages/:
- Products.tsx — sortable/searchable table of all products
- Orders.tsx — table of orders with customer and employee info
- Customers.tsx — searchable customer directory
- Employees.tsx — employee list with titles
- Categories.tsx — category grid with descriptions
- Suppliers.tsx — supplier directory
- OrderDetails.tsx — line-item detail table

Each page should:
- Fetch data with React Query
- Include a search/filter input at the top
- Display data in a styled table using the UI components
```

**What this does:** Gives users drill-down access to every entity
behind the dashboard summaries.

---

## Phase 8: Layout & Navigation

### Prompt 10 — Add app shell with sidebar navigation

```
Create client/src/components/Layout.tsx as the app shell.
It should have a collapsible sidebar with navigation links to:
Dashboard, Products, Orders, Customers, Employees, Categories,
Suppliers, Order Details.

Use React Router's <Outlet /> for the page content area.
Make the sidebar dark-themed and highlight the active route.

Create client/src/App.tsx that wraps everything in:
- QueryClientProvider (for React Query)
- BrowserRouter (for routing)
- Layout with nested Routes for each page
```

**What this does:** Ties all the pages together into a navigable app
with a professional sidebar layout.

---

## Phase 9: Polish & Enhancements (Optional)

### Prompt 11 — Add cross-filtering

```
Add a global filter context (client/src/lib/filter-context.tsx) that lets
users click on a country in the dashboard charts to filter ALL dashboard
data to that country. Clicking again clears the filter.

When a filter is active:
- Unselected chart segments should dim (reduced opacity)
- The selected segment should highlight
- All KPIs and charts should update to show filtered data only
```

### Prompt 12 — Add an analytics page

```
Create an Analytics page (client/src/pages/Analytics.tsx) that shows
deeper analysis:
- Revenue by category (bar chart)
- Discount impact analysis
- Shipping performance metrics
- Top products by revenue

Add it to the sidebar navigation and routes.
```

---

## Running the App

Once all prompts are complete, run both servers:

```bash
# Terminal 1 — backend
npm run dev

# Terminal 2 — frontend
npm run dev:client
```

Open http://localhost:5173 in your browser.

---

## Tips for Working with Claude Code

### Be specific about what you want
Bad: "Make it look better"
Good: "Change the dashboard KPI cards to use a 4-column grid with blue accent borders"

### Build incrementally
Don't try to describe the entire app in one prompt. Break it into logical
steps like this guide does. Each prompt builds on the last.

### Let Claude see existing code
Claude Code reads your project files automatically. If something isn't working,
you can say: "The /api/products endpoint returns an empty array — can you debug it?"

### Ask Claude to run it
You can say: "Run `npm run dev` and tell me if there are any errors." Claude Code
can execute terminal commands and read the output.

### Fix errors by describing symptoms
Instead of guessing at fixes, tell Claude what you see:
"When I click the Products link, I get a blank page and a console error
that says 'Cannot read properties of undefined'"

### Iterate on the design
After the dashboard works, you can keep going:
- "Add a date range picker that filters orders by date"
- "Make the sidebar collapsible with a hamburger icon"
- "Add a loading skeleton animation while data fetches"
- "Export the products table to CSV when I click a button"

---

## What You Built

| Layer     | Tech                              | Purpose                        |
|-----------|-----------------------------------|--------------------------------|
| Data      | OData V4 (Northwind)              | Public demo data feed          |
| Backend   | Express + TypeScript              | Proxy, cache, and serve data   |
| Caching   | In-memory Map + node-cron         | Fast responses, periodic sync  |
| Frontend  | React + Vite + TypeScript         | SPA with routing               |
| Data Mgmt | @tanstack/react-query             | Fetch, cache, and sync state   |
| Charts    | Recharts                          | Interactive data visualizations |
| Styling   | Tailwind CSS                      | Dark-themed responsive UI      |

---

*This guide was built for the Acumatical AugForum demo. The OData endpoint
(Northwind) is free and public — swap it out for any OData V4 feed
(including Acumatica's) by changing the URL in `src/config.ts`.*
