Guest Mode Implementation (Sample Result Preview)

Sprint 111 — Guest Mode Implementation (Sample Result Preview)

Background

There was no entry point for unauthenticated users to experience AlgoSu's core value (AI code analysis) without OAuth registration. The /login page only offered 3 OAuth providers + demo account login (full feature tour), causing high drop-off from potential users who wanted to "just see the results briefly without signing up."

Sprint 111 introduced a lightweight guest mode showing only 3 pre-seeded sample analysis results without session or authentication. It is a completely independent module separated from the existing GuestContext (share-link based), with zero backend changes.

Wave structure: W1 (Herald frontend implementation) → W2 (Gatekeeper security review) → W3 (Scribe ADR + memory update).

Goals

ItemContentStatus
Middleware PUBLIC_PATHS extension/guest unauthenticated access allowed✅ Complete (W1)
Static fixture dataGuestSample[] 3 items (JS/Python/SQL)✅ Complete (W1)
Guest index page/guest — card grid + CTA✅ Complete (W1)
Guest detail page/guest/preview/[slug] — ScoreGauge + feedback✅ Complete (W1)
GuestNav componentglassmorphism nav (logo + sign-up CTA + theme toggle)✅ Complete (W1)
Login page entry link"Browse as guest" text link✅ Complete (W1)
Security reviewAuth bypass / XSS / Open Redirect / route regression✅ 0 blocking (W2)

Decisions

D1. Stateless Identification — No JWT/cookie, localStorage Flag Not Introduced

Background: Plan mentioned localStorage: algosu:guest-mode=true flag as an option, but Herald did not implement it.

Options:

  1. Introduce localStorage flag (as planned)
  2. Fully stateless — guest allowed by URL access alone, no flag

Decision: Option 2. localStorage flag not introduced.

Rationale: Gatekeeper review (A-2) confirmed this is security-superior as "state manipulation vector removed." Accessing /guest URL directly is recognized as guest — no additional state management needed. Guest-to-member conversion tracking (event logging) is a follow-up sprint task.

D2. 3 Static Fixtures — Ensuring Difficulty/Language/Subject Diversity

Background: The number and type of guest samples needed to be decided.

Options:

  1. Single sample (simplest)
  2. 3 samples — Bronze/Gold/Silver, JavaScript/Python/SQL combination
  3. 5+ samples

Decision: Option 2. 3 fixtures.

SlugProblemDifficultyLanguageScore
two-sumLeetCode #1 Two SumBRONZEJavaScript92
lru-cacheLeetCode #146 LRU CacheGOLDPython88
sql-windowProgrammers Department Salary RankingSILVERSQL85

Rationale: Covering Bronze/Silver/Gold 3 levels and JavaScript/Python/SQL 3 languages shows AlgoSu's core learning paths at once. SQL also exposes the SQL learning path added in Sprints 108–109.

D3. Guest Route — AppLayout Not Used, Independent GuestNav

Background: In App Router, the guest route needed to bypass AppLayout (Sidebar, SessionProvider, etc.) which requires authentication.

Options:

  1. Conditionally skip authentication in existing AppLayout
  2. Independent layout + GuestNav for /guest group

Decision: Option 2. Separate layout for /app/guest/ route group, new GuestNav.tsx.

Rationale: AppLayout includes auth-dependent components like SessionProvider, useSession, Sidebar. Conditional skip could cause side effects on existing auth flow — independent layout is safer from a separation of concerns perspective. Zero new Palette tokens added by reusing glass-nav token and existing Logo, next-themes.

D4. No Real-time AI Calls — Static Fixtures Only

Background: Some reviews discussed providing real-time AI analysis via rate-limited API.

Options:

  1. Rate-limited real-time AI calls (IP-based limiting)
  2. Human-written static fixtures only (0 LLM calls)

Decision: Option 2. Static fixtures only.

Rationale: Triple burden of cost/security/latency. Guest mode's purpose is to preview the "form" of AI analysis results, not to provide actual analysis. Static fixtures can provide more polished exemplary answers than actual AI analysis results, with zero server resource consumption.


Security Review Results (Gatekeeper W2)

0 blocking issues. All PASS.

ItemResult
Middleware route guard boundary conditions/guestXYZ, /guest-admin blocking confirmed
Protected route regression/dashboard → /login?redirect=... normal
API call absence0 fetch/authApi/token references
XSS vectorNo dangerouslySetInnerHTML, Prism auto-escaping
Open RedirectsanitizeRedirect() logic unchanged
Existing GuestContext separationNo import cross-references
slug Path TraversalGUEST_SAMPLES.find() → notFound(), no filesystem access
Bundle size/guest First Load 184 kB (under 200 KB threshold passed)

Recommendations (INFO — non-blocking):

  • A-1: sql: 'sql' not registered in CodeBlock LANG_MAP → text fallback (1-line addition recommended follow-up)
  • A-2: robots.txt / noindex policy unresolved (decide in follow-up SEO sprint)
  • A-3: sourceUrl hardcoding safe. Allowlist required when switching to dynamic sourcing

Wave Execution Log

WaveAgentTaskCommit
W1HeraldMiddleware patch + fixture data + routes + GuestNav + login link (9 files)7c45842
W2GatekeeperSecurity review (no code changes)
W3ScribeSprint 111 ADR + sprint-window/MEMORY.md update

Outputs and Changed Files

FileActionWaveDescription
frontend/src/middleware.tsModifiedW1'/guest' added to PUBLIC_PATHS (1 line)
frontend/src/data/guest-samples/index.tsNewW1GuestSample type + GUEST_SAMPLES array
frontend/src/data/guest-samples/samples/two-sum.tsNewW1Two Sum sample (BRONZE/JavaScript, score 92)
frontend/src/data/guest-samples/samples/lru-cache.tsNewW1LRU Cache sample (GOLD/Python, score 88)
frontend/src/data/guest-samples/samples/sql-window.tsNewW1Department Salary Ranking sample (SILVER/SQL, score 85)
frontend/src/components/guest/GuestNav.tsxNewW1Guest-exclusive glassmorphism nav
frontend/src/app/guest/page.tsxNewW1Guest index — hero + sample card grid
frontend/src/app/guest/preview/[slug]/page.tsxNewW1Guest detail — ScoreGauge + CodeBlock + feedback + bottom banner
frontend/src/app/(auth)/login/page.tsxModifiedW1"Browse as guest" text-text-3 link added

Change statistics: 9 files changed, 892 insertions(+), 1 deletion(−)

Commit list (1 item):

  • 7c45842 — feat(frontend): guest mode implementation — static fixture based sample analysis preview

Lessons Learned

1. Security Benefits of Stateless Design

The plan included localStorage flag as an option, but Herald not implementing it was evaluated as "state manipulation vector removed" — superior in security — by Gatekeeper review. Fully stateless approach of identifying guests solely by URL-based route access is optimal for read-only preview like guest mode.

2. Design Clarity from Zero-Backend Constraint

The explicit constraint "0 backend code changes" kept the design simple. Naturally blocked consideration of real-time AI calls and allowed focus on the correct direction of static fixtures.

3. Existing Component Reuse — Zero New Palette Tokens

Complete reuse of existing components (ScoreGauge, CodeBlock, DifficultyBadge, parseFeedback()) and tokens (glass-nav, text-text-3, etc.) enabled implementation completion in a single wave without Palette consultation. Effect of explicitly specifying "no new tokens/Palette components" constraint in the sprint planning stage.

4. CodeBlock SQL Fallback — Unregistered Languages Must Be Pre-checked

The sql-window sample's language: 'sql' was not in CodeBlock's LANG_MAP, so text fallback was applied. This could have been prevented by pre-checking CodeBlock's supported language list when deciding fixture languages. Future new language sample additions must check LANG_MAP registration first.


Carried Over

ItemContentPriority
CodeBlock SQL supportAdd sql: 'sql' to LANG_MAP (1 line)LOW
robots.txt / noindex policyDecide guest page indexingLOW
Guest conversion tracking/guest → sign-up event loggingLOW

  • docs/adr/sprints/sprint-110.md — preceding sprint (complete carry-over processing)
  • frontend/src/middleware.ts — PUBLIC_PATHS guest patch
  • frontend/src/data/guest-samples/ — GuestSample type + 3 fixtures
  • frontend/src/app/guest/ — guest route group
  • frontend/src/components/guest/GuestNav.tsx — guest-exclusive nav