# Smart Mining ERP — PWA / Offline Architecture

## Goals

- Installable admin shell (manifest + service worker)
- Cache static admin assets for basic offline shell
- Queue operational API writes when offline
- Sync with idempotency to avoid duplicate domain posts

## Components

### Manifest

`public/manifest.json` — app name, theme, start URL `/admin`.

### Service worker

`public/sw.js` — caches admin shell assets; does **not** cache `/api/*` responses (financial freshness & auth).

Register from the admin layout or a small bootstrap script:

```js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}
```

### Offline queue (client)

Client responsibility:

1. Detect offline / failed write
2. Store `{ uuid, endpoint, payload }` in IndexedDB
3. On reconnect, `POST /api/v1/sync/push` with the same `idempotency_key`

### Server idempotency

Table `idempotency_keys`:

| Column | Purpose |
|--------|---------|
| `id` (uuid) | Client key |
| `user_id` | Owner |
| `endpoint` | Logical endpoint |
| `payload_hash` | SHA-256 of payload |
| `response` / `status_code` | Cached acceptance |

Repeated push with same user+endpoint+hash returns the stored response (`idempotent: true`).

### Conflict handling

- Same key + same hash → replay stored response
- Same key + different hash → create new row / reject as conflict (current push always hashes payload)
- Domain validation still runs when a push is first accepted and later processed by workers (extensible)

### Sync status

`GET /api/v1/sync/status` returns recent keys and counts for the authenticated user.

## Security notes

- Attachments stay on private `local` disk (`storage/app/private`)
- Sync endpoints require Sanctum auth + API throttle
- Never sync secrets or raw SQL
