# Guest vs authenticated: data and feature sanity check

**Branch:** `docs/guest-vs-auth-data-audit`  
**Purpose:** Document current behavior so we can confirm: when not logged in you are a guest and most data is in localStorage, with a few known exceptions (e.g. AI may require or benefit from a free account).

---

## 1. How guest vs signed-in is determined

- **Auth:** Supabase Auth. Session is read via `supabaseClient.auth.getSession()` / `onAuthStateChange`.
- **Guest:** No session (or `session.user` is null). UI shows “Sign in” and the guest auth block (`#auth-guest`).
- **Signed-in:** `session.user` exists. `Blueprint.currentUserId` is set, `Blueprint.useSupabaseData = true`, and projects/frameworks/guides are loaded from Supabase.

**Where this is set:** `js/app-init.js` → `setAuthUI(session)`. If `session && session.user`: signed-in path (useSupabaseData = true, loadFromSupabase, etc.). Else: guest path (useSupabaseData = false, clear Supabase caches, `refreshUIAfterSupabaseLoad()` so UI reads from local storage).

---

## 2. Guest: data in localStorage (expected)

When **not** signed in, `Blueprint.useSupabaseData` is **false**. The storage layer and data layer then use **localStorage** for:

| Data | localStorage key(s) | Notes |
|------|---------------------|--------|
| Projects | `crossDomainProjects` | Create, edit, delete: all local. |
| Frameworks | `crossDomainFrameworks` | Same. |
| Guides | `blueprintGuides` / `crossDomainGuides` (see app-data.js / storage.js) | Same. |
| Selected project/guide | `crossDomainSelectedProjectId`, `crossDomainSelectedGuideId` | Selection only. |
| Theme | `crossDomainTheme` | Light/dark. |
| Checklist (implementation) | `crossDomainChecklist` | Check state. |
| Snippets | `blueprintSnippets` | Code snippets. |
| Last section / tab | `crossDomainLastSection`, `lastImplementationToolsTab` | UI state. |
| Datalayer config | `blueprintDatalayerConfig` | Tracking config. |
| GA Audit checklist (local) | `gaAuditChecklist`, `gaAuditAutoLoadLastViewed`, `lastViewedGaAudit_*`, `gaAuditLockConfirmedItems` | When not signed in. |
| Appearance | `blueprintAppearance` | UI preference. |
| AI last extract (cached locally) | `blueprintLastAiExtract` | Optional local cache of last result. |
| Guest / upload flags | `blueprint_uploaded_local`, `blueprint_skipped_upload`, `blueprint_ai_guest_id` | Guest identity and upload modal. |

**Code:** `js/storage.js` and `js/app-data.js` — when `Blueprint.useSupabaseData` is false, `getProjects` / `getFrameworks` / `getGuides` (and corresponding setters) use the keys above. So **guest data is localStorage-only** for projects, frameworks, guides, checklist, snippets, and selections.

---

## 3. Exceptions: what is not purely local for a guest

- **App-level / public content (read-only from Supabase):**  
  Fetched regardless of auth for everyone (including guests): plans, app notices, welcome banners, GA4 tracking config, user guide content, promo/get-started content, **interview question bank/templates** (app_settings), **implementation checklist** (app_settings), **guide templates** (app_settings), valued resources, etc. No login required to *read* these.

- **AI extract (requirements from text):**  
  **Works for guests** with a **guest limit**:
  - Guest ID: `getOrCreateGuestId()` in `js/app-core.js` — stored in `localStorage['blueprint_ai_guest_id']`.
  - Backend: `supabase/functions/ai-assist/index.ts` uses `GUEST_EXTRACT_LIMIT = 3` and table `ai_guest_usage` (by `guest_id` + month). So **guests get 3 free AI extractions per month**; no account required. Sign-in gives higher limits (free plan: typically 10 from `plans.ai_extract_limit`).

- **Pricing/checkout:**  
  Plans are read from DB. Guest checkout for subscriptions is allowed (no auth required); **buying credits requires sign-in** (see create-checkout-session).

---

## 4. Features that require sign-in (current behavior)

These explicitly check `currentUserId` / `getCurrentUserId()` or session and show a “Sign in” message or redirect:

| Feature | Message / behavior |
|--------|---------------------|
| Save guide as template | “Sign in to save templates.” |
| Customize implementation checklist | “Sign in to customize the checklist.” |
| Customize question bank (interviews) | “Sign in to customize the question bank.” |
| Generate from gaps (guide) | Button disabled; title “Sign in to use Generate from gaps”. |
| GA4 audit (run audit) | “Sign in to run GA4 audit.” |
| GA4 audit (delete saved result) | Requires authenticated user. |
| Analytics insights (admin/promo) | “Sign in to use Analytics insights.” |
| Website detection (admin) | “Unauthorized. Please sign in to use website detection.” |
| Admin area | Only shown when signed in; RLS and role checks on backend. |
| Profile / account | Only when signed in. |

So: **core editing (projects, frameworks, guides, checklist, snippets) is local for guests**; **customizing shared content, GA4 audit, guide generation from gaps, and account/admin features require sign-in**.

---

## 5. Sanity-check summary

- **Not logged in ⇒ guest:** Yes. No session ⇒ `useSupabaseData = false`, UI shows “Sign in”, and projects/frameworks/guides/checklist/snippets/selections come from **localStorage**.
- **Exceptions:**  
  - **Read-only content** (plans, notices, interview defaults, checklist content, guide templates, etc.) is loaded from Supabase for everyone; no account needed.  
  - **AI extract:** Guests can use it; limit 3/month (guest_id in `ai_guest_usage`). A free account gives a higher limit (e.g. 10) via `plans.ai_extract_limit`.
- **Sign-in required for:** Saving templates, customizing checklist/question bank, Generate from gaps, GA4 audit, Analytics insights, website detection, admin, profile.

This matches the intended model: **guest = localStorage for almost all user data, with a few exceptions (read-only app content + limited AI for guests; sign-in for customization and advanced features).**
