# Stage 4 — User Accounts, Saved Projects, and Archive

Stage 4 makes every new conversion account-owned and accessible across devices. It adds email/password registration, login/logout, password recovery, profile and password updates, a saved-project dashboard, archive/restore, permanent deletion, and automatic editor drafts.

## Authentication and ownership

The React SPA uses Laravel Sanctum's HTTP-only session cookie. Mutating requests first obtain `/sanctum/csrf-cookie`, send credentials, and include the XSRF token. All authoring and package routes require `auth:sanctum`; controllers return 404 for another user's project. Signed slide, poster, media, and caption URLs remain short-lived package-preview resources.

New uploads are assigned to the signed-in user. A pre-Stage-4 browser token can be submitted once to `/api/v1/projects/claim-legacy`; only an unowned conversion with the matching token can be claimed.

Password reset messages use the first `FRONTEND_URL` entry. Local development writes messages to `storage/logs/laravel.log`; production must configure a real Laravel mail transport.

## Projects and drafts

The dashboard lists active or archived projects, supports search, and exposes open, rename, download, archive, restore, and confirmed permanent deletion. Archived projects are read-only until restored, although an existing completed package can still be downloaded.

Project editor URLs use `/tools/powerpoint-to-scorm/{uuid}`. Valid settings, quiz, media, and course-flow changes save after an 800 ms debounce. Revision conflicts return HTTP 409, failed work remains visibly dirty, and closing a dirty editor produces a browser warning.

Permanent deletion marks the conversion immediately and queues recursive storage/database cleanup. Deleted media and conversion jobs exit safely when their target no longer exists.

## Required environment values

Local frontend and API URLs must use the same host spelling. Production should configure:

```dotenv
FRONTEND_URL=https://tools.example.com
SANCTUM_STATEFUL_DOMAINS=tools.example.com
SESSION_DOMAIN=.example.com
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
MAIL_MAILER=smtp
```

Run `php artisan migrate --force`, keep the normal conversion and media workers running, and restart workers after deployment.
