@gymmymac/bob-widget 3.2.3 → 3.2.5
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/BOB-DOCUMENTATION.md +17 -134
- package/CHANGELOG.md +16 -0
- package/README.md +11 -8
- package/dist/__tests__/bobV2DirectorModes.test.d.ts +10 -0
- package/dist/__tests__/quickReplyAndStopSpeech.test.d.ts +11 -0
- package/dist/__tests__/v325BugFixes.test.d.ts +9 -0
- package/dist/components/BobStandalone.d.ts +18 -1
- package/dist/components/mobile/ContainedChatDrawer.d.ts +4 -0
- package/dist/components/mobile/ContainedMobileBobLayout.d.ts +4 -0
- package/dist/components/mobile/MobileBobLayout.d.ts +4 -0
- package/dist/components/mobile/MobileChatDrawer.d.ts +4 -0
- package/dist/hooks/useBobAnalytics.d.ts +12 -1
- package/dist/hooks/useBobChat.d.ts +2 -0
- package/dist/hooks/useMicPermission.d.ts +12 -0
- package/dist/hooks/useSpeechSynthesis.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +32 -32
- package/dist/index.mjs +4168 -3878
- package/dist/types/context.d.ts +5 -0
- package/dist/types/message.d.ts +8 -0
- package/package.json +1 -1
- package/install/carfix/00-README-PREINSTALL.md +0 -111
- package/install/carfix/05-runtime-verification-checklist.md +0 -54
- package/install/carfix/CARFIX-INSTALLATION-BRIEF.md +0 -367
package/dist/types/context.d.ts
CHANGED
|
@@ -153,6 +153,11 @@ export interface BobCallbacks {
|
|
|
153
153
|
onError?: (error: Error) => void;
|
|
154
154
|
/** Called for every trackable event - for server-side analytics */
|
|
155
155
|
onAnalyticsEvent?: (event: BobAnalyticsEvent) => void;
|
|
156
|
+
/**
|
|
157
|
+
* Called once when the internal stopSpeech function is ready.
|
|
158
|
+
* Capture it to expose imperative speech control to the host (e.g. via BobStandaloneHandle).
|
|
159
|
+
*/
|
|
160
|
+
onStopSpeechReady?: (fn: () => void) => void;
|
|
156
161
|
}
|
|
157
162
|
/**
|
|
158
163
|
* Complete configuration for BobProvider
|
package/dist/types/message.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Product } from './product';
|
|
2
2
|
|
|
3
|
+
export interface QuickReply {
|
|
4
|
+
/** Button label, e.g. "View Brake Pads" */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Navigation URL, e.g. "/products/brake-pads" */
|
|
7
|
+
url: string;
|
|
8
|
+
}
|
|
3
9
|
export interface Message {
|
|
4
10
|
role: "user" | "assistant";
|
|
5
11
|
content: string;
|
|
@@ -7,6 +13,8 @@ export interface Message {
|
|
|
7
13
|
suggestedProducts?: Product[];
|
|
8
14
|
/** Custom header for suggestions (e.g., "Wipers for your 2018 Toyota Rav 4") */
|
|
9
15
|
suggestionsTitle?: string;
|
|
16
|
+
/** Navigation CTA buttons — tap fires onNavigate(url), no chat message sent */
|
|
17
|
+
quickReplies?: QuickReply[];
|
|
10
18
|
}
|
|
11
19
|
export interface HighlightedProduct {
|
|
12
20
|
brand: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gymmymac/bob-widget",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.5",
|
|
4
4
|
"description": "Bob - AI-powered automotive parts assistant widget with multi-tenant support, RAF animations, swipeable interactions, and GA4 analytics",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# Bob Widget v3.1.11 - CARFIX Installation Guide
|
|
2
|
-
|
|
3
|
-
> 🚨 **STOP - READ THIS FIRST**
|
|
4
|
-
>
|
|
5
|
-
> Bob v3.1.11 requires a **strict 3-stage installation process**. Skipping stages WILL cause visual issues (blur, wrong scale, wrong position).
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
The 3-stage process ensures:
|
|
10
|
-
1. **Stage A**: No old code remains (forensic removal)
|
|
11
|
-
2. **Stage B**: Container is correctly configured (page preparation)
|
|
12
|
-
3. **Stage C**: Only the new version is installed and verified
|
|
13
|
-
|
|
14
|
-
## Quick Start (CLI)
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
# Stage A: Forensic Scan & Purge
|
|
18
|
-
npx @gymmymac/bob-widget carfix stage-a
|
|
19
|
-
|
|
20
|
-
# Stage B: Generate Page Template (if you have existing Header/BottomNav)
|
|
21
|
-
npx @gymmymac/bob-widget carfix stage-b --target next-pages --output pages/ask-bob.tsx
|
|
22
|
-
|
|
23
|
-
# Stage B: Generate Page Template WITH Layout Components (if you need Header/BottomNav)
|
|
24
|
-
npx @gymmymac/bob-widget carfix stage-b --target next-pages --with-layout
|
|
25
|
-
|
|
26
|
-
# Stage C: Install & Verify
|
|
27
|
-
npx @gymmymac/bob-widget carfix stage-c --partner CARFIX
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## What Each Stage Does
|
|
31
|
-
|
|
32
|
-
### Stage A: Forensic Removal
|
|
33
|
-
|
|
34
|
-
**Time: 2-5 minutes**
|
|
35
|
-
|
|
36
|
-
Scans for and removes:
|
|
37
|
-
- Bob component files (`Bob*.tsx`, `AskBob*.tsx`)
|
|
38
|
-
- Bob hook files (`useBob*.ts`)
|
|
39
|
-
- Bob type definitions (`*bob*.d.ts`)
|
|
40
|
-
- Bob imports in any file
|
|
41
|
-
- `BOB_` environment variables
|
|
42
|
-
- Cached packages
|
|
43
|
-
|
|
44
|
-
If issues are found, the script **exits with an error** and lists what to delete manually.
|
|
45
|
-
|
|
46
|
-
### Stage B: Page Preparation
|
|
47
|
-
|
|
48
|
-
**Time: 1 minute**
|
|
49
|
-
|
|
50
|
-
Generates a container page template for your framework:
|
|
51
|
-
- `next-pages` - Next.js Pages Router
|
|
52
|
-
- `next-app` - Next.js App Router
|
|
53
|
-
- `react-router` - React Router (Vite)
|
|
54
|
-
|
|
55
|
-
**⚠️ IMPORTANT: Layout Components Required**
|
|
56
|
-
|
|
57
|
-
The container height formula assumes you have:
|
|
58
|
-
- **CARFIX Header**: 72px fixed at top
|
|
59
|
-
- **CARFIX Bottom Navigation**: 72px fixed at bottom
|
|
60
|
-
|
|
61
|
-
If these components **don't exist**, use the `--with-layout` flag:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npx @gymmymac/bob-widget carfix stage-b --target next-pages --with-layout
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
This generates:
|
|
68
|
-
- `components/CarfixHeader.tsx` (72px header)
|
|
69
|
-
- `components/CarfixBottomNav.tsx` (72px bottom nav)
|
|
70
|
-
- Complete page template with layout wired up
|
|
71
|
-
|
|
72
|
-
The template includes the correct container height calculation:
|
|
73
|
-
```css
|
|
74
|
-
height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Stage C: Install & Verify
|
|
78
|
-
|
|
79
|
-
**Time: 1-2 minutes**
|
|
80
|
-
|
|
81
|
-
- Installs `@gymmymac/bob-widget@3.1.11`
|
|
82
|
-
- Verifies the installed version
|
|
83
|
-
- Tests backend connectivity
|
|
84
|
-
- Provides final code integration example
|
|
85
|
-
|
|
86
|
-
## Manual Scripts
|
|
87
|
-
|
|
88
|
-
If you prefer to run the stages manually, see:
|
|
89
|
-
- `01-stage-a-forensic-scan.sh` / `.ps1`
|
|
90
|
-
- `02-stage-a-cache-purge.sh` / `.ps1`
|
|
91
|
-
- `03-stage-b-generate-container-template.mjs`
|
|
92
|
-
- `04-stage-c-install-and-verify.mjs`
|
|
93
|
-
|
|
94
|
-
## Verification Checklist
|
|
95
|
-
|
|
96
|
-
After completing all stages, verify in browser:
|
|
97
|
-
|
|
98
|
-
| Test | Expected Result |
|
|
99
|
-
|------|-----------------|
|
|
100
|
-
| Console version | `[BobWidget] Package loaded - v3.1.11` |
|
|
101
|
-
| Bob visibility | Fully visible, not cropped |
|
|
102
|
-
| No blur | Background is NOT blurred |
|
|
103
|
-
| Correct scale | Bob is prominently sized |
|
|
104
|
-
| Chat works | Messages send and Bob responds |
|
|
105
|
-
| PTT (HTTPS) | Speech recognition activates |
|
|
106
|
-
| Header visible | 72px CARFIX header at top |
|
|
107
|
-
| Bottom nav visible | 72px navigation at bottom |
|
|
108
|
-
|
|
109
|
-
## Support
|
|
110
|
-
|
|
111
|
-
For issues, check the troubleshooting section in `BOB-DOCUMENTATION.md`.
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# Bob Widget v3.1.19 - Runtime Verification Checklist
|
|
2
|
-
|
|
3
|
-
> Complete this checklist after Stage C to confirm Bob is working correctly.
|
|
4
|
-
|
|
5
|
-
## Browser Console Checks
|
|
6
|
-
|
|
7
|
-
Open DevTools (F12) → Console tab:
|
|
8
|
-
|
|
9
|
-
- [ ] `[BobWidget] Package loaded - v3.1.19`
|
|
10
|
-
- [ ] `[BobStandalone] Initialized { version: "3.1.19", partner: "CARFIX", ... }`
|
|
11
|
-
- [ ] `[BobWidget] Partner config loaded: { partner: "CARFIX", ... }`
|
|
12
|
-
- [ ] No red error messages
|
|
13
|
-
|
|
14
|
-
## Network Tab Checks
|
|
15
|
-
|
|
16
|
-
Filter by `gjoguxzstsihhxvdgpto`:
|
|
17
|
-
|
|
18
|
-
- [ ] `bob_partners` query returns 200
|
|
19
|
-
- [ ] `bob_looks` query returns 200
|
|
20
|
-
- [ ] `animation_states` query returns 200
|
|
21
|
-
- [ ] `bob_animations` query returns 200
|
|
22
|
-
- [ ] `bob_backdrops` query returns 200
|
|
23
|
-
|
|
24
|
-
## Visual Checks
|
|
25
|
-
|
|
26
|
-
- [ ] **Bob Visibility**: Character is fully visible, not cropped at top or bottom
|
|
27
|
-
- [ ] **No Blur**: Background backdrop is NOT blurred (should be crisp)
|
|
28
|
-
- [ ] **Correct Scale**: Bob is prominently sized (~140% mobile scale)
|
|
29
|
-
- [ ] **Position**: Bob stands ON the counter overlay, not below it
|
|
30
|
-
- [ ] **Container**: Bob fills space between CARFIX header and bottom nav
|
|
31
|
-
|
|
32
|
-
## Functional Checks
|
|
33
|
-
|
|
34
|
-
- [ ] **Chat Input**: Type a message → Bob responds
|
|
35
|
-
- [ ] **PTT** (HTTPS only): Click microphone → speech recognition activates
|
|
36
|
-
- [ ] **Vehicle Lookup**: Enter REGO (e.g., "HZP550") → Vehicle info returned
|
|
37
|
-
- [ ] **Products**: Ask for parts → Products appear on shelf
|
|
38
|
-
- [ ] **Add to Cart**: Say "add to cart" → `onAddToCart` callback fires
|
|
39
|
-
|
|
40
|
-
## Common Issues
|
|
41
|
-
|
|
42
|
-
| Issue | Solution |
|
|
43
|
-
|-------|----------|
|
|
44
|
-
| Wrong version in console | Clear `.vite` cache, restart dev server |
|
|
45
|
-
| Background is blurred | Check CSS `--bob-blur-intensity` is 0 |
|
|
46
|
-
| Bob is tiny | Check `scale` value in `bob_animations` table |
|
|
47
|
-
| Bob is cropped | Container height not using 144px offset formula |
|
|
48
|
-
| No products loading | Check `vehicle_id` is numeric in session token |
|
|
49
|
-
|
|
50
|
-
## Pass/Fail
|
|
51
|
-
|
|
52
|
-
If all checks pass: ✅ **Bob is correctly installed**
|
|
53
|
-
|
|
54
|
-
If any check fails: See troubleshooting in `BOB-DOCUMENTATION.md` Section 9.
|
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
# Bob Widget — CARFIX Installation Brief
|
|
2
|
-
|
|
3
|
-
**Package:** `@gymmymac/bob-widget@3.1.19`
|
|
4
|
-
**Date:** 2026-02-13
|
|
5
|
-
**Status:** Production-ready, 36 unit tests passing, E2E baseline locked
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Peer Dependencies (Critical for Build)
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{
|
|
13
|
-
"peerDependencies": {
|
|
14
|
-
"react": "^18.0.0",
|
|
15
|
-
"react-dom": "^18.0.0"
|
|
16
|
-
},
|
|
17
|
-
"dependencies (bundled — no action needed)": {
|
|
18
|
-
"@supabase/supabase-js": "^2.84.0",
|
|
19
|
-
"@tanstack/react-query": "^5.0.0"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
> If CARFIX already uses `@tanstack/react-query`, ensure versions are compatible (v5+).
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 2. Installation
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm install @gymmymac/bob-widget@latest
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 3. Minimal Integration (4 lines)
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
import { BobStandalone } from '@gymmymac/bob-widget';
|
|
40
|
-
|
|
41
|
-
function AskBobPage() {
|
|
42
|
-
const router = useRouter();
|
|
43
|
-
const sessionToken = router.query.session as string;
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div style={{
|
|
47
|
-
height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
|
|
48
|
-
position: 'relative',
|
|
49
|
-
/* DO NOT use overflow: hidden — clips PTT button and chat drawer */
|
|
50
|
-
}}>
|
|
51
|
-
<BobStandalone
|
|
52
|
-
partner="CARFIX"
|
|
53
|
-
sessionToken={sessionToken}
|
|
54
|
-
bottomOffset={0} /* Container already handles spacing */
|
|
55
|
-
zIndexBase={100} /* Above header z-40 and nav z-30 */
|
|
56
|
-
onAddToCart={async (item) => {
|
|
57
|
-
// See Section 6 for full item shape including bundle metadata
|
|
58
|
-
await carfixCart.add(item);
|
|
59
|
-
}}
|
|
60
|
-
onNavigate={(url) => router.push(url)}
|
|
61
|
-
onCheckout={(checkoutUrl) => window.location.href = checkoutUrl}
|
|
62
|
-
onError={(error) => console.error('[Bob Error]', error)}
|
|
63
|
-
/>
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
> **Auto-configuration:** The `partner="CARFIX"` prop loads all API URLs, credentials, layout defaults, and feature flags from the `bob_partners` database table. No manual config needed.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 4. CARFIX API Configuration (Already in Database)
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"baseUrl": "https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1",
|
|
78
|
-
"apiKey": "eyJhbGciOiJIUzI1NiIs...wKoJ51_VPro_BrJz-A-NRpSmUW0XBP-7TJJcrhvYwxE",
|
|
79
|
-
"partnerCode": "CARFIX"
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Available Endpoints
|
|
84
|
-
|
|
85
|
-
| Endpoint | Purpose |
|
|
86
|
-
|---|---|
|
|
87
|
-
| `partner-api` | Session creation, cart, user context, orders |
|
|
88
|
-
| `calculate-service-bundles` | Service packs with `preparedTiers[]` (incl. bundle discounts) |
|
|
89
|
-
| `retrieve-vehicle-info` | NZ rego lookup |
|
|
90
|
-
| `retrieve-parts` | Vehicle parts by category |
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## 5. Layout Constraints
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
┌──────────────────────────────┐
|
|
98
|
-
│ CARFIX Header (72px, z-40) │
|
|
99
|
-
├──────────────────────────────┤
|
|
100
|
-
│ │
|
|
101
|
-
│ Bob Container │
|
|
102
|
-
│ height: calc(100dvh - 144px │
|
|
103
|
-
│ - safe-area-inset) │
|
|
104
|
-
│ position: relative │
|
|
105
|
-
│ NO overflow: hidden! │
|
|
106
|
-
│ │
|
|
107
|
-
├──────────────────────────────┤
|
|
108
|
-
│ Bottom Nav (72px, z-30) │
|
|
109
|
-
└──────────────────────────────┘
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
**Bob's internal z-index stack (relative to `zIndexBase={100}`):**
|
|
113
|
-
|
|
114
|
-
| Layer | z-index |
|
|
115
|
-
|---|---|
|
|
116
|
-
| Chat PTT Button | 145 |
|
|
117
|
-
| Chat Drawer | 130 |
|
|
118
|
-
| Counter Overlay | 70 |
|
|
119
|
-
| Bob Character | 60 |
|
|
120
|
-
| Product Shelf | 55 |
|
|
121
|
-
| Backdrop | 10 |
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## 6. Callback Signatures
|
|
126
|
-
|
|
127
|
-
### onAddToCart
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
onAddToCart: (item: {
|
|
131
|
-
product_id: string;
|
|
132
|
-
product_name: string;
|
|
133
|
-
quantity: number;
|
|
134
|
-
unit_price: number; // Final price (discount already applied for bundle items)
|
|
135
|
-
sku?: string;
|
|
136
|
-
brand?: string;
|
|
137
|
-
image_url?: string;
|
|
138
|
-
vehicle_id?: string;
|
|
139
|
-
// Bundle metadata (present when item is part of a service package)
|
|
140
|
-
is_bundle_item?: boolean;
|
|
141
|
-
bundle_discount_percentage?: number;
|
|
142
|
-
service_package_name?: string;
|
|
143
|
-
service_package_id?: string;
|
|
144
|
-
quality_tier?: string; // "Economy" | "Standard" | "Premium" | "Performance"
|
|
145
|
-
}) => Promise<void> | void;
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### onNavigate
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
onNavigate: (url: string) => void;
|
|
152
|
-
// Example urls: "/product/SKU123", "/checkout"
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### onCheckout
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
onCheckout: (checkoutUrl: string) => void;
|
|
159
|
-
// checkoutUrl is a full Stripe payment URL
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### onError
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
onError: (error: Error) => void;
|
|
166
|
-
// Bob shows toast by default — this is for host-side logging
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## 7. Bundle Discount Fields (NEW)
|
|
172
|
-
|
|
173
|
-
The `calculate-service-bundles` API returns these fields per `PreparedTier`:
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
interface PreparedTier {
|
|
177
|
-
tierName: string; // "Economy" | "Standard" | "Premium" | "Performance"
|
|
178
|
-
displayName: string;
|
|
179
|
-
description: string;
|
|
180
|
-
isRecommended: boolean; // true = CARFIX Value tier
|
|
181
|
-
isHidden: boolean; // true = filter out (duplicate price)
|
|
182
|
-
|
|
183
|
-
// Pricing (pre-calculated by API — never recompute)
|
|
184
|
-
totalPrice: number; // Discounted bundle price
|
|
185
|
-
originalTotalPrice?: number; // Full price before discount
|
|
186
|
-
savingsAmount?: number; // Dollar savings (originalTotalPrice - totalPrice)
|
|
187
|
-
bundleDiscountPercentage?: number; // Discount % applied (0-50)
|
|
188
|
-
|
|
189
|
-
productCount: number;
|
|
190
|
-
dominantBrand: string | null;
|
|
191
|
-
brands: PreparedTierBrand[];
|
|
192
|
-
products: PreparedTierProduct[];
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
interface PreparedTierProduct {
|
|
196
|
-
partslotId: number;
|
|
197
|
-
partslotName: string; // "BRAKE PADS FRONT"
|
|
198
|
-
sku: string;
|
|
199
|
-
name: string;
|
|
200
|
-
brand: string;
|
|
201
|
-
brandFullName: string;
|
|
202
|
-
brandImageUrl: string; // Full URL — use directly in <img>
|
|
203
|
-
productImageUrl: string; // Full URL — use directly in <img>
|
|
204
|
-
price: number; // Legacy unit price
|
|
205
|
-
unitPrice: number; // Per-unit price
|
|
206
|
-
displayPrice: number; // Total (unitPrice × perCarQty) — USE THIS
|
|
207
|
-
isRotor: boolean; // Show "[Pair]" badge
|
|
208
|
-
isMultiQty: boolean; // Show quantity breakdown (e.g. spark plugs)
|
|
209
|
-
perCarQty: number; // Quantity needed
|
|
210
|
-
partNumber: string | null;
|
|
211
|
-
webDescription: string | null;
|
|
212
|
-
viscosity: string | null;
|
|
213
|
-
volume: number | null;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
interface PreparedTierBrand {
|
|
217
|
-
name: string;
|
|
218
|
-
fullName: string;
|
|
219
|
-
imageUrl: string; // Full URL
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Rendering Rules
|
|
224
|
-
|
|
225
|
-
1. **Filter hidden tiers:** `preparedTiers.filter(t => !t.isHidden)`
|
|
226
|
-
2. **When `savingsAmount > 0`:** Show ~~$originalTotalPrice~~ → **$totalPrice** + "SAVE $XX — X% Bundle Deal"
|
|
227
|
-
3. **When `savingsAmount === 0`:** Show `totalPrice` normally, no discount UI
|
|
228
|
-
4. **Use `displayPrice`** for individual products (already includes quantity)
|
|
229
|
-
5. **Never calculate prices client-side** — all values arrive pre-calculated
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## 8. Session Handoff (Pre-authenticated Users)
|
|
234
|
-
|
|
235
|
-
To pass vehicle/customer context from CARFIX to Bob:
|
|
236
|
-
|
|
237
|
-
```
|
|
238
|
-
1. CARFIX calls partner-api with action: "create_session"
|
|
239
|
-
→ Body: { vehicle_id: 42899 } ← MUST be a NUMBER
|
|
240
|
-
→ Returns: { session_token: "abc123..." }
|
|
241
|
-
|
|
242
|
-
2. Redirect to Bob page: /ask-bob?session=abc123...
|
|
243
|
-
|
|
244
|
-
3. BobStandalone reads sessionToken from URL
|
|
245
|
-
→ Calls session-handoff edge function
|
|
246
|
-
→ Injects vehicle + customer context into chat
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
> **Critical:** `vehicle_id` must be numeric throughout the pipeline. String values cause silent API failures.
|
|
250
|
-
|
|
251
|
-
---
|
|
252
|
-
|
|
253
|
-
## 9. Design Tokens
|
|
254
|
-
|
|
255
|
-
The full design token file is exported from the package:
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
import {
|
|
259
|
-
CARFIX_COLORS,
|
|
260
|
-
QUALITY_TIER_CONFIG,
|
|
261
|
-
IMAGE_URLS,
|
|
262
|
-
BADGE_CONFIG,
|
|
263
|
-
TYPOGRAPHY,
|
|
264
|
-
isRotorProduct,
|
|
265
|
-
getDisplayPrice,
|
|
266
|
-
formatNZD,
|
|
267
|
-
} from '@gymmymac/bob-widget';
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
### Key Colors
|
|
271
|
-
|
|
272
|
-
| Token | Value | Usage |
|
|
273
|
-
|---|---|---|
|
|
274
|
-
| `primary` | `#0052CC` | Standard tier, CTAs, CARFIX Value |
|
|
275
|
-
| `secondary` | `#38BDF8` | Accents, links |
|
|
276
|
-
| `accent` | `#FF8C00` | Premium tier |
|
|
277
|
-
| `success` | `#22C55E` | "Fits Vehicle" badges, Add to Cart |
|
|
278
|
-
| `destructive` | `#EF4444` | Performance tier |
|
|
279
|
-
| `foreground` | `#0F172A` | Headers, primary text |
|
|
280
|
-
| `mutedForeground` | `#64748B` | Descriptions |
|
|
281
|
-
|
|
282
|
-
### Tier Visual Config
|
|
283
|
-
|
|
284
|
-
| Tier | Color | Badge |
|
|
285
|
-
|---|---|---|
|
|
286
|
-
| Economy | `#475569` on `#F1F5F9` | 💰 |
|
|
287
|
-
| Standard | `#0052CC` on `rgba(0,82,204,0.1)` | ⭐ CARFIX Value |
|
|
288
|
-
| Premium | `#D97706` on `#FEF3C7` | 🏆 |
|
|
289
|
-
| Performance | `#DC2626` on `#FEE2E2` | ⚡ |
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## 10. Exported Types (Full List)
|
|
294
|
-
|
|
295
|
-
```typescript
|
|
296
|
-
// Core widget components
|
|
297
|
-
export { BobStandalone } from '@gymmymac/bob-widget';
|
|
298
|
-
export type { StandaloneWidgetProps } from '@gymmymac/bob-widget';
|
|
299
|
-
|
|
300
|
-
// Types available for CARFIX integration
|
|
301
|
-
export type {
|
|
302
|
-
// Context & Config
|
|
303
|
-
HostContext, HostUserContext, HostVehicleContext, HostCartContext,
|
|
304
|
-
BobConfig, HostApiConfig, BobCallbacks, BobProviderConfig, BobLayoutConfig,
|
|
305
|
-
|
|
306
|
-
// Products & Packages
|
|
307
|
-
Product, CartItem, ServicePackage, PreparedTier, PreparedTierProduct, PreparedTierBrand,
|
|
308
|
-
Partslot, QualityTiers, Part,
|
|
309
|
-
|
|
310
|
-
// Partner
|
|
311
|
-
PartnerConfig, PartnerFeatureFlags, EssentialCallbacks,
|
|
312
|
-
|
|
313
|
-
// Vehicle
|
|
314
|
-
Vehicle,
|
|
315
|
-
|
|
316
|
-
// Messages
|
|
317
|
-
Message, HighlightedProduct,
|
|
318
|
-
|
|
319
|
-
// Analytics
|
|
320
|
-
BobAnalyticsEvent, BobGA4Config,
|
|
321
|
-
} from '@gymmymac/bob-widget';
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
---
|
|
325
|
-
|
|
326
|
-
## 11. Verification Checklist (Post-Install)
|
|
327
|
-
|
|
328
|
-
```
|
|
329
|
-
□ npm install completes without peer dependency warnings
|
|
330
|
-
□ BobStandalone renders loading spinner, then Bob appears
|
|
331
|
-
□ Bob character sits between header and bottom nav
|
|
332
|
-
□ Chat drawer opens above bottom navigation (z-index check)
|
|
333
|
-
□ PTT button is visible and not clipped
|
|
334
|
-
□ Vehicle lookup works (try rego: HZP550)
|
|
335
|
-
□ Service packages appear with tier cards
|
|
336
|
-
□ Bundle discount shows Was/Now pricing where applicable
|
|
337
|
-
□ "Add to Cart" callback fires with correct item shape
|
|
338
|
-
□ Session handoff works (pass ?session=TOKEN)
|
|
339
|
-
□ No console errors related to Bob
|
|
340
|
-
□ Mobile: safe-area-inset respected on notched devices
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
---
|
|
344
|
-
|
|
345
|
-
## 12. Test Baseline
|
|
346
|
-
|
|
347
|
-
Bob ships with **36 unit tests** and **8+ E2E scenarios** covering:
|
|
348
|
-
|
|
349
|
-
- Callback mapping and stability
|
|
350
|
-
- Tier validation and empty states
|
|
351
|
-
- Rear Brake Disc/Drum filter logic
|
|
352
|
-
- Bundle discount display and cart pricing
|
|
353
|
-
- Vehicle lookup flow
|
|
354
|
-
- Service package rendering
|
|
355
|
-
- Chat drawer positioning
|
|
356
|
-
|
|
357
|
-
Run locally: `cd packages/bob-widget && npx vitest run`
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## Support
|
|
362
|
-
|
|
363
|
-
For integration issues, the Bob team needs:
|
|
364
|
-
1. Browser console output (filter for `[Bob`)
|
|
365
|
-
2. Network tab showing failed API calls
|
|
366
|
-
3. Screenshot of layout issue
|
|
367
|
-
4. Device/browser/viewport info
|