Skip to content

Architecture Evaluation: Resilient Guest-to-Authenticated User Transition Systems

Metadata

  • Status: Draft
  • Date: 2026-01-17
  • Related Issue: 2512_genai_food_tracking-kzq
  • Type: Deep Research / Architecture Evaluation (ACP-002)

1. Executive Summary

Strategic Context

The implementation of a "Guest Mode"—allowing users to log meals and track macros prior to authentication—is a critical Product-Led Growth (PLG) lever. By deferring the friction of account creation, we reduce funnel drop-off and maximize the "Aha!" moment.

This requirement introduces complexity into the data persistence and synchronization layers. The transition from a local-only, anonymous state to a synchronized cloud profile is a distributed systems problem. The system must adhere to three architectural imperatives:

  1. Local Authority: The local database is the primary source of truth during the guest phase.
  2. Deferred Synchronization: Sync logic must be decoupled from the rendering cycle.
  3. Atomic and Idempotent Migration: The "Merge Event" must handle partial failures gracefully.

2. Client-Side Data Persistence

2.1 The Bottleneck of localStorage

localStorage operates synchronously on the main JavaScript thread. As a user's log history grows, the required serialization (JSON.stringify) and deserialization (JSON.parse) operations introduce perceptible UI latency ("jank").

Constraints

  • Blocking: Synchronous I/O halts the main thread.
  • Capacity: Hard 5MB quota per origin.

2.2 The Solution: IndexedDB via Dexie.js

To ensure 60fps performance and accommodate extensive history, we should utilize IndexedDB.

Recommendation: Dexie.js

Use Dexie.js as the abstraction layer. It provides a clean Promise-based API that eliminates the boilerplate of raw IndexedDB, focusing purely on efficient data retrieval.

  • Asynchronous I/O: Read/write operations do not block the UI thread.
  • Structured Cloning: Supports storing JavaScript objects directly.
  • Capacity: Quotas are significantly higher (often % of available disk space).

3. Client-Side Data Hygiene

Since the data is not sensitive PII, the focus is on simple data hygiene to prevent confusion on shared devices.

Session Cleanup

  • Logout Protocol: The logout action must explicitly invoke Dexie.delete() or db.table.clear().
  • State Reset: Ensure any in-memory global state (React Context/Query) is reset.

4. The Synchronization Engine

4.1 The Repository Pattern for Frontend State

The UI components should not be aware of whether the data is coming from the local DB or the server.

The Universal Hook

A custom hook (e.g., useUniversalMacros) verifies the auth state.

  • Guest: Streams data via useLiveQuery from Dexie.
  • User: Activates the React Query fetcher.

5. Identity Transition

5.1 Hybrid Proposal: Local-First to Just-In-Time Auth

To minimize backend costs and complexity:

  1. Visitor (Default): No ID, Local Storage (Dexie) only. Zero database cost.
  2. Conversion (Sign Up): User creates an account to save data permanently.
  3. Migration: Local data is "pushed" to the new identity during onboarding.

6. Backend Data Ingestion

The "Merge Event" creates a write throughput spike.

6.1 Idempotent Batching

Use BatchWriteItem rather than TransactWriteItems to maximize throughput and minimize cost.

  • Chunking: Client or resolver must split the payload into batches of 25 (DynamoDB limit).
  • Idempotency: Backend handles retries gracefully using deterministic IDs (Client-side UUIDs).

6.2 The Custom Migration Resolver

Implement a dedicated importGuestHistory mutation backed by a Lambda resolver to handle chunking and error aggregation efficiently.


7. Conflict Resolution

Strategy: Smart Merge with Recency Preference

  • Disjoint Data: Unique IDs (UUIDs) are simply appended.
  • Overlapping Data: Trust the Guest. Assume immediate, local interaction reflects the user's most current intent.

8. Shared Validation

The Monorepo Advantage

Use Zod for schema definition. Define a single MealLogSchema to validate user input on the client (Dexie) and in the Lambda resolver (DynamoDB).


9. Operational Readiness

  • Offline Migration Recovery: Flag local data as pending_sync if upload fails.
  • Data Consistency: Ensure Client-side UUID generation is robust.

10. Summary of Architectural Specifications

Component Legacy/Naive Approach Proposed Robust Architecture
Local Storage localStorage (Blocking) Dexie.js / IndexedDB (Async)
Data Security Plaintext Standard Browser Sandbox (Clear on Logout)
Sync Logic Manual/Redux Persist React Query + Background Sync
Migration N+1 GraphQL Mutations Lambda Batch Resolver (Chunked)
Conflicts Last Write Wins Smart Merge (Recency Preference)
Validation Duplicated / Divergent Shared Zod Schema (Zod)