Files
grateful-journal/docs/project-context.md

7.5 KiB

Project Context for AI Agents

This file contains critical rules and patterns that AI agents must follow when implementing code in this project. Focus on unobvious details that agents might otherwise miss.


Project overview

Grateful Journal — A minimal, private-first gratitude journaling web app. Three main pages (Write, History/calendar, Settings/profile) plus Google auth. No feeds or algorithms; privacy by design with client-side encryption; daily use, even one sentence.

User: Jeet


Technology stack & versions

Layer Technology Notes
Frontend React 19, TypeScript Vite 7 build; port 8000
Routing react-router-dom 7 Routes: /, /history, /settings, /login
Auth Firebase 12 Google sign-in only (no database)
Styling Plain CSS src/index.css (globals), src/App.css (components)
Backend FastAPI 0.104 Python; port 8001; modular routes
Database MongoDB 6.x Local instance; collections: users, entries, settings

Critical implementation rules

Frontend

  • Colour palette (Coolors): Use CSS variables from src/index.css. Primary green #1be62c, background soft #f1eee1, surface #ffffff, accent light #cff2dc, accent bright #c3fd2f. Do not introduce new palette colours without reason.
  • Layout: Responsive for all screens. Breakpoints: --bp-sm 480px, --bp-md 768px, --bp-lg 1024px, --bp-xl 1280px. On laptop (1024px+), page is single-screen 100vh — no vertical scroll; fonts and spacing scaled so content fits one viewport.
  • Touch targets: Minimum 44px (--touch-min) on interactive elements for small screens.
  • Safe areas: Use env(safe-area-inset-*) for padding where the app can sit under notches or system UI. Viewport meta includes viewport-fit=cover.
  • Structure: Main app layout: page container → header + main content + fixed BottomNav. Content max-width min(680px, 100%) (or --content-max 720px where appropriate).

Backend (when implemented)

  • Framework: FastAPI. APIs in Python only.
  • Modularity: Separate file per route. Each feature (users, entries) has its own router module.
  • Database: MongoDB. Setup instructions below.
  • Port: 8001 (backend); 8000 (frontend). CORS configured between them.
  • Authentication: Relies on Firebase Google Auth token from frontend (passed in Authorization header).

Conventions

  • Fonts: Inter for UI, Playfair Display for headings/editorial, Lora for body/entry text. Loaded via Google Fonts in index.html.
  • Naming: CSS uses BEM-like class names (e.g. .journal-card, .journal-prompt). Keep the same pattern for new components.
  • Build: Fixing the current TypeScript/ESLint build errors is deferred to a later step; do not assume a clean build when adding features.

File layout (reference)

src/                          # Frontend
  App.tsx, App.css            # Root layout, routes, global page styles
  index.css                   # Resets, :root vars, base typography
  main.tsx
  pages/                      # HomePage, HistoryPage, SettingsPage, LoginPage
  components/                 # BottomNav, LoginCard, GoogleSignInButton, ProtectedRoute
  contexts/                   # AuthContext (Firebase Google Auth)
  lib/
    firebase.ts               # Firebase auth config (Google sign-in only)
    api.ts                    # API client for backend calls

backend/                      # FastAPI backend (Port 8001)
  main.py                     # FastAPI app, CORS, routes, lifespan
  config.py                   # Settings, environment variables
  db.py                       # MongoDB connection manager
  models.py                   # Pydantic models (User, JournalEntry, Settings)
  requirements.txt            # Python dependencies
  .env.example                # Environment variables template
  routers/
    users.py                  # User registration, update, delete endpoints
    entries.py                # Entry CRUD, date filtering endpoints

Last updated: 2026-03-04

Recent Changes & Status

Port Configuration (Updated)

Frontend port changed to 8000 (was 5173)
Backend port remains 8001
CORS configuration updated in FastAPI
Vite config updated with server port 8000

Backend Setup (Completed)

FastAPI backend initialized (port 8001)
MongoDB connection configured (local instance)
Pydantic models for User, JournalEntry, UserSettings
Route structure: /api/users/* and /api/entries/*
CORS enabled for frontend (localhost:8000)
Firebase Google Auth kept (Firestore completely removed) MongoDB as single source of truth

API Ready

  • User registration, profile updates, deletion
  • Entry CRUD (create, read, update, delete)
  • Entry filtering by date
  • Pagination support

Zero-Knowledge Encryption Implementation (Completed)

Crypto Module — Created src/lib/crypto.ts with complete zero-knowledge privacy

  • Libsodium.js integrated for cryptography (XSalsa20-Poly1305)
  • Key derivation from Firebase credentials using Argon2i KDF
  • Device key generation and localStorage persistence
  • Encrypted secret key storage in IndexedDB
  • Entry encryption/decryption utilities

Key Management Flow

  • Login: KDF derives master key from firebaseUID + firebaseIDToken + salt
  • Device Setup: Random device key generated, stored in localStorage
  • Key Cache: Master key encrypted with device key → IndexedDB
  • Memory: Master key kept in memory during session only
  • Subsequent Login: Cached encrypted key recovered via device key
  • New Device: Full KDF derivation, new device key generated
  • Logout: Master key cleared from memory; device key persists for next session

AuthContext Enhanced

  • Added secretKey state (in-memory only)
  • Integrated encryption initialization on login
  • Device key and IndexedDB cache management
  • Automatic recovery of cached keys on same device

Backend Models Updated — Zero-knowledge storage

  • JournalEntryCreate: title/content optional (null if encrypted)
  • EncryptionMetadata: stores ciphertext, nonce, algorithm
  • Server stores encryption metadata only, never plaintext
  • All entries encrypted with XSalsa20-Poly1305 (libsodium)

API Routes — Encrypted entry flow

  • POST /api/entries/{userId} accepts encrypted entries
  • Validation ensures ciphertext and nonce present
  • Entry retrieval returns full encryption metadata
  • Update routes support re-encryption
  • Server processes only encrypted data

HomePage — Encrypted entry creation

  • Entry and title combined: title\n\n{entry}
  • Encrypted with master key before transmission
  • Sends ciphertext, nonce, algorithm metadata to backend
  • Success feedback confirms secure storage

HistoryPage — Entry decryption & display

  • Fetches encrypted entries from server
  • Client-side decryption with master key
  • Splits decrypted content: first line = title
  • Graceful handling of decryption failures
  • Displays original title or [Encrypted] on error

Next Steps (Implementation)

🔄 Entry detail view with full decryption
🔄 Edit encrypted entries (re-encrypt on changes)
🔄 Search/filter encrypted entries (client-side only)
🔄 Export/backup encrypted entries with device key