@gymmymac/bob-widget 3.1.10 β 3.1.20
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 +32 -2
- package/CHANGELOG.md +108 -0
- package/README.md +436 -38
- package/bin/bob-widget.mjs +263 -14
- package/dist/__tests__/Bob.callbacks.test.d.ts +10 -0
- package/dist/__tests__/bundleDiscount.test.d.ts +7 -0
- package/dist/__tests__/rearBrakeFilter.test.d.ts +7 -0
- package/dist/components/ProductTile.d.ts +4 -5
- package/dist/components/mobile/ContainedChatDrawer.d.ts +2 -0
- package/dist/components/mobile/ContainedMobileBobLayout.d.ts +5 -0
- package/dist/components/mobile/MobileBobLayout.d.ts +5 -0
- package/dist/components/mobile/MobileBobLayoutCore.d.ts +18 -0
- package/dist/components/mobile/MobileChatDrawer.d.ts +2 -0
- package/dist/components/mobile/MobileProductColumn.d.ts +20 -0
- package/dist/hooks/useBobChat.d.ts +4 -1
- package/dist/index.js +32 -32
- package/dist/index.mjs +5114 -4895
- package/dist/styles/carfix-tokens.d.ts +2 -1
- package/dist/types/product.d.ts +9 -0
- package/dist/utils/rearBrakeFilter.d.ts +15 -0
- package/install/carfix/00-README-PREINSTALL.md +27 -5
- package/install/carfix/05-runtime-verification-checklist.md +3 -3
- package/install/carfix/CARFIX-INSTALLATION-BRIEF.md +367 -0
- package/package.json +1 -1
package/BOB-DOCUMENTATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bob Widget - Complete Documentation
|
|
2
2
|
|
|
3
|
-
> **Version:** 3.1.
|
|
3
|
+
> **Version:** 3.1.19 | **Last Updated:** February 2026
|
|
4
4
|
|
|
5
5
|
AI-powered automotive parts assistant widget for seamless integration into partner websites.
|
|
6
6
|
|
|
@@ -26,11 +26,12 @@ AI-powered automotive parts assistant widget for seamless integration into partn
|
|
|
26
26
|
|
|
27
27
|
Bob is a friendly Kiwi auto parts expert that helps customers find the right parts for their vehicles through natural conversation. The widget is designed as a **"black box"** that auto-configures from the databaseβpartners only need to provide a partner code.
|
|
28
28
|
|
|
29
|
-
### Key Features (v3.1.
|
|
29
|
+
### Key Features (v3.1.19)
|
|
30
30
|
|
|
31
31
|
| Feature | Description |
|
|
32
32
|
|---------|-------------|
|
|
33
33
|
| **CLI Installer** | 3-stage installation via `npx @gymmymac/bob-widget carfix stage-a\|b\|c` |
|
|
34
|
+
| **`--with-layout` Flag** | Stage B can generate CARFIX Header (72px) and BottomNav (72px) components |
|
|
34
35
|
| **BobStandalone** | Auto-configures from database - 4 lines to integrate |
|
|
35
36
|
| **No Hardcoded Blur** | Background uses CSS variable `--bob-blur-intensity` (default: 0) |
|
|
36
37
|
| **Partner Config System** | All settings stored in `bob_partners` table |
|
|
@@ -733,6 +734,35 @@ Before proceeding to Stage B, confirm:
|
|
|
733
734
|
|
|
734
735
|
Create the blank page that will host Bob. **Do NOT import Bob yet** - that happens in Stage C.
|
|
735
736
|
|
|
737
|
+
#### CARFIX Layout Components (Required)
|
|
738
|
+
|
|
739
|
+
Before creating the Bob container, ensure your CARFIX application has:
|
|
740
|
+
|
|
741
|
+
1. **Fixed Header (72px)** - Fixed to top of viewport
|
|
742
|
+
2. **Fixed Bottom Navigation (72px)** - Fixed to bottom of viewport
|
|
743
|
+
|
|
744
|
+
**If these elements do NOT exist**, you must create them first. The 144px height offset
|
|
745
|
+
in the container formula ASSUMES both elements are present.
|
|
746
|
+
|
|
747
|
+
##### Option A: Use Existing Layout
|
|
748
|
+
|
|
749
|
+
If your CARFIX app already has a header and bottom nav, confirm their heights:
|
|
750
|
+
- Header: Must be exactly 72px
|
|
751
|
+
- Bottom Nav: Must be exactly 72px (plus safe-area-inset-bottom on mobile)
|
|
752
|
+
|
|
753
|
+
##### Option B: Generate Layout Components
|
|
754
|
+
|
|
755
|
+
Run Stage B with the `--with-layout` flag to generate placeholder components:
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
npx @gymmymac/bob-widget carfix stage-b --target next-pages --with-layout
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
This generates:
|
|
762
|
+
- `components/CarfixHeader.tsx` (72px header)
|
|
763
|
+
- `components/CarfixBottomNav.tsx` (72px bottom nav)
|
|
764
|
+
- `pages/ask-bob.tsx` (complete page with layout)
|
|
765
|
+
|
|
736
766
|
#### Requirements
|
|
737
767
|
|
|
738
768
|
1. Page must use the standard CARFIX layout (Header + Bottom Navigation)
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,114 @@ All notable changes to the `@gymmymac/bob-widget` package will be documented in
|
|
|
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
|
+
## [3.1.20] - 2026-02-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- π¦ **CARFIX Installation Brief**: README.md now serves as the comprehensive installation document with full container preparation requirements, anti-patterns table, pre-mount checklist, and layout diagram
|
|
12
|
+
- π§ͺ **Quality Baseline Tests**: 36 unit tests locked in across rear brake filter, bundle discount pricing, and callback stability
|
|
13
|
+
- π° **Bundle Discount Display**: Was/Now pricing with savings badges for service package tiers when `savingsAmount > 0`
|
|
14
|
+
- π **Bundle Cart Metadata**: Cart items from service packages now include `is_bundle_item`, `bundle_discount_percentage`, `service_package_name`, and `quality_tier`
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- π **README Overhaul**: Full installation brief is now front-and-center β visible on npm, GitHub, and in `node_modules`
|
|
18
|
+
- π **Container Anti-Patterns**: Documented all prohibited CSS properties (`overflow: hidden`, `transform`, etc.) that break Bob's layering
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [3.1.19] - 2026-02-04
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- π **Vehicle Variant Deduplication**: Smart filtering removes duplicate vehicle variants based on parts-relevant specs (fuel type, engine capacity, power output) rather than superficial trim differences
|
|
26
|
+
- π£οΈ **REGO Terminology Alignment**: Bob now treats "registration", "rego", "plate", and "number plate" identically
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- π’ **Speech Count Alignment**: Bob's spoken variant count now matches the deduplicated UI cards shown on screen
|
|
30
|
+
- π΄ **Variant Card Display**: Cards now show specs-first format without characterization text
|
|
31
|
+
|
|
32
|
+
### Documentation
|
|
33
|
+
- π **bottomOffset Clarification**: `bottomOffset` prop only applies to fixed-position variants. Contained/embedded variants position relative to their container (which should already be sized to fit between header/footer).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## [3.1.18] - 2026-01-28
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- π£οΈ **Language Consistency**: Replaced all "CFX" references with "CARFIX" in:
|
|
41
|
+
- Database prompts (sales_flow)
|
|
42
|
+
- Edge function tool descriptions
|
|
43
|
+
- Service package descriptions in carfix-tokens.ts
|
|
44
|
+
- π¬ **Bob's Recommendations**: Bob now verbally recommends "CARFIX Value" tier (was "Standard")
|
|
45
|
+
- π¨ **Button Styling**:
|
|
46
|
+
- CARFIX Value tier: Solid green (#22C55E) button with white text
|
|
47
|
+
- Other tiers: Light background with green text
|
|
48
|
+
- Removed cart icons from all Add buttons
|
|
49
|
+
- π·οΈ **Badge Update**: "RECOMMENDED" pill renamed to "CARFIX VALUE"
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## [3.1.17] - 2026-01-28
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- π·οΈ **Shelf Header**: Replaced "Bob's Shelf" with vehicle make/model (e.g., "Toyota RAV4")
|
|
57
|
+
- ποΈ **Service Packs Label**: Removed "CFX SERVICE PACKS" row to reclaim vertical space
|
|
58
|
+
- π¨ **Recommended Badge**: Changed green "Recommended" pill to blue "Carfix Value"
|
|
59
|
+
- π **Add Buttons**: Removed cart icons, centered button text
|
|
60
|
+
- π **Chevron Handle**: Larger handle button (32px) positioned higher (-24px) to prevent clipping
|
|
61
|
+
- π **Chat Height**: Increased collapsed drawer from 90px to 110px for PTT button visibility
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## [3.1.16] - 2026-01-28
|
|
66
|
+
|
|
67
|
+
## [3.1.15] - 2026-01-28
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
- π£οΈ **State Terminology**: Default animation states updated to match V2 Bob:
|
|
71
|
+
- "talking" (was "talk")
|
|
72
|
+
- "researching" (was "research")
|
|
73
|
+
- "listening" (was "talk_pause")
|
|
74
|
+
- "idle" for complete state (was "complete")
|
|
75
|
+
- π **Chat Drawer Position**: Chat drawer now positioned at `bottom: 0` to sit below the counter overlay visually
|
|
76
|
+
- πΌοΈ **Counter Stretching**: Counter overlay now uses `object-fit: fill` to stretch to configured height
|
|
77
|
+
- π **Chat Height**: Increased collapsed chat drawer height from 70px to 90px
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## [3.1.14] - 2026-01-28
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
- π **ContainedChatDrawer Positioning**: Removed incorrect `bottomOffset` addition - container already accounts for host UI
|
|
85
|
+
- π¨ **Chat Drawer Height**: Chat drawer now correctly positions at `counterHeightPercent%` from container bottom
|
|
86
|
+
- π **Counter Overlay**: Single counter display verified (backdrop + overlay are separate layers)
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## [3.1.13] - 2026-01-28
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
- π **Chat Drawer Positioning**: Chat drawer now positions above counter overlay using `counterHeightPercent`
|
|
94
|
+
- π¨ **Visual Alignment**: Chat input and PTT button no longer overlap with counter graphic
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## [3.1.12] - 2026-01-28
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
- π¨ **Chat Drawer Z-Index**: Raised chat drawer z-index above counter overlay (z-80) to ensure visibility
|
|
102
|
+
- π€ **PTT Button Layering**: Elevated PTT button and handle button z-index for proper layer hierarchy
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## [3.1.11] - 2026-01-28
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
- π **Stage B `--with-layout` Flag**: New CLI option generates CARFIX Header (72px) and Bottom Navigation (72px) components
|
|
110
|
+
- π **CARFIX Layout Components Section**: Documentation now explicitly provides Header and BottomNav code templates
|
|
111
|
+
- π§ͺ **Demo Route `/ask-bob`**: Added test route to demo repo with mock CARFIX layout for accurate local testing
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
- π **Stage B Instructions**: Now include explicit layout component requirements instead of assuming they exist
|
|
115
|
+
|
|
8
116
|
## [3.1.10] - 2026-01-28
|
|
9
117
|
|
|
10
118
|
### Added
|
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @gymmymac/bob-widget
|
|
2
2
|
|
|
3
|
-
AI-powered automotive parts assistant widget for
|
|
3
|
+
AI-powered automotive parts assistant widget for partner websites.
|
|
4
4
|
|
|
5
|
-
**Current Version:** 3.1.
|
|
5
|
+
**Current Version:** 3.1.20 | **36 unit tests** | **8+ E2E scenarios** | Production-ready
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## π¨ STOP
|
|
9
|
+
## π¨ STOP β RUN THE INSTALLER FIRST
|
|
10
10
|
|
|
11
|
-
Bob v3.1.
|
|
11
|
+
Bob v3.1.19 includes an **executable 3-stage installer**. Do NOT skip this step.
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
# Stage A: Forensic Scan & Purge (removes old Bob code)
|
|
@@ -21,62 +21,460 @@ npx @gymmymac/bob-widget carfix stage-b --target next-pages --output pages/ask-b
|
|
|
21
21
|
npx @gymmymac/bob-widget carfix stage-c --partner CARFIX
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
---
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|----------|-------------|
|
|
28
|
-
| **[BOB-DOCUMENTATION.md](./BOB-DOCUMENTATION.md)** | **Complete integration guide** - Contains CARFIX-specific installation steps, container height calculations, and verification tests. **START HERE.** |
|
|
29
|
-
| **[CHANGELOG.md](./CHANGELOG.md)** | Version history and release notes |
|
|
30
|
-
| **[install/carfix/](./install/carfix/)** | Installer scripts and templates |
|
|
26
|
+
## 1. Peer Dependencies
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^18.0.0",
|
|
32
|
+
"react-dom": "^18.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
3. **HTTPS Required**: Push-to-Talk (PTT) requires HTTPS - will be disabled on HTTP connections
|
|
37
|
-
4. **No Background Blur**: v3.1.10 removes hardcoded blur - background is crisp by default
|
|
37
|
+
> `@supabase/supabase-js` and `@tanstack/react-query` are bundled β no action needed.
|
|
38
|
+
> If CARFIX already uses `@tanstack/react-query`, ensure v5+ compatibility.
|
|
38
39
|
|
|
39
40
|
---
|
|
40
41
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
After completing the 3-stage installation:
|
|
42
|
+
## 2. Minimal Integration (4 Lines)
|
|
44
43
|
|
|
45
44
|
```tsx
|
|
46
45
|
import { BobStandalone } from '@gymmymac/bob-widget';
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
sessionToken=
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
function AskBobPage() {
|
|
48
|
+
const router = useRouter();
|
|
49
|
+
const sessionToken = router.query.session as string;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div style={{
|
|
53
|
+
height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
|
|
54
|
+
position: 'relative',
|
|
55
|
+
/* DO NOT use overflow: hidden β clips PTT button and chat drawer */
|
|
56
|
+
}}>
|
|
57
|
+
<BobStandalone
|
|
58
|
+
partner="CARFIX"
|
|
59
|
+
sessionToken={sessionToken}
|
|
60
|
+
bottomOffset={0}
|
|
61
|
+
zIndexBase={100}
|
|
62
|
+
onAddToCart={async (item) => await carfixCart.add(item)}
|
|
63
|
+
onNavigate={(url) => router.push(url)}
|
|
64
|
+
onCheckout={(checkoutUrl) => window.location.href = checkoutUrl}
|
|
65
|
+
onError={(error) => console.error('[Bob Error]', error)}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> **Auto-configuration:** `partner="CARFIX"` loads all API URLs, credentials, layout defaults, and feature flags from the `bob_partners` database table. No manual config needed.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 3. CARFIX API Configuration (Already in Database)
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"baseUrl": "https://flpzjbasdsfwoeruyxgp.supabase.co/functions/v1",
|
|
81
|
+
"apiKey": "(anon key β auto-loaded)",
|
|
82
|
+
"partnerCode": "CARFIX"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Available Endpoints
|
|
87
|
+
|
|
88
|
+
| Endpoint | Purpose |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `partner-api` | Session creation, cart, user context, orders |
|
|
91
|
+
| `calculate-service-bundles` | Service packs with `preparedTiers[]` (incl. bundle discounts) |
|
|
92
|
+
| `retrieve-vehicle-info` | NZ rego lookup |
|
|
93
|
+
| `retrieve-parts` | Vehicle parts by category |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 4. Host Container Preparation (MANDATORY)
|
|
98
|
+
|
|
99
|
+
> β οΈ **Bob will not render correctly if the host container is misconfigured.** Complete ALL items below before mounting `<BobStandalone>`.
|
|
100
|
+
|
|
101
|
+
### 4.1 Container Requirements
|
|
102
|
+
|
|
103
|
+
The CARFIX page that hosts Bob **must** provide a container element with these exact properties:
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
/* The Bob container β EVERY property is required */
|
|
107
|
+
.bob-container {
|
|
108
|
+
height: calc(100dvh - 144px - env(safe-area-inset-bottom, 0px));
|
|
109
|
+
position: relative;
|
|
110
|
+
width: 100%;
|
|
111
|
+
|
|
112
|
+
/* β PROHIBITED β these WILL break Bob */
|
|
113
|
+
/* overflow: hidden; β Clips PTT button, chat drawer, and expand handle */
|
|
114
|
+
/* overflow: clip; β Same issue on WebKit */
|
|
115
|
+
/* overflow: auto; β Creates nested scroll context, breaks shelf scrolling */
|
|
116
|
+
/* overflow: scroll; β Same as above */
|
|
117
|
+
/* transform: ...; β Creates new stacking context, breaks z-index layering */
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
// β
Correct JSX
|
|
123
|
+
<div style={{
|
|
124
|
+
height: 'calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))',
|
|
125
|
+
position: 'relative',
|
|
126
|
+
width: '100%',
|
|
127
|
+
}}>
|
|
128
|
+
<BobStandalone partner="CARFIX" ... />
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
// β WRONG β overflow hidden clips Bob's interactive elements
|
|
132
|
+
<div style={{ height: '100%', overflow: 'hidden' }}>
|
|
133
|
+
<BobStandalone partner="CARFIX" ... />
|
|
134
|
+
</div>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 4.2 Height Calculation Breakdown
|
|
138
|
+
|
|
139
|
+
| Component | Height | Notes |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| CARFIX Header | 72px | `position: fixed; top: 0; z-index: 40` |
|
|
142
|
+
| CARFIX Bottom Nav | 72px | `position: fixed; bottom: 0; z-index: 30` |
|
|
143
|
+
| **Total chrome** | **144px** | Subtracted from viewport |
|
|
144
|
+
| Safe area inset | Variable | For notched devices (iPhone, etc.) |
|
|
145
|
+
| **Bob container** | `100dvh - 144px - safe-area` | Everything between header and nav |
|
|
146
|
+
|
|
147
|
+
### 4.3 Header & Bottom Nav Requirements
|
|
148
|
+
|
|
149
|
+
Bob's UI layers (chat drawer at z-130, PTT at z-145) must sit **above** CARFIX navigation:
|
|
150
|
+
|
|
151
|
+
```css
|
|
152
|
+
/* CARFIX Header */
|
|
153
|
+
.carfix-header {
|
|
154
|
+
position: fixed;
|
|
155
|
+
top: 0;
|
|
156
|
+
left: 0;
|
|
157
|
+
right: 0;
|
|
158
|
+
height: 72px;
|
|
159
|
+
z-index: 40; /* Bob uses zIndexBase=100, so Bob layers above this */
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* CARFIX Bottom Nav */
|
|
163
|
+
.carfix-bottom-nav {
|
|
164
|
+
position: fixed;
|
|
165
|
+
bottom: 0;
|
|
166
|
+
left: 0;
|
|
167
|
+
right: 0;
|
|
168
|
+
height: 72px;
|
|
169
|
+
z-index: 30; /* Must be BELOW Bob's z-base of 100 */
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
> **If your header or nav use `z-index: 50` or higher**, increase Bob's `zIndexBase` prop accordingly (e.g., `zIndexBase={150}`).
|
|
174
|
+
|
|
175
|
+
### 4.4 Container Anti-Patterns (WILL CAUSE BUGS)
|
|
176
|
+
|
|
177
|
+
| β Don't Do This | Why It Breaks |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `overflow: hidden` on container | Clips PTT button, chat drawer, and expand handle |
|
|
180
|
+
| `overflow: auto/scroll` on container | Creates nested scroll context β product shelf scroll breaks |
|
|
181
|
+
| `transform` on container or ancestors | Creates new stacking context β z-index layering fails |
|
|
182
|
+
| `isolation: isolate` on container | Same stacking context issue (Bob manages its own isolation) |
|
|
183
|
+
| Container height as `%` without parent height | Bob collapses to 0px |
|
|
184
|
+
| Missing `position: relative` | Absolutely-positioned Bob layers escape the container |
|
|
185
|
+
| Wrapping Bob in a scrollable parent | Bob has its own scroll management β nesting causes conflicts |
|
|
186
|
+
|
|
187
|
+
### 4.5 Pre-Mount Checklist
|
|
188
|
+
|
|
189
|
+
Before writing any integration code, verify:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
β‘ Header is position: fixed, 72px tall, z-index β€ 49
|
|
193
|
+
β‘ Bottom nav is position: fixed, 72px tall, z-index β€ 49
|
|
194
|
+
β‘ Bob container uses calc(100dvh - 144px - env(safe-area-inset-bottom, 0px))
|
|
195
|
+
β‘ Bob container has position: relative
|
|
196
|
+
β‘ Bob container has NO overflow property set
|
|
197
|
+
β‘ Bob container has NO transform property set
|
|
198
|
+
β‘ No ancestor element between <body> and Bob container has overflow: hidden
|
|
199
|
+
β‘ No ancestor element has a transform that creates a stacking context
|
|
200
|
+
β‘ Container renders at correct height (inspect element in DevTools)
|
|
201
|
+
β‘ HTTPS is enabled (required for Push-to-Talk microphone access)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### 4.6 Layout Diagram
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
ββββββββββββββββββββββββββββββββ
|
|
210
|
+
β CARFIX Header (72px, z-40) β β position: fixed; top: 0
|
|
211
|
+
ββββββββββββββββββββββββββββββββ€
|
|
212
|
+
β β
|
|
213
|
+
β Bob Container β β position: relative
|
|
214
|
+
β height: calc(100dvh - 144px β NO overflow property
|
|
215
|
+
β - safe-area-inset) β NO transform property
|
|
216
|
+
β β
|
|
217
|
+
β ββ Bob Internal Layers ββββ β
|
|
218
|
+
β β PTT Button z-145 β β
|
|
219
|
+
β β Chat Drawer z-130 β β
|
|
220
|
+
β β Counter Overlay z-70 β β
|
|
221
|
+
β β Bob Character z-60 β β
|
|
222
|
+
β β Product Shelf z-55 β β
|
|
223
|
+
β β Backdrop z-10 β β
|
|
224
|
+
β βββββββββββββββββββββββββββ β
|
|
225
|
+
β β
|
|
226
|
+
ββββββββββββββββββββββββββββββββ€
|
|
227
|
+
β Bottom Nav (72px, z-30) β β position: fixed; bottom: 0
|
|
228
|
+
ββββββββββββββββββββββββββββββββ
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Bob's internal z-index stack (relative to `zIndexBase={100}`):**
|
|
232
|
+
|
|
233
|
+
| Layer | z-index |
|
|
234
|
+
|---|---|
|
|
235
|
+
| Chat PTT Button | 145 |
|
|
236
|
+
| Chat Drawer | 130 |
|
|
237
|
+
| Counter Overlay | 70 |
|
|
238
|
+
| Bob Character | 60 |
|
|
239
|
+
| Product Shelf | 55 |
|
|
240
|
+
| Backdrop | 10 |
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 5. Callback Signatures
|
|
245
|
+
|
|
246
|
+
### onAddToCart
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
onAddToCart: (item: {
|
|
250
|
+
product_id: string;
|
|
251
|
+
product_name: string;
|
|
252
|
+
quantity: number;
|
|
253
|
+
unit_price: number; // Final price (discount already applied for bundle items)
|
|
254
|
+
sku?: string;
|
|
255
|
+
brand?: string;
|
|
256
|
+
image_url?: string;
|
|
257
|
+
vehicle_id?: string;
|
|
258
|
+
// Bundle metadata (present when item is part of a service package)
|
|
259
|
+
is_bundle_item?: boolean;
|
|
260
|
+
bundle_discount_percentage?: number;
|
|
261
|
+
service_package_name?: string;
|
|
262
|
+
service_package_id?: string;
|
|
263
|
+
quality_tier?: string; // "Economy" | "Standard" | "Premium" | "Performance"
|
|
264
|
+
}) => Promise<void> | void;
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### onNavigate
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
onNavigate: (url: string) => void;
|
|
271
|
+
// Example urls: "/product/SKU123", "/checkout"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### onCheckout
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
onCheckout: (checkoutUrl: string) => void;
|
|
278
|
+
// checkoutUrl is a full Stripe payment URL
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### onError
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
onError: (error: Error) => void;
|
|
285
|
+
// Bob shows toast by default β this is for host-side logging
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 6. Bundle Discount Fields (NEW)
|
|
291
|
+
|
|
292
|
+
The `calculate-service-bundles` API returns these fields per `PreparedTier`:
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
interface PreparedTier {
|
|
296
|
+
tierName: string; // "Economy" | "Standard" | "Premium" | "Performance"
|
|
297
|
+
displayName: string;
|
|
298
|
+
description: string;
|
|
299
|
+
isRecommended: boolean; // true = CARFIX Value tier
|
|
300
|
+
isHidden: boolean; // true = filter out (duplicate price)
|
|
301
|
+
|
|
302
|
+
// Pricing (pre-calculated by API β never recompute)
|
|
303
|
+
totalPrice: number; // Discounted bundle price
|
|
304
|
+
originalTotalPrice?: number; // Full price before discount
|
|
305
|
+
savingsAmount?: number; // Dollar savings
|
|
306
|
+
bundleDiscountPercentage?: number; // Discount % (0β50)
|
|
307
|
+
|
|
308
|
+
productCount: number;
|
|
309
|
+
dominantBrand: string | null;
|
|
310
|
+
brands: PreparedTierBrand[];
|
|
311
|
+
products: PreparedTierProduct[];
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
interface PreparedTierProduct {
|
|
315
|
+
partslotId: number;
|
|
316
|
+
partslotName: string; // "BRAKE PADS FRONT"
|
|
317
|
+
sku: string;
|
|
318
|
+
name: string;
|
|
319
|
+
brand: string;
|
|
320
|
+
brandFullName: string;
|
|
321
|
+
brandImageUrl: string; // Full URL β use directly in <img>
|
|
322
|
+
productImageUrl: string; // Full URL β use directly in <img>
|
|
323
|
+
price: number; // Legacy unit price
|
|
324
|
+
unitPrice: number; // Per-unit price
|
|
325
|
+
displayPrice: number; // Total (unitPrice Γ perCarQty) β USE THIS
|
|
326
|
+
isRotor: boolean; // Show "[Pair]" badge
|
|
327
|
+
isMultiQty: boolean; // Show quantity breakdown (e.g. spark plugs)
|
|
328
|
+
perCarQty: number;
|
|
329
|
+
partNumber: string | null;
|
|
330
|
+
webDescription: string | null;
|
|
331
|
+
viscosity: string | null;
|
|
332
|
+
volume: number | null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
interface PreparedTierBrand {
|
|
336
|
+
name: string;
|
|
337
|
+
fullName: string;
|
|
338
|
+
imageUrl: string; // Full URL
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Rendering Rules
|
|
343
|
+
|
|
344
|
+
1. **Filter hidden tiers:** `preparedTiers.filter(t => !t.isHidden)`
|
|
345
|
+
2. **When `savingsAmount > 0`:** Show ~~$originalTotalPrice~~ β **$totalPrice** + "SAVE $XX β X% Bundle Deal"
|
|
346
|
+
3. **When `savingsAmount === 0`:** Show `totalPrice` normally, no discount UI
|
|
347
|
+
4. **Use `displayPrice`** for individual products (already includes quantity)
|
|
348
|
+
5. **Never calculate prices client-side** β all values arrive pre-calculated
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## 7. Session Handoff (Pre-authenticated Users)
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
1. CARFIX calls partner-api: { action: "create_session", vehicle_id: 42899 }
|
|
356
|
+
β vehicle_id MUST be a NUMBER (not string)
|
|
357
|
+
β Returns: { session_token: "abc123..." }
|
|
358
|
+
|
|
359
|
+
2. Redirect to: /ask-bob?session=abc123...
|
|
360
|
+
|
|
361
|
+
3. BobStandalone reads sessionToken β resolves vehicle + customer context
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
> **Critical:** `vehicle_id` must be numeric throughout the pipeline. String values cause silent API failures.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 8. Design Tokens
|
|
369
|
+
|
|
370
|
+
Exported from the package for use on CARFIX pages that mirror Bob's styling:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import {
|
|
374
|
+
CARFIX_COLORS,
|
|
375
|
+
QUALITY_TIER_CONFIG,
|
|
376
|
+
IMAGE_URLS,
|
|
377
|
+
BADGE_CONFIG,
|
|
378
|
+
TYPOGRAPHY,
|
|
379
|
+
isRotorProduct,
|
|
380
|
+
getDisplayPrice,
|
|
381
|
+
formatNZD,
|
|
382
|
+
} from '@gymmymac/bob-widget';
|
|
55
383
|
```
|
|
56
384
|
|
|
57
|
-
|
|
385
|
+
### Key Colors
|
|
386
|
+
|
|
387
|
+
| Token | Value | Usage |
|
|
388
|
+
|---|---|---|
|
|
389
|
+
| `primary` | `#0052CC` | Standard tier, CTAs, CARFIX Value |
|
|
390
|
+
| `secondary` | `#38BDF8` | Accents, links |
|
|
391
|
+
| `accent` | `#FF8C00` | Premium tier |
|
|
392
|
+
| `success` | `#22C55E` | "Fits Vehicle" badges, Add to Cart |
|
|
393
|
+
| `destructive` | `#EF4444` | Performance tier |
|
|
394
|
+
|
|
395
|
+
### Tier Visual Config
|
|
396
|
+
|
|
397
|
+
| Tier | Color | Background | Badge |
|
|
398
|
+
|---|---|---|---|
|
|
399
|
+
| Economy | `#475569` | `#F1F5F9` | π° |
|
|
400
|
+
| Standard | `#0052CC` | `rgba(0,82,204,0.1)` | β CARFIX Value |
|
|
401
|
+
| Premium | `#D97706` | `#FEF3C7` | π |
|
|
402
|
+
| Performance | `#DC2626` | `#FEE2E2` | β‘ |
|
|
58
403
|
|
|
59
404
|
---
|
|
60
405
|
|
|
61
|
-
##
|
|
406
|
+
## 9. Exported Types (Full List)
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
// Components
|
|
410
|
+
export { BobStandalone } from '@gymmymac/bob-widget';
|
|
411
|
+
export type { StandaloneWidgetProps } from '@gymmymac/bob-widget';
|
|
62
412
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
413
|
+
// Types
|
|
414
|
+
export type {
|
|
415
|
+
HostContext, HostUserContext, HostVehicleContext, HostCartContext,
|
|
416
|
+
BobConfig, HostApiConfig, BobCallbacks, BobProviderConfig, BobLayoutConfig,
|
|
417
|
+
Product, CartItem, ServicePackage, PreparedTier, PreparedTierProduct, PreparedTierBrand,
|
|
418
|
+
Partslot, QualityTiers, Part,
|
|
419
|
+
PartnerConfig, PartnerFeatureFlags, EssentialCallbacks,
|
|
420
|
+
Vehicle, Message, HighlightedProduct,
|
|
421
|
+
BobAnalyticsEvent, BobGA4Config,
|
|
422
|
+
} from '@gymmymac/bob-widget';
|
|
423
|
+
```
|
|
68
424
|
|
|
69
|
-
|
|
425
|
+
---
|
|
70
426
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
427
|
+
## 10. Post-Install Verification Checklist
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
β‘ npm install completes without peer dependency warnings
|
|
431
|
+
β‘ BobStandalone renders loading spinner, then Bob appears
|
|
432
|
+
β‘ Bob character sits between header (72px) and bottom nav (72px)
|
|
433
|
+
β‘ Chat drawer opens above bottom navigation (z-index check)
|
|
434
|
+
β‘ PTT button is visible and not clipped
|
|
435
|
+
β‘ Vehicle lookup works (try rego: HZP550)
|
|
436
|
+
β‘ Service packages appear with tier cards
|
|
437
|
+
β‘ Bundle discount shows Was/Now pricing where applicable
|
|
438
|
+
β‘ "Add to Cart" callback fires with correct item shape
|
|
439
|
+
β‘ Session handoff works (pass ?session=TOKEN)
|
|
440
|
+
β‘ No console errors (filter for [Bob)
|
|
441
|
+
β‘ Mobile: safe-area-inset respected on notched devices
|
|
442
|
+
```
|
|
74
443
|
|
|
75
|
-
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## 11. Test Baseline
|
|
447
|
+
|
|
448
|
+
Bob ships with **36 unit tests** and **8+ E2E scenarios** covering:
|
|
449
|
+
|
|
450
|
+
- Callback mapping and stability
|
|
451
|
+
- Tier validation and empty states
|
|
452
|
+
- Rear Brake Disc/Drum filter logic
|
|
453
|
+
- Bundle discount display and cart pricing
|
|
454
|
+
- Vehicle lookup flow
|
|
455
|
+
- Service package rendering
|
|
456
|
+
|
|
457
|
+
Run locally: `cd packages/bob-widget && npx vitest run`
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## π Additional Documentation
|
|
462
|
+
|
|
463
|
+
| Document | Description |
|
|
464
|
+
|----------|-------------|
|
|
465
|
+
| **[BOB-DOCUMENTATION.md](./BOB-DOCUMENTATION.md)** | Complete integration guide with troubleshooting |
|
|
466
|
+
| **[CHANGELOG.md](./CHANGELOG.md)** | Version history and release notes |
|
|
467
|
+
| **[install/carfix/](./install/carfix/)** | Installer scripts, templates, and verification checklists |
|
|
468
|
+
|
|
469
|
+
---
|
|
76
470
|
|
|
77
471
|
## Support
|
|
78
472
|
|
|
79
|
-
For integration issues,
|
|
473
|
+
For integration issues, the Bob team needs:
|
|
474
|
+
1. Browser console output (filter for `[Bob`)
|
|
475
|
+
2. Network tab showing failed API calls
|
|
476
|
+
3. Screenshot of layout issue
|
|
477
|
+
4. Device / browser / viewport info
|
|
80
478
|
|
|
81
479
|
## License
|
|
82
480
|
|