initial commit
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
# Cross-Origin / Same-Code Debugging (SPQ-specific)
|
||||
|
||||
Diagnose why the **same PocketBase + React app code** behaves differently on two domains.
|
||||
|
||||
## When to Use
|
||||
|
||||
User reports: "Feature X works on shopproquote.graj-media.com but returns 'Invalid input' / 'Error' on grajmedia.duckdns.org." Both serve the same build.
|
||||
|
||||
## Protocol
|
||||
|
||||
### 1. Verify code is identical
|
||||
|
||||
Check nginx config at `/etc/nginx/sites-enabled/`:
|
||||
|
||||
```bash
|
||||
cat /etc/nginx/sites-enabled/shopproquote
|
||||
```
|
||||
|
||||
Look for:
|
||||
- `root` directive — same path for both `server_name` entries?
|
||||
- `server_name` — both domains listed in the same `server` block?
|
||||
|
||||
In SPQ's deployment, nginx serves all three domains (`grajmedia.duckdns.org`, `graj-media.com`, `shopproquote.graj-media.com`) from a single `root` at `/mnt/seagate8tb/Websites/ShopProQuote.backup-20260626-2058/spq-v2/dist`.
|
||||
|
||||
### 2. Check backend proxy
|
||||
|
||||
In the same nginx config, check all `location /pb/` blocks:
|
||||
|
||||
```
|
||||
proxy_pass http://127.0.0.1:8091/;
|
||||
```
|
||||
|
||||
Both domains proxy to the same PocketBase instance. No difference possible.
|
||||
|
||||
### 3. Conclusion
|
||||
|
||||
If code AND backend are identical, the difference is **client-side state**:
|
||||
|
||||
- **localStorage** — per-origin; the Zustand `spq-quote` store is persisted here
|
||||
- Service worker cache (less common)
|
||||
- Cookies
|
||||
|
||||
### 4. Find the failing data path
|
||||
|
||||
In SPQ's Quote Generator, both **Save** (`handleSave` in `QuoteSummary.tsx`) and **Share** (`handleShare` → `ensureShareToken`) do:
|
||||
|
||||
```typescript
|
||||
const parsed = quoteWriteSchema.safeParse(data);
|
||||
if (!parsed.success) {
|
||||
console.warn('Quote schema validation failed:', JSON.stringify(parsed.error.issues, null, 2));
|
||||
showToast(parsed.error.issues[0].message, 'error');
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
The toast message like "Invalid input" comes from Zod validation. Common fields that fail:
|
||||
|
||||
| Field | Schema constraint | Stale localStorage value |
|
||||
|---|---|---|
|
||||
| `discountType` | `z.enum(['dollar', 'percent'])` | `null`, `undefined`, or unexpected string |
|
||||
| `customerDecision` (per service) | `z.enum(['approved', 'declined', 'pending'])` | `undefined` (missing from old store shape) |
|
||||
| `customerName` | `z.string().min(1)` | `""` |
|
||||
| `vehicleInfo` | `z.string().min(1)` | `""` |
|
||||
|
||||
### 5. Confirm stale localStorage
|
||||
|
||||
Open DevTools → Application → Local Storage → `<origin>` → key `spq-quote`.
|
||||
Compare the stored `discount` and `services` arrays against the current Zod schema (`src/schemas/quote.ts`).
|
||||
|
||||
### 6. Fix
|
||||
|
||||
```js
|
||||
localStorage.removeItem('spq-quote');
|
||||
```
|
||||
|
||||
Reload and retry.
|
||||
Reference in New Issue
Block a user