173 lines
7.5 KiB
Markdown
173 lines
7.5 KiB
Markdown
# 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
|