initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# Common Bugs & Pitfalls
|
||||
|
||||
## Auth redirect loop (index.html ↔ dashboard.html)
|
||||
|
||||
**Symptom**: Page constantly refreshes between index.html and dashboard.html.
|
||||
|
||||
**Root cause**: `index.html` line 131 blindly checks `localStorage.getItem('pocketbase_auth')` — any truthy value (including stale/expired tokens) triggers a redirect to dashboard.html. Dashboard's `onAuthStateChanged` then detects the invalid token and bounces back to index.html, but the stale token is never cleared from localStorage.
|
||||
|
||||
**Fix**: In every file that redirects unauthenticated users back to index.html, clear the stale token first:
|
||||
|
||||
```javascript
|
||||
localStorage.removeItem('pocketbase_auth');
|
||||
window.location.href = 'index.html';
|
||||
```
|
||||
|
||||
Files that need this: `dashboard.js` (line 122), `appointments.js` (line 50), `repair-orders.js` (line 58).
|
||||
|
||||
## PocketBase auto-cancellation ("request was auto-cancelled")
|
||||
|
||||
**Symptom**: Creating/updating records fails with "The request was auto-cancelled" or similar abort error.
|
||||
|
||||
**Root cause**: PocketBase SDK auto-cancels requests that share the same `requestKey`. By default, all `create`/`update` calls to the same collection share the same key — a rapid double-click fires two identical requests and the first is aborted.
|
||||
|
||||
**Fix — two parts**:
|
||||
|
||||
1. Disable auto-cancellation in `pocketbase.js` by passing `{ requestKey: null }` to all mutating PocketBase calls:
|
||||
- `addDoc`: `pb.collection(collName).create(pbData, { requestKey: null })`
|
||||
- `updateDoc`: `pb.collection(collName).update(docId, pbData, { requestKey: null })`
|
||||
- `setDoc`: both internal `update` and `create` calls need it
|
||||
|
||||
2. Add double-submission guard to form submit handlers — disable the button on first click:
|
||||
```javascript
|
||||
const submitBtn = document.getElementById('submit-create-ro');
|
||||
if (submitBtn && submitBtn.disabled) return;
|
||||
if (submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = 'Creating...';
|
||||
}
|
||||
```
|
||||
Re-enable the button in BOTH the success path (after form clear/collapse) AND the catch block on error. Forgetting the success path leaves the button permanently disabled after a successful submission.
|
||||
|
||||
## DuckDNS DNS stale / site unreachable
|
||||
|
||||
**Symptom**: "This site can't be reached" when accessing grajmedia.duckdns.org.
|
||||
|
||||
**Check order**:
|
||||
1. `dig +short grajmedia.duckdns.org` — if returns `127.0.0.1`, run the DuckDNS updater manually: `bash /opt/duckdns/update.sh`
|
||||
2. The cron job runs every 5 min: `*/5 * * * * /opt/duckdns/update.sh`
|
||||
3. `/etc/hosts` has `127.0.0.1 grajmedia.duckdns.org` for local hairpin NAT — this is intentional, not a bug
|
||||
|
||||
## Dashboard Completed counter shows 0 (`ro.status` vs `ro.workStatus`)
|
||||
|
||||
**Symptom**: "Completed: 0" on the dashboard Repair Orders Today card, despite having completed orders today.
|
||||
|
||||
**Root causes (usually BOTH apply)**:
|
||||
|
||||
1. **Wrong field**: Code filters by `ro.status === 'completed'` but `status` only stores `waiter`/`drop-off`. Must use `ro.workStatus === 'completed'`.
|
||||
2. **Completed orders filtered out at source**: `loadRepairOrders()` in dashboard.js removes all completed orders from `dashboardData.repairOrders` before any counter can see them.
|
||||
|
||||
**Fix checklist**:
|
||||
- Replace ALL `ro.status === 'completed'` with `ro.workStatus === 'completed'`
|
||||
- Replace ALL `ro.status === 'picked-up'` with `ro.workStatus === 'waiting-for-pickup'`
|
||||
- Remove the completed-filter from `loadRepairOrders()` so `dashboardData.repairOrders` contains ALL orders
|
||||
- Each consumer then filters by `ro.workStatus` as needed
|
||||
- See `references/status-field-confusion.md` for the full reference
|
||||
Reference in New Issue
Block a user