@schandlergarcia/sf-web-components 1.9.77 → 1.9.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.a4drules/skills/command-center-builder/SKILL.md +2 -1
- package/.a4drules/skills/command-center-builder/getting-started.md +136 -45
- package/.a4drules/skills/command-center-builder/improved-build-process.md +42 -6
- package/CHANGELOG.md +32 -0
- package/data/engine-command-center-prd.md +31 -14
- package/data/useEngineLiveData.ts +6 -11
- package/dist/components/library/data/useDataSource.js +6 -9
- package/dist/components/library/data/useDataSource.js.map +1 -1
- package/package.json +1 -1
- package/src/components/library/data/useDataSource.jsx +9 -10
- package/src/templates/lib/dataStrategy.ts.template +12 -30
- package/src/templates/workspace/CommandCenter.tsx.template +2 -1
|
@@ -43,6 +43,7 @@ export default function HomePage() {
|
|
|
43
43
|
// src/components/workspace/CommandCenter.tsx
|
|
44
44
|
import AppThemeProvider from "@/components/library/theme/AppThemeProvider";
|
|
45
45
|
import DataModeProvider from "@/components/library/data/DataModeProvider";
|
|
46
|
+
import { ENABLE_SAMPLE_DATA_CACHE } from "@/lib/dataStrategy";
|
|
46
47
|
import { Toast } from "@heroui/react";
|
|
47
48
|
import MyDashboard from "../../pages/MyDashboard"; // ← change ONLY this import
|
|
48
49
|
|
|
@@ -50,7 +51,7 @@ export default function CommandCenter() {
|
|
|
50
51
|
return (
|
|
51
52
|
<div className="heroui-scope">
|
|
52
53
|
<AppThemeProvider initialMode="light">
|
|
53
|
-
<DataModeProvider initialMode="sample">
|
|
54
|
+
<DataModeProvider initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}>
|
|
54
55
|
<MyDashboard />
|
|
55
56
|
<Toast.Provider placement="bottom end" />
|
|
56
57
|
</DataModeProvider>
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
The dashboard is built in **3 phases**, one per user prompt. Each phase adds a layer. Do NOT build ahead — only build what the current phase asks for.
|
|
4
4
|
|
|
5
|
+
## General Rules for All Phases
|
|
6
|
+
|
|
7
|
+
1. **Phase 1 writes new files. Phases 2 and 3 make surgical edits.** Phase 2 and 3 should NEVER rewrite `EngineDashboard.tsx` from scratch — use targeted edits (add imports, update specific lines, insert JSX blocks). Rewriting the entire file risks losing Phase 1 work and takes 60+ seconds vs seconds per edit.
|
|
8
|
+
|
|
9
|
+
2. **Don't read files you don't need.** The patterns for `useDataSource`, `DataModeProvider`, `DataModeToggle`, and library components are documented in this skill. Only read files that contain project-specific code you need to understand (e.g., the dashboard you're editing, the live data file for its shape).
|
|
10
|
+
|
|
11
|
+
3. **Don't run `npm run build` during the build.** Vite handles JSX/TSX regardless of TypeScript errors. Pre-existing TS7016 errors are normal.
|
|
12
|
+
|
|
13
|
+
4. **STOP and ASK before creating Salesforce metadata.** When the build guide says "suggest" a custom field, platform event, or Apex class — you must present the suggestion to the user and WAIT for confirmation. Do NOT create the file until the user says yes. This is a scripted demo moment.
|
|
14
|
+
|
|
5
15
|
---
|
|
6
16
|
|
|
7
17
|
## Phase 1 — Build the Dashboard (sample data only)
|
|
@@ -35,52 +45,130 @@ The dashboard is built in **3 phases**, one per user prompt. Each phase adds a l
|
|
|
35
45
|
|
|
36
46
|
## Phase 2 — Connect to Live Data
|
|
37
47
|
|
|
38
|
-
**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
**The point of Phase 2:** The dashboard switches from sample data (8 US travelers: Sarah Chen, Marcus Johnson…) to a completely different live dataset (12 global travelers: Raj Kapoor, Sofia Reyes… with a Midwest storm scenario). The user should see different names, different cities, different metrics, and different disruptions.
|
|
49
|
+
|
|
50
|
+
**How the switch works:** `ENABLE_SAMPLE_DATA_CACHE` in `src/lib/dataStrategy.ts` controls which data `useDataSource` returns. `CommandCenter.tsx` reads this flag and passes it to `DataModeProvider`. When the flag is `true` (default), mode is "sample." When `false`, mode is "live" and every `useDataSource` call returns its `live` prop instead.
|
|
51
|
+
|
|
52
|
+
**How to work:** Make surgical edits to the existing `EngineDashboard.tsx`. Do NOT rewrite the file.
|
|
53
|
+
|
|
54
|
+
**Files to read first (only these):**
|
|
55
|
+
1. `src/pages/EngineDashboard.tsx` — the Phase 1 dashboard you're editing
|
|
56
|
+
2. `src/hooks/useEngineLiveData.ts` — to see the live data shape
|
|
57
|
+
|
|
58
|
+
**Do NOT read:** `useDataSource.jsx`, `DataModeProvider.jsx`, `dataStrategy.ts`, or any library component source. The patterns are right here.
|
|
59
|
+
|
|
60
|
+
**Edits to make (in order):**
|
|
61
|
+
|
|
62
|
+
1. **Add import** at the top of EngineDashboard.tsx:
|
|
63
|
+
```tsx
|
|
64
|
+
import { useEngineLiveData } from "@/hooks/useEngineLiveData";
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. **Add hook call** inside the component, near the top:
|
|
68
|
+
```tsx
|
|
69
|
+
const live = useEngineLiveData();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
3. **Update every `useDataSource` call** to pass live data:
|
|
73
|
+
```tsx
|
|
74
|
+
// Before (Phase 1):
|
|
75
|
+
const markers = useDataSource({ sample: MAP_MARKERS, live: [] });
|
|
76
|
+
// After (Phase 2):
|
|
77
|
+
const markers = useDataSource({ sample: MAP_MARKERS, live: live.mapMarkers });
|
|
78
|
+
```
|
|
79
|
+
Do this for markers, arcs, travelers, flights, escalations, disruptions, spendData — whatever the dashboard uses.
|
|
80
|
+
|
|
81
|
+
4. **Update KPI derivations** to react to active data:
|
|
82
|
+
```tsx
|
|
83
|
+
const activeMetrics = live.loading ? SAMPLE_METRICS : live.metrics;
|
|
84
|
+
```
|
|
85
|
+
Then use `activeMetrics` in KPI overlays instead of hardcoded sample constants.
|
|
86
|
+
|
|
87
|
+
5. **Flip the backend switch** — change `src/lib/dataStrategy.ts`:
|
|
88
|
+
```tsx
|
|
89
|
+
export const ENABLE_SAMPLE_DATA_CACHE = false;
|
|
90
|
+
```
|
|
91
|
+
This causes `CommandCenter.tsx` to pass `initialMode="live"` to `DataModeProvider`, and every `useDataSource` call now returns the live prop. The dashboard instantly shows the live dataset on next load.
|
|
92
|
+
|
|
93
|
+
That's 5 targeted edits. Not a full rewrite.
|
|
94
|
+
|
|
95
|
+
**No UI toggle.** There is no `DataModeToggle` in the dashboard. The switch is `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts`.
|
|
96
|
+
|
|
97
|
+
**After wiring — STOP and suggest (do not create yet):**
|
|
98
|
+
|
|
99
|
+
Say something like: *"I notice Flight__c doesn't have a field to track weather impact on individual flights. A Weather_Impact__c picklist would help the dashboard filter storm-affected flights. Want me to create it?"*
|
|
100
|
+
|
|
101
|
+
Only create `Flight__c.Weather_Impact__c` (PRD section 14a) AFTER the user confirms.
|
|
54
102
|
|
|
55
103
|
**What NOT to build:**
|
|
56
104
|
- No ChatBar or Eva — that's Phase 3
|
|
57
105
|
- No platform events or Apex — that's Phase 3
|
|
106
|
+
- Do NOT rewrite EngineDashboard.tsx from scratch
|
|
107
|
+
- Do NOT add `DataModeToggle` to the UI
|
|
108
|
+
- Do NOT read library component source files
|
|
109
|
+
- Do NOT run `npm run build` between edits
|
|
58
110
|
|
|
59
111
|
---
|
|
60
112
|
|
|
61
113
|
## Phase 3 — Add Agentforce
|
|
62
114
|
|
|
63
|
-
**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
115
|
+
**How to work:** Make surgical edits to the existing `EngineDashboard.tsx`. Do NOT rewrite the file.
|
|
116
|
+
|
|
117
|
+
**Files to read first (only these):**
|
|
118
|
+
1. `src/pages/EngineDashboard.tsx` — the current dashboard
|
|
119
|
+
|
|
120
|
+
**Edits to make (in order):**
|
|
121
|
+
|
|
122
|
+
1. **Add ChatBar import** (if not already imported from the barrel):
|
|
123
|
+
```tsx
|
|
124
|
+
import { ChatBar } from "@/components/library";
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
2. **Add chat suggestions constant** at module scope:
|
|
128
|
+
```tsx
|
|
129
|
+
const CHAT_SUGGESTIONS = [
|
|
130
|
+
"Are any travelers affected by the Denver weather?",
|
|
131
|
+
"What's our rebooking policy for weather delays?",
|
|
132
|
+
"Notify all travelers on disrupted flights",
|
|
133
|
+
"Create a support case for the SFO→JFK cancellation",
|
|
134
|
+
];
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
3. **Add handleChat function** at module scope:
|
|
138
|
+
```tsx
|
|
139
|
+
const handleChat = (msg: string) => ({ text: `Looking into: "${msg}"…` });
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
4. **Insert ChatBar JSX** between the map section and the data panels:
|
|
143
|
+
```tsx
|
|
144
|
+
<div className="px-4 pt-4">
|
|
145
|
+
<ChatBar
|
|
146
|
+
title="Eva"
|
|
147
|
+
placeholder="Ask Eva anything about travelers, bookings, policy, or spend…"
|
|
148
|
+
suggestions={CHAT_SUGGESTIONS}
|
|
149
|
+
onSend={handleChat}
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
5. **Add AgentforceConversationClient** with `agentId="0Xxa5000000relhCAA"` and `agentLabel="Eva"`
|
|
155
|
+
|
|
156
|
+
**After adding Eva — STOP and suggest (do not create yet):**
|
|
157
|
+
|
|
158
|
+
Say: *"The dashboard tracks disruptions in real time. I can create a Travel_Disruption_Alert__e platform event so disruption data can be published to the Salesforce event bus. Want me to set it up?"*
|
|
159
|
+
|
|
160
|
+
Only create the platform event (PRD section 14b) AFTER the user confirms.
|
|
161
|
+
|
|
162
|
+
**After the platform event — STOP and suggest again:**
|
|
163
|
+
|
|
164
|
+
Say: *"Now I'll write an Apex service class to publish disruption records to that event bus. Want me to create it?"*
|
|
165
|
+
|
|
166
|
+
Only create `TravelDisruptionEventService` (PRD section 14c) AFTER the user confirms.
|
|
167
|
+
|
|
168
|
+
**What NOT to build without asking:**
|
|
169
|
+
- Do NOT create platform events or Apex classes without user confirmation
|
|
170
|
+
- Do NOT rewrite EngineDashboard.tsx from scratch
|
|
171
|
+
- Do NOT read library component source files
|
|
84
172
|
|
|
85
173
|
---
|
|
86
174
|
|
|
@@ -88,11 +176,14 @@ The dashboard is built in **3 phases**, one per user prompt. Each phase adds a l
|
|
|
88
176
|
|
|
89
177
|
| | Phase 1 | Phase 2 | Phase 3 |
|
|
90
178
|
|---|---------|---------|---------|
|
|
91
|
-
| Dashboard layout & panels |
|
|
92
|
-
| Sample data | Wire | — | — |
|
|
93
|
-
| Live data | Skip |
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
179
|
+
| Dashboard layout & panels | Write new file | — | — |
|
|
180
|
+
| Sample data | Wire (`live: []`) | — | — |
|
|
181
|
+
| Live data wiring | Skip | Surgical edits | — |
|
|
182
|
+
| Flip `dataStrategy.ts` to `false` | Skip | Edit | — |
|
|
183
|
+
| Custom field metadata | Skip | Suggest → wait | — |
|
|
184
|
+
| ChatBar (Eva) | Skip | Skip | Surgical edit |
|
|
185
|
+
| AgentforceConversationClient | Skip | Skip | Surgical edit |
|
|
186
|
+
| Platform event | Skip | Skip | Suggest → wait |
|
|
187
|
+
| Apex service | Skip | Skip | Suggest → wait |
|
|
188
|
+
|
|
189
|
+
**Data mode control:** `ENABLE_SAMPLE_DATA_CACHE` in `src/lib/dataStrategy.ts` is the backend switch. `CommandCenter.tsx` reads this flag and passes `initialMode` to `DataModeProvider`. Phase 1 leaves it `true` (sample data). Phase 2 flips it to `false` (live data — different travelers, cities, and metrics). There is no UI toggle.
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# Efficient Build Process
|
|
2
2
|
|
|
3
|
+
## The #1 Rule: Phase 1 Writes, Phases 2-3 Edit
|
|
4
|
+
|
|
5
|
+
- **Phase 1** creates `EngineDashboard.tsx` from scratch (Write). Also writes CommandCenter.tsx, Home.tsx, edits routes.tsx.
|
|
6
|
+
- **Phase 2** makes ~5 surgical edits to the existing dashboard (StrReplace / targeted edits). Never rewrites the file.
|
|
7
|
+
- **Phase 3** makes ~4 surgical edits to the existing dashboard (StrReplace / targeted edits). Never rewrites the file.
|
|
8
|
+
|
|
9
|
+
Rewriting a 400+ line file from scratch takes 60 seconds, risks losing prior work, and can introduce regressions. Surgical edits take seconds each and preserve everything.
|
|
10
|
+
|
|
3
11
|
## Speed Rules
|
|
4
12
|
|
|
5
13
|
1. **Load only 2 files before building:** the PRD and this skill (command-center-builder). Do NOT load component-library, command-center-project, or outer-app skills — they add latency and aren't needed for the initial build.
|
|
6
14
|
|
|
7
|
-
2. **Do NOT read component source files.** The props for every component (GeoMap, BaseCard, Avatar, ChartCard, D3Chart, etc.) are documented in this skill and the PRD. Reading `GeoMap.jsx`, `BaseCard.jsx`, etc. wastes time and produces no new information.
|
|
15
|
+
2. **Do NOT read component source files.** The props for every component (GeoMap, BaseCard, Avatar, ChartCard, D3Chart, etc.) are documented in this skill and the PRD. Reading `GeoMap.jsx`, `BaseCard.jsx`, `useDataSource.js`, `DataModeProvider.jsx`, etc. wastes time and produces no new information.
|
|
8
16
|
|
|
9
|
-
3. **Write the dashboard in one pass.** Plan the full file before writing. Do not write a partial dashboard and iterate — write the complete component with all imports, data, and JSX in a single Write call.
|
|
17
|
+
3. **Phase 1: Write the dashboard in one pass.** Plan the full file before writing. Do not write a partial dashboard and iterate — write the complete component with all imports, data, and JSX in a single Write call. Then write all 4 files without stopping.
|
|
10
18
|
|
|
11
|
-
4. **
|
|
19
|
+
4. **Phases 2-3: Make targeted edits only.** Read the existing dashboard, then make specific edits (add imports, update lines, insert JSX blocks). Do NOT use Write to replace the entire file.
|
|
12
20
|
|
|
13
21
|
5. **Do NOT run `npm run build`, `npm run dev`, `tsc`, or `npm run validate:dashboard` during the build.** These waste time. The Vite build handles JSX/TSX regardless of TypeScript errors, and pre-existing TS7016 errors (from untyped .jsx library files) are normal.
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
6. **STOP and ASK before creating metadata.** Custom fields, platform events, and Apex classes are scripted demo moments. Suggest them, wait for "yes," then create. Never just create them.
|
|
24
|
+
|
|
25
|
+
## Phase 1 File Write Order
|
|
16
26
|
|
|
17
27
|
```
|
|
18
28
|
1. src/pages/EngineDashboard.tsx ← full dashboard, one pass
|
|
@@ -21,12 +31,38 @@
|
|
|
21
31
|
4. src/routes.tsx ← edit index route label to "Dashboard"
|
|
22
32
|
```
|
|
23
33
|
|
|
34
|
+
## Phase 2 Edit Order
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
1. Add useEngineLiveData import to EngineDashboard.tsx
|
|
38
|
+
2. Add const live = useEngineLiveData() hook call
|
|
39
|
+
3. Update each useDataSource({ sample, live: [] }) → live: live.xxx
|
|
40
|
+
4. Update KPI derivations to use activeMetrics
|
|
41
|
+
5. Flip ENABLE_SAMPLE_DATA_CACHE to false in src/lib/dataStrategy.ts
|
|
42
|
+
→ STOP — suggest Weather_Impact__c, wait for confirmation
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
No UI toggle. The switch is `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts`. When `false`, `CommandCenter.tsx` passes `initialMode="live"` and every `useDataSource` returns its live prop.
|
|
46
|
+
|
|
47
|
+
## Phase 3 Edit Order
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
1. Add ChatBar import (if not in barrel import)
|
|
51
|
+
2. Add CHAT_SUGGESTIONS constant + handleChat function
|
|
52
|
+
3. Insert <ChatBar /> JSX between map and data panels
|
|
53
|
+
4. Add AgentforceConversationClient
|
|
54
|
+
→ STOP — suggest platform event, wait for confirmation
|
|
55
|
+
→ STOP — suggest Apex class, wait for confirmation
|
|
56
|
+
```
|
|
57
|
+
|
|
24
58
|
## Common Time Wasters
|
|
25
59
|
|
|
26
60
|
| Waste | Fix |
|
|
27
61
|
|-------|-----|
|
|
28
62
|
| Loading 4-5 skills before starting | Load only command-center-builder + PRD |
|
|
29
|
-
| Reading GeoMap.jsx, Avatar.jsx,
|
|
30
|
-
|
|
|
63
|
+
| Reading GeoMap.jsx, Avatar.jsx, useDataSource.js source | Props/patterns are in this skill — trust the docs |
|
|
64
|
+
| Rewriting EngineDashboard.tsx from scratch in Phase 2/3 | Make 5 surgical edits, not a 454-line rewrite |
|
|
65
|
+
| Running `npm run build` between edits | Don't — Vite handles it, TS errors are pre-existing |
|
|
31
66
|
| Fixing imports iteratively (wrong icon names, wrong exports) | Check the PRD and this skill for exact import names before writing |
|
|
32
67
|
| Writing Home.tsx with Account Search content | REPLACE it with the 3-line CommandCenter wrapper (see WIRING section) |
|
|
68
|
+
| Creating metadata without asking | STOP, suggest, wait for "yes" — it's a scripted demo moment |
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.79] - 2026-04-04
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Data mode switching was broken** — `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts` was dead code (nothing read it). `useEngineLiveData` was auto-calling `setMode("live")` after 2 seconds via React context, which was fragile and confusing
|
|
12
|
+
- **No visible data change between phases** — Phase 2 should produce visibly different data (12 global travelers vs 8 US travelers, Midwest storm scenario) but the switching mechanism wasn't wired to `dataStrategy.ts`
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **`useEngineLiveData.ts`** — Removed `setMode("sample"/"live")` calls. Hook now just provides the live data; it no longer controls the data mode
|
|
16
|
+
- **`useDataSource.jsx`** — Updated to fall back to sample when live is null/empty, reads mode from `DataModeProvider` context which is now properly controlled by `dataStrategy.ts`
|
|
17
|
+
- **`CommandCenter.tsx` template** — Now imports `ENABLE_SAMPLE_DATA_CACHE` from `@/lib/dataStrategy` and passes `initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}` to `DataModeProvider`
|
|
18
|
+
- **`dataStrategy.ts` template** — Rewritten comments to explain the Phase 1/Phase 2 connection and how flipping the flag changes the dashboard data
|
|
19
|
+
- **Build guide Phase 2** — Added step 5: "Flip `ENABLE_SAMPLE_DATA_CACHE` to `false`". Added explanation of what changes visually (different names, cities, metrics)
|
|
20
|
+
- **PRD Phase 2** — Added `dataStrategy.ts` flip as step 6 with explanation of the visual change
|
|
21
|
+
- **Efficient build process** — Updated Phase 2 edit order to include the flag flip
|
|
22
|
+
- **SKILL.md** — Updated `CommandCenter.tsx` wiring example to include `ENABLE_SAMPLE_DATA_CACHE` import
|
|
23
|
+
|
|
24
|
+
**Context:** The data mode switch was supposed to be a backend config (`dataStrategy.ts`) but the flag was disconnected. The actual switching was done by `useEngineLiveData` auto-calling `setMode("live")` after a 2-second delay, which meant the hook controlled both data AND mode — not clean. Now: `dataStrategy.ts` is the single control point, `CommandCenter.tsx` reads it, `DataModeProvider` respects it, and `useDataSource` returns the right data. Phase 2 just flips the flag.
|
|
25
|
+
|
|
26
|
+
## [1.9.78] - 2026-04-04
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- **Phase 2 rewrites entire dashboard** — Agent was writing a brand new 454-line file instead of making ~4 surgical edits. Build guide and PRD now enforce "Phase 1 writes, Phases 2-3 edit" with explicit edit lists
|
|
30
|
+
- **Agent creates metadata without asking** — Agent was creating custom fields/platform events/Apex without waiting for user confirmation. All phases now say "STOP and suggest — wait for yes" with scripted dialogue
|
|
31
|
+
- **Agent reads 6+ files before starting Phase 2** — Now limited to reading only the dashboard and live data file; library component source files are explicitly prohibited
|
|
32
|
+
- **DataModeToggle in the UI** — Removed from all Phase 2 instructions. Data mode is controlled by `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts`, not a visible toggle
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- **Build guide (`getting-started.md`)** — Full rewrite with surgical edit instructions for Phases 2-3, explicit "files to read" and "do NOT read" lists, "STOP and ASK" enforcement for metadata creation
|
|
36
|
+
- **Efficient build process (`improved-build-process.md`)** — Added "#1 Rule: Phase 1 Writes, Phases 2-3 Edit", phase-specific edit orders, metadata ask-before-creating rule
|
|
37
|
+
- **PRD Prompt 2** — Added "What the agent must NOT do" section, removed DataModeToggle, reworded user prompt to remove "toggle" language
|
|
38
|
+
- **PRD Prompt 3** — Added "What the agent must NOT do" section, enforced stop-and-ask pattern for each metadata creation
|
|
39
|
+
|
|
8
40
|
## [1.9.77] - 2026-04-04
|
|
9
41
|
|
|
10
42
|
### Added
|
|
@@ -348,18 +348,29 @@ Build incrementally in 3 prompts. Each prompt builds on the previous result. The
|
|
|
348
348
|
|
|
349
349
|
### Prompt 2 — Connect to Salesforce Data
|
|
350
350
|
|
|
351
|
-
> Now let's connect this to real data. There's a second dataset with different travelers and metrics — hook that up as the "live" data source so
|
|
351
|
+
> Now let's connect this to real data. There's a second dataset with different travelers and metrics — hook that up as the "live" data source so the dashboard can pull from either dataset depending on the backend config. After that, see if there are any data model improvements we should make for tracking weather disruptions.
|
|
352
352
|
|
|
353
353
|
**What the agent must do:**
|
|
354
354
|
|
|
355
|
-
1.
|
|
356
|
-
2.
|
|
357
|
-
3.
|
|
358
|
-
4.
|
|
355
|
+
1. Read only `EngineDashboard.tsx` and `src/hooks/useEngineLiveData.ts` — don't read `useDataSource.jsx`, `DataModeProvider.jsx`, or other library source files (the patterns are in the build guide)
|
|
356
|
+
2. Make **surgical edits** to the existing `EngineDashboard.tsx` — do NOT rewrite the entire file
|
|
357
|
+
3. Add `useEngineLiveData` import and hook call
|
|
358
|
+
4. Update every `useDataSource({ sample, live })` call to pass live data
|
|
359
|
+
5. Update KPI overlays to derive from whichever metrics are active
|
|
360
|
+
6. **Flip the backend switch:** change `ENABLE_SAMPLE_DATA_CACHE` from `true` to `false` in `src/lib/dataStrategy.ts` — this makes `CommandCenter.tsx` pass `initialMode="live"` to `DataModeProvider`, so every `useDataSource` call now returns the live prop. The dashboard will show completely different data: 12 global travelers (Raj Kapoor, Sofia Reyes…) instead of 8 US travelers, a Midwest storm scenario, and different metrics.
|
|
361
|
+
7. After wiring is complete, **STOP and suggest** the `Weather_Impact__c` custom field — do NOT create it until the user confirms
|
|
359
362
|
|
|
360
|
-
**
|
|
363
|
+
**What the agent must NOT do in this prompt:**
|
|
364
|
+
- Do NOT rewrite `EngineDashboard.tsx` from scratch — make targeted edits to the existing Phase 1 file
|
|
365
|
+
- Do NOT read library component source files (`useDataSource.jsx`, `DataModeProvider.jsx`, `dataStrategy.ts`) — the wiring patterns are in the build guide
|
|
366
|
+
- Do NOT add `DataModeToggle` to the UI — there is no UI toggle, the switch is `dataStrategy.ts`
|
|
367
|
+
- Do NOT create the custom field without asking first — suggest it, then wait for "yes"
|
|
368
|
+
- Do NOT add ChatBar, Eva, or any Agentforce integration — that's Prompt 3
|
|
369
|
+
- Do NOT run `npm run build` between edits
|
|
370
|
+
|
|
371
|
+
**Reference — what the agent should say after wiring:**
|
|
361
372
|
|
|
362
|
-
|
|
373
|
+
*"I notice `Flight__c` doesn't have a field to track weather impact on individual flights. A `Weather_Impact__c` picklist would help the dashboard filter storm-affected flights. Want me to create it?"* — Only create the custom field XML from section 14a AFTER the user confirms.
|
|
363
374
|
|
|
364
375
|
---
|
|
365
376
|
|
|
@@ -369,16 +380,22 @@ After wiring the live data: *"I notice `Flight__c` doesn't have a field to track
|
|
|
369
380
|
|
|
370
381
|
**What the agent must do:**
|
|
371
382
|
|
|
372
|
-
1.
|
|
373
|
-
2. Add `
|
|
374
|
-
3.
|
|
375
|
-
4. After the event
|
|
383
|
+
1. Make **surgical edits** to the existing `EngineDashboard.tsx` — do NOT rewrite the entire file
|
|
384
|
+
2. Add `ChatBar` with suggestions from section 9, placed between map and data panels
|
|
385
|
+
3. Add `AgentforceConversationClient` with `agentId="0Xxa5000000relhCAA"` and `agentLabel="Eva"`
|
|
386
|
+
4. After adding Eva, **STOP and suggest** the platform event — do NOT create it until the user confirms
|
|
387
|
+
5. After user confirms and platform event is created, **STOP and suggest** the Apex class — do NOT create it until the user confirms
|
|
388
|
+
|
|
389
|
+
**What the agent must NOT do in this prompt:**
|
|
390
|
+
- Do NOT rewrite `EngineDashboard.tsx` from scratch — make targeted edits to the existing Phase 2 file
|
|
391
|
+
- Do NOT create platform events or Apex classes without user confirmation — each is a scripted demo moment where you suggest, wait, then create
|
|
392
|
+
- Do NOT read library component source files
|
|
376
393
|
|
|
377
|
-
**Reference — what the agent should say:**
|
|
394
|
+
**Reference — what the agent should say (in sequence, stopping after each):**
|
|
378
395
|
|
|
379
|
-
1. After adding Eva: *"The dashboard tracks disruptions in real time. I can create a `Travel_Disruption_Alert__e` platform event so disruption data can be published to the Salesforce event bus — other systems and automation can subscribe to it. Want me to set it up?"* —
|
|
396
|
+
1. After adding Eva: *"The dashboard tracks disruptions in real time. I can create a `Travel_Disruption_Alert__e` platform event so disruption data can be published to the Salesforce event bus — other systems and automation can subscribe to it. Want me to set it up?"* — Only create the platform event (section 14b) AFTER the user confirms.
|
|
380
397
|
|
|
381
|
-
2. After the platform event: *"Now I'll write an Apex service class to publish disruption records to that event bus. `TravelDisruptionEventService` will take a list of disruptions and fire platform events with the flight number, severity, and description. Want me to create it?"* —
|
|
398
|
+
2. After the platform event: *"Now I'll write an Apex service class to publish disruption records to that event bus. `TravelDisruptionEventService` will take a list of disruptions and fire platform events with the flight number, severity, and description. Want me to create it?"* — Only create the Apex class (section 14c) AFTER the user confirms.
|
|
382
399
|
|
|
383
400
|
---
|
|
384
401
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useState, useEffect } from "react";
|
|
2
|
-
import { useDataMode } from "@/components/library/data/DataModeProvider";
|
|
3
2
|
import * as live from "@/data/engine-live-data";
|
|
4
3
|
|
|
5
4
|
const SIMULATED_LOAD_MS = 2000;
|
|
@@ -18,26 +17,22 @@ export interface EngineLiveData {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
20
|
+
* Provides the live dataset for the Engine Travel Command Center.
|
|
22
21
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* live prop instead of
|
|
27
|
-
* simultaneously with new data.
|
|
22
|
+
* Simulates a 2-second network fetch, then resolves with all live data.
|
|
23
|
+
* Does NOT control the data mode — that's handled by ENABLE_SAMPLE_DATA_CACHE
|
|
24
|
+
* in src/lib/dataStrategy.ts. When the flag is false, every useDataSource call
|
|
25
|
+
* returns its live prop (which this hook provides) instead of its sample prop.
|
|
28
26
|
*/
|
|
29
27
|
export function useEngineLiveData(): EngineLiveData {
|
|
30
28
|
const [loading, setLoading] = useState(true);
|
|
31
|
-
const { setMode } = useDataMode();
|
|
32
29
|
|
|
33
30
|
useEffect(() => {
|
|
34
|
-
setMode("sample");
|
|
35
31
|
const timer = setTimeout(() => {
|
|
36
32
|
setLoading(false);
|
|
37
|
-
setMode("live");
|
|
38
33
|
}, SIMULATED_LOAD_MS);
|
|
39
34
|
return () => clearTimeout(timer);
|
|
40
|
-
}, [
|
|
35
|
+
}, []);
|
|
41
36
|
|
|
42
37
|
return {
|
|
43
38
|
loading,
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { useMemo as
|
|
2
|
-
import { useDataMode as
|
|
3
|
-
function
|
|
4
|
-
const { mode:
|
|
5
|
-
return
|
|
6
|
-
const o = r === "sample" ? t : e;
|
|
7
|
-
return typeof o == "function" ? o() : o;
|
|
8
|
-
}, [r, t, e]);
|
|
1
|
+
import { useMemo as n } from "react";
|
|
2
|
+
import { useDataMode as u } from "./DataModeProvider.js";
|
|
3
|
+
function a({ sample: t, live: r }) {
|
|
4
|
+
const { mode: o } = u();
|
|
5
|
+
return n(() => o === "live" && r != null && !(Array.isArray(r) && r.length === 0) ? typeof r == "function" ? r() : r : typeof t == "function" ? t() : t, [o, t, r]);
|
|
9
6
|
}
|
|
10
7
|
export {
|
|
11
|
-
|
|
8
|
+
a as default
|
|
12
9
|
};
|
|
13
10
|
//# sourceMappingURL=useDataSource.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.jsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n *
|
|
1
|
+
{"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.jsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * The mode is controlled by ENABLE_SAMPLE_DATA_CACHE in src/lib/dataStrategy.ts,\n * which CommandCenter.tsx passes to DataModeProvider as initialMode.\n * When the flag is true, mode is \"sample\" and this hook returns the sample prop.\n * When false, mode is \"live\" and this hook returns the live prop.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n * const incidents = useDataSource({\n * sample: sampleIncidents,\n * live: fetchedIncidents,\n * });\n */\nexport default function useDataSource({ sample, live }) {\n const { mode } = useDataMode();\n\n return useMemo(() => {\n if (mode === \"live\" && live != null && !(Array.isArray(live) && live.length === 0)) {\n return typeof live === \"function\" ? live() : live;\n }\n return typeof sample === \"function\" ? sample() : sample;\n }, [mode, sample, live]);\n}\n"],"names":["useDataSource","sample","live","mode","useDataMode","useMemo"],"mappings":";;AAsBA,SAAwBA,EAAc,EAAE,QAAAC,GAAQ,MAAAC,KAAQ;AACtD,QAAM,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,SAAOC,EAAQ,MACTF,MAAS,UAAUD,KAAQ,QAAQ,EAAE,MAAM,QAAQA,CAAI,KAAKA,EAAK,WAAW,KACvE,OAAOA,KAAS,aAAaA,EAAA,IAASA,IAExC,OAAOD,KAAW,aAAaA,EAAA,IAAWA,GAChD,CAACE,GAAMF,GAAQC,CAAI,CAAC;AACzB;"}
|
package/package.json
CHANGED
|
@@ -4,30 +4,29 @@ import { useDataMode } from "./DataModeProvider";
|
|
|
4
4
|
/**
|
|
5
5
|
* Select between sample and live data based on the global data mode.
|
|
6
6
|
*
|
|
7
|
+
* The mode is controlled by ENABLE_SAMPLE_DATA_CACHE in src/lib/dataStrategy.ts,
|
|
8
|
+
* which CommandCenter.tsx passes to DataModeProvider as initialMode.
|
|
9
|
+
* When the flag is true, mode is "sample" and this hook returns the sample prop.
|
|
10
|
+
* When false, mode is "live" and this hook returns the live prop.
|
|
11
|
+
*
|
|
7
12
|
* Values can be plain data or functions (lazy-evaluated only when active).
|
|
8
13
|
*
|
|
9
14
|
* @param {{ sample: any | () => any, live: any | () => any }} sources
|
|
10
15
|
* @returns {any} the resolved value for the active mode
|
|
11
16
|
*
|
|
12
17
|
* @example
|
|
13
|
-
* // Static data
|
|
14
18
|
* const incidents = useDataSource({
|
|
15
19
|
* sample: sampleIncidents,
|
|
16
20
|
* live: fetchedIncidents,
|
|
17
21
|
* });
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // Lazy — factory only runs when that mode is active
|
|
21
|
-
* const metrics = useDataSource({
|
|
22
|
-
* sample: () => generateSampleMetrics(),
|
|
23
|
-
* live: () => computeFromAPI(apiData),
|
|
24
|
-
* });
|
|
25
22
|
*/
|
|
26
23
|
export default function useDataSource({ sample, live }) {
|
|
27
24
|
const { mode } = useDataMode();
|
|
28
25
|
|
|
29
26
|
return useMemo(() => {
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
if (mode === "live" && live != null && !(Array.isArray(live) && live.length === 0)) {
|
|
28
|
+
return typeof live === "function" ? live() : live;
|
|
29
|
+
}
|
|
30
|
+
return typeof sample === "function" ? sample() : sample;
|
|
32
31
|
}, [mode, sample, live]);
|
|
33
32
|
}
|
|
@@ -1,42 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Data Strategy Configuration
|
|
3
3
|
*
|
|
4
|
-
* Controls
|
|
4
|
+
* Controls which dataset the dashboard displays.
|
|
5
5
|
*
|
|
6
6
|
* ENABLE_SAMPLE_DATA_CACHE:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Faster load times during development
|
|
10
|
-
* - Consistent data for testing and presentations
|
|
11
|
-
* - Reduced API load
|
|
12
|
-
* - Offline-first capability
|
|
7
|
+
* - true → Dashboard shows sample data (default after install)
|
|
8
|
+
* - false → Dashboard shows live data (different travelers, cities, metrics)
|
|
13
9
|
*
|
|
14
10
|
* HOW IT WORKS:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* seamless switching between data sources without code changes.
|
|
11
|
+
* CommandCenter.tsx reads this flag and passes initialMode to DataModeProvider:
|
|
12
|
+
* initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}
|
|
18
13
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
14
|
+
* Every useDataSource({ sample, live }) call returns whichever prop matches
|
|
15
|
+
* the active mode. When you flip this flag to false, the dashboard instantly
|
|
16
|
+
* shows the live dataset on next load — no code changes needed.
|
|
22
17
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
18
|
+
* USAGE:
|
|
19
|
+
* Phase 1 (Build the Dashboard): Leave as true — sample data.
|
|
20
|
+
* Phase 2 (Connect to Live Data): Flip to false — live data with different
|
|
21
|
+
* travelers, cities, disruptions, and metrics.
|
|
25
22
|
*/
|
|
26
23
|
|
|
27
24
|
export const ENABLE_SAMPLE_DATA_CACHE = true;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Sample data cache is currently ENABLED
|
|
31
|
-
*
|
|
32
|
-
* Benefits:
|
|
33
|
-
* ✓ Instant data loading (no network latency)
|
|
34
|
-
* ✓ No API rate limiting concerns
|
|
35
|
-
* ✓ Consistent data for demos and testing
|
|
36
|
-
* ✓ Works offline
|
|
37
|
-
* ✓ Reduced backend load
|
|
38
|
-
*
|
|
39
|
-
* To enable live API data:
|
|
40
|
-
* 1. Set ENABLE_SAMPLE_DATA_CACHE to false
|
|
41
|
-
* 2. Restart the development server
|
|
42
|
-
*/
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import AppThemeProvider from "@/components/library/theme/AppThemeProvider";
|
|
2
2
|
import DataModeProvider from "@/components/library/data/DataModeProvider";
|
|
3
|
+
import { ENABLE_SAMPLE_DATA_CACHE } from "@/lib/dataStrategy";
|
|
3
4
|
import { Toaster } from "sonner";
|
|
4
5
|
import BlankDashboard from "../pages/BlankDashboard";
|
|
5
6
|
|
|
6
7
|
export default function CommandCenter() {
|
|
7
8
|
return (
|
|
8
9
|
<AppThemeProvider initialMode="light">
|
|
9
|
-
<DataModeProvider initialMode="sample">
|
|
10
|
+
<DataModeProvider initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}>
|
|
10
11
|
<BlankDashboard />
|
|
11
12
|
<Toaster position="bottom-right" />
|
|
12
13
|
</DataModeProvider>
|