# Phase 24: Public Access & Infrastructure - Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-04-09
**Phase:** 24-public-access-infrastructure
**Areas discussed:** Auth boundary redesign, Client-side routing for anonymous users, Rate limiting strategy, Loading experience for visitors

---

## Auth Boundary Redesign

| Option | Description | Selected |
|--------|-------------|----------|
| Allowlist public routes | Keep requireAuth as default on /api/*, maintain explicit list of public GET routes that skip auth. Extends current pattern. | ✓ |
| Separate route registration | Register public routes BEFORE auth middleware, private routes AFTER. Route order determines auth. | |
| Per-route middleware | Remove blanket /api/* auth. Each route file applies requireAuth on its own write endpoints. | |

**User's choice:** Allowlist public routes (recommended)
**Notes:** None

| Option | Description | Selected |
|--------|-------------|----------|
| Yes, make categories public | Categories are structural data — needed for catalog browsing context. | |
| No, keep categories auth-gated | Only expose what's strictly required. | |

**User's choice:** Other — Categories are user-scoped. Unauthenticated users access global items which use tags, not categories. Categories stay private.
**Notes:** "the thing is currently all item categories are what the user defines them to be, so if the user isn't authenticated the items they are accessing shouldn't have a category in the first place, instead they have tags, for sorting searching etc"

| Option | Description | Selected |
|--------|-------------|----------|
| Show category names in public view | Include owner's category name as read-only display context in public setup view. | ✓ |
| Items without category context | Public setup view shows items with weight/price but no category labels. | |

**User's choice:** Show category names in public view (recommended)
**Notes:** None

---

## Client-Side Routing for Anonymous Users

| Option | Description | Selected |
|--------|-------------|----------|
| Expand public route list | Extend isPublicRoute check to include /global-items/*, /setups/*/public, /catalog, and /. Keep login redirect for private routes. | ✓ |
| Invert to private route list | List private routes instead; everything else accessible without auth. | |
| You decide | Claude picks cleanest approach. | |

**User's choice:** Expand public route list (recommended)
**Notes:** None

| Option | Description | Selected |
|--------|-------------|----------|
| Hide TotalsBar for anonymous | No TotalsBar when not authenticated. Public pages show their own header. | |
| Show a simplified public header | Replace TotalsBar with minimal header for anonymous visitors. | |
| Keep TotalsBar with login CTA | Replace stats with sign-in message. | |

**User's choice:** Other — TotalsBar is already only in collection views, not in the header. No changes needed.
**Notes:** "there should only be a totals bar in the collection views etc, we should have removed the one from the header already, so no need there"

| Option | Description | Selected |
|--------|-------------|----------|
| Redirect to /login with return URL | Standard redirect-based pattern. | |
| Show inline login prompt | Show modal/toast instead of navigating away. Keeps context visible. | ✓ |
| You decide | Claude picks best UX pattern. | |

**User's choice:** Show inline login prompt — but specifically with "sign in or sign up" messaging, not just login.
**Notes:** "we should show a popup saying to manage your own collection you need to sign in or sign up, because while a direct sending to signin might be a better flow for already signed up users it is terrible for new users, which i think matters more"

---

## Rate Limiting Strategy

| Option | Description | Selected |
|--------|-------------|----------|
| 100 req/min per IP | Generous for normal browsing, blocks scraping. Standard for public APIs. | |
| 60 req/min per IP | More conservative. | |
| You decide | Claude picks appropriate limits per endpoint type. | ✓ |

**User's choice:** You decide
**Notes:** None

| Option | Description | Selected |
|--------|-------------|----------|
| Exempt authenticated users | Authenticated users trusted, rate limiting for anonymous abuse. | |
| Higher limits for authenticated | Still rate-limit but at 5-10x anonymous limit. | |
| Same limits for everyone | Simplest, no distinction. | ✓ |

**User's choice:** Same limits for everyone
**Notes:** "i feel like there is no diff, authenticated users could still spam the api, we should find a good sweet spot for the amount of calls that are being made, i think this is something that will change with experience"

---

## Loading Experience for Visitors

| Option | Description | Selected |
|--------|-------------|----------|
| Fire-and-forget auth check | Render page immediately, check auth in background. Anonymous users see content right away. | ✓ |
| Fast auth with skeleton | Check auth first but show content skeleton instead of spinner. | |
| You decide | Claude picks best approach. | |

**User's choice:** Fire-and-forget auth check (recommended)
**Notes:** None

| Option | Description | Selected |
|--------|-------------|----------|
| Login button in top-right corner | Simple 'Sign in' link on all public pages. Disappears when authenticated. | ✓ |
| No persistent login link | Users find login through write-action popup only. | |
| You decide | Claude picks based on navigation patterns. | |

**User's choice:** Login button in top-right corner (recommended)
**Notes:** None

---

## Claude's Discretion

- Rate limit numbers per endpoint type (browse, search, detail)

## Deferred Ideas

None — discussion stayed within phase scope
