# Offline Action Queue

## Objective

Let people keep working through a dropped connection and sync it safely later.

A durable queue that captures writes made while the app is offline and replays them against the server on reconnect.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Choose a small, explicit set of actions that are safe to queue. Build on the app's existing service worker and storage if it already has one rather than standing up a second offline layer.
2. Persist queued actions durably so a reload or crash does not lose them, and record enough context to replay each one exactly.
3. Give every queued action a client-generated idempotency key and have the server reject a repeat of the same key, so a retried request cannot write twice.
4. Replay in the order the user performed the actions, and halt the dependent chain when one action fails rather than applying later actions against a state that never existed.
5. Show the user what is queued, what synced, and what failed, with a way to retry or discard individual items.
6. Do NOT queue anything the server might reject for authorization or business reasons without a plan for the rejection. A silently dropped write is worse than a write that never happened, because the user believes it landed.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Do not store credentials, tokens, or sensitive field values in offline storage — it is readable on a shared or stolen device.
- A session that expires while offline must prompt for re-authentication before replay, not fail every queued item.
- Permissions can change while offline; a queued edit to a record the user no longer owns must surface as a conflict, not a crash.
- If the record changed server-side since the action was queued, present the conflict with both versions instead of blindly overwriting.
- A queue that fails permanently must be drainable: cap retries, mark items dead, and let the user export or discard them.
- Cap the queue size and the age of entries. Replaying a two-week-old action is usually wrong.
- Creating an item offline and then editing it requires the temporary local id to be remapped to the server id during replay.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Queued actions survive reload and browser restart.
- [ ] Every replayed request carries an idempotency key and duplicates are rejected server-side.
- [ ] Replay preserves user ordering and stops a chain when a dependency fails.
- [ ] Expired sessions, permission changes, and validation failures each produce a specific, visible outcome.
- [ ] The user can see the queue and retry or discard individual failed items.
- [ ] No credentials or sensitive values are written to offline storage.
- [ ] The queue always reaches a terminal state — it cannot retry forever.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
