Files
hermes-config/skills/self-hosting/shop-pro-quote/references/pocketbase-schema.md
T
2026-07-12 10:17:17 -04:00

3.0 KiB

PocketBase Collection Schemas

All userId fields are type text (not relation). PocketBase 0.39.1.

services

Fields: id, userId, name, description, price, category, duration, maintenanceInterval, createdAt, updatedAt, recommendation, explanation, technicianNotes

Critical: The legacy import stores technician narratives in explanation, NOT description. When loading services for display in the Settings catalog, map explanationdescription UI field. The QuoteGenerator already reads explanation directly.

settings

Fields: id, userId, name, data (JSON)

All business settings go into the data JSON field. When creating: { userId, name: 'businessSettings', data: { businessName, ... } }. When updating: { data: { businessName, ... } }. When loading: read from record.data.businessName (not record.businessName). Include fallback to top-level for backward compatibility.

service_advisors

Fields: id, name, email, phone, userId (text)

API rules (must be set after creation): listRule: "userId = @request.auth.id", viewRule: "userId = @request.auth.id", createRule: "@request.auth.id != ''", updateRule: "userId = @request.auth.id", deleteRule: "userId = @request.auth.id"

repairOrders (spq-v2)

Fields: id, status (TEXT), userId (TEXT), customerName, customerEmail, customerPhone, vehicleInfo, vin, mileage, roNumber, notes, services (TEXT — JSON array stored as string), writeupTime (TEXT — ISO timestamp), promisedTime (TEXT — ISO timestamp), estimatedTime (TEXT — hours as decimal string, e.g. "1.5"), completedTime (TEXT — ISO timestamp), financial (JSON blob), advisorName, total (NUMERIC), tax (NUMERIC), shopCharges (NUMERIC), warranty (TEXT/"bool"), lastModified, createdAt, updatedAt, customerId, workStatus

⚠️ Critical: Field name mismatch. The React frontend uses estimatedDuration (minutes number) but PB stores estimatedTime (hours as TEXT string like "1.5"). Always normalize in both directions:

  • On load (fetchOrders): estimatedDuration = Math.round(parseFloat(item.estimatedTime) * 60);
  • On save (handleSave / handleAddTime): estimatedTime: (estimatedDuration / 60).toFixed(1);

Custom fields: There is no customerType or estimatedDuration column. Store extra fields in the financial JSON blob:

  • Read: item.financial?.customerType
  • Write: pb.collection('repairOrders').update(id, { financial: JSON.stringify({ ...existing, customerType: 'waiter' }) })

Creating collections via API

POST to /api/collections with fields array (not schema). PocketBase 0.39.x uses fields. Example:

{
  "name": "service_advisors",
  "type": "base",
  "fields": [
    {"name": "name", "type": "text", "required": true},
    {"name": "userId", "type": "text", "required": true}
  ]
}

Superuser auth: POST /api/collections/_superusers/auth-with-password with { "identity": "email", "password": "..." }. Returns { token, record }. Use token in Authorization header.