feat: implement content management dashboard and update proxy configurations to support AI-assisted learning material generation
This commit is contained in:
65
AI_AGENT.md
65
AI_AGENT.md
@@ -3,33 +3,46 @@
|
||||
Welcome, fellow AI agent! If you are reading this, you are tasked with maintaining or extending the Respellion Learning Platform. This document provides the critical context, architectural patterns, and design standards you need to successfully work on this codebase.
|
||||
|
||||
## 1. Architectural Overview
|
||||
This is a single-page React application built with **Vite**. It is completely self-contained and currently runs without a dedicated backend database.
|
||||
This is a single-page React application built with **Vite**, backed by **PocketBase** as the database and auth layer.
|
||||
* **Frontend:** React, React Router, Tailwind CSS.
|
||||
* **Backend:** PocketBase (self-hosted). All data is stored in PocketBase collections, not localStorage.
|
||||
* **Animations:** Framer Motion (used extensively for page transitions, podium effects, and gamification feedback).
|
||||
* **Icons:** Lucide React.
|
||||
* **Visualizations:** D3.js (used strictly for the Admin Knowledge Graph).
|
||||
|
||||
## 2. State Management & Storage (Critical)
|
||||
There is **no backend database**. All data is persisted locally in the browser using a custom wrapper around `window.localStorage` located at `src/lib/storage.js`.
|
||||
All persistent data lives in **PocketBase**. The data access layer is in `src/lib/db.js`, which wraps the PocketBase SDK client from `src/lib/pb.js`.
|
||||
|
||||
**Namespacing Convention:**
|
||||
You must strictly adhere to these prefixes when reading/writing to `storage.js`:
|
||||
* `kb:*` - Knowledge base data (e.g., `kb:topics`, `kb:relations`, `kb:content:{topicId}`).
|
||||
* `admin:*` - Admin settings (e.g., `admin:anthropic_key`, `admin:sources`, `admin:use_simulation`).
|
||||
* `user:{id}:*` - Specific user progress (e.g., `user:{id}:week:{n}:learn_done`).
|
||||
* `quiz:bank:{topicId}` - Cached banks of AI-generated multiple-choice questions.
|
||||
* `quiz:result:{userId}:week:{n}` - The exact score and payload of a user's weekly test.
|
||||
* `leaderboard:current` - The active points ledger. Array of objects: `{ userId, name, points, testsCompleted, perfectScores }`.
|
||||
* `users:registry` - Array of registered users, including admins.
|
||||
**PocketBase Collections:**
|
||||
* `topics` — Knowledge graph nodes (`id`, `label`, `type`, `description`).
|
||||
* `relations` — Knowledge graph edges (`source`, `target`, `type`).
|
||||
* `content` — AI-generated learning modules per topic (`topic_id`, `data`).
|
||||
* `quiz_banks` — Banks of AI-generated questions per topic (`topic_id`, `questions[]`).
|
||||
* `quiz_results` — User test scores (`user_id`, `week_number`, `score`, `total`, `percentage`, etc.).
|
||||
* `quiz_cache` — Cached weekly quiz for a user (`user_id`, `week_number`, `questions[]`, `meta`).
|
||||
* `learn_progress` — Whether a user completed the weekly learning session (`user_id`, `week_number`, `done`).
|
||||
* `leaderboard` — Points ledger (`user_id`, `name`, `points`, `tests_completed`).
|
||||
* `team_members` — Registered users with PIN auth (`name`, `role`, `pin`).
|
||||
* `sources` — Uploaded source documents and their extraction status (`name`, `status`, `error`).
|
||||
* `settings` — Key/value store for app-wide settings (`key`, `value`).
|
||||
|
||||
**localStorage** is only used for **admin browser settings** (not user data):
|
||||
* `respellion:admin:anthropic_key` — Anthropic API key.
|
||||
* `respellion:admin:model` — Model override.
|
||||
* `respellion:admin:use_simulation` — Simulation mode toggle.
|
||||
|
||||
**Session:** User login is PIN-based. The logged-in user's ID is stored in `sessionStorage` under `respellion_session` and resolved against `team_members` on app load (see `src/store/AppContext.jsx`).
|
||||
|
||||
**Important:** All `db.js` functions are `async`. Always `await` them — omitting `await` will silently pass a Promise where data is expected.
|
||||
|
||||
## 3. The AI Integration (Anthropic)
|
||||
The application acts as a proxy to the Anthropic API (`claude-sonnet-4`).
|
||||
The application calls the Anthropic API via a proxy to avoid CORS issues.
|
||||
* **Location:** `src/lib/api.js`.
|
||||
* **Proxy:** In Docker, `/api/anthropic` is proxied via Nginx to bypass CORS restrictions. If the user reports CORS errors during local dev, ensure the Vite proxy in `vite.config.js` matches the Nginx spec.
|
||||
* **JSON Enforcement:** Prompts *must* strictly enforce that Claude returns *only* raw JSON. Do not let the AI wrap the response in markdown blocks (`\`\`\``) unless you build a regex to strip them (which is currently implemented via `.match(/\{[\s\S]*\}/)`).
|
||||
* **Proxy:** In Docker, `/api/anthropic` is proxied via Nginx to the Anthropic API endpoint. In local dev, configure `vite.config.js` to proxy the same path.
|
||||
* **JSON Enforcement:** Prompts *must* strictly enforce that Claude returns *only* raw JSON. Do not let the AI wrap the response in markdown blocks — a regex strip via `.match(/\{[\s\S]*\}/)` is already applied in all service files.
|
||||
|
||||
## 4. Design System & Aesthetics
|
||||
Respellion relies on a premium, modern aesthetic.
|
||||
Respellion relies on a premium, modern aesthetic.
|
||||
* **CSS Variables:** Rely heavily on the variables defined in `src/index.css`.
|
||||
* Colors: `var(--color-bg)`, `var(--color-paper)`, `var(--color-teal)`, `var(--color-accent)`.
|
||||
* Radii: `var(--r-sm)`, `var(--r-lg)`, `var(--r-org)` (an organic, pill-like shape used for badges and podiums).
|
||||
@@ -38,21 +51,23 @@ Respellion relies on a premium, modern aesthetic.
|
||||
|
||||
## 5. Gamification Rules
|
||||
If you are extending the Gamification system (`src/pages/Leaderboard.jsx`):
|
||||
* Tests grant **+2 points** per correct answer.
|
||||
* A 100% score grants the **Perfectionist** badge.
|
||||
* Tests grant **+2 points** per correct answer (handled in `testService.js → saveTestResult`).
|
||||
* A 100% score grants the **Perfectionist** badge (computed at render time in `Leaderboard.jsx`).
|
||||
* Completing 1 test grants **First Steps**, completing 5 grants **Veteran**.
|
||||
* Do not reset points dynamically. Read from `leaderboard:current`, mutate, and save back immediately.
|
||||
* Points are accumulated in the `leaderboard` collection via `db.upsertLeaderboardEntry`.
|
||||
|
||||
## 6. Docker & Deployment
|
||||
The app is fully containerized.
|
||||
The app is fully containerized. PocketBase runs as a sidecar service.
|
||||
* **Build:** `docker build -t respellion-app:latest .`
|
||||
* **Run:** `docker run -d -p 8080:80 --name respellion respellion-app:latest`
|
||||
* **Nginx:** Ensure any new frontend routes are caught by the Nginx `try_files $uri $uri/ /index.html;` directive defined in `nginx.conf` to prevent 404s on page refresh.
|
||||
* **Run:** `docker compose up -d` (see `docker-compose.yml`).
|
||||
* **Nginx:** Ensures any frontend route not matching a static file falls back to `index.html` (SPA support). The `/api/anthropic` path is proxied to the Anthropic API. The `/pb` path is proxied to the PocketBase service.
|
||||
* **PocketBase URL:** Resolved from `VITE_PB_URL` env var, or falls back to `window.location.origin + '/pb'` (see `src/lib/pb.js`).
|
||||
|
||||
## 7. How to Add New Features
|
||||
1. **Define State:** Decide where the data lives in `localStorage`.
|
||||
2. **Build UI:** Create components using `Card`, `Button`, and `framer-motion` for smooth entry (`animate-in fade-in slide-in-from-bottom-4`).
|
||||
3. **Wire Logic:** Connect to `src/store/AppContext.jsx` if it requires global user context, otherwise manage locally and persist to `storage.js`.
|
||||
4. **Test:** Run the Docker container to ensure no build errors exist.
|
||||
1. **Define Schema:** Add a new PocketBase collection via the Admin UI or the init script (`scripts/setup-pb-collections.mjs`).
|
||||
2. **Add DB Helpers:** Add async CRUD functions in `src/lib/db.js`.
|
||||
3. **Build UI:** Create components using `Card`, `Button`, and `framer-motion` for smooth entry (`animate-in fade-in slide-in-from-bottom-4`).
|
||||
4. **Wire Logic:** Connect to `src/store/AppContext.jsx` if it requires global user context, otherwise manage state locally.
|
||||
5. **Test:** Run the Docker stack (`docker compose up`) to ensure no build errors exist.
|
||||
|
||||
Good luck! You are building a platform that empowers continuous learning. Keep it fast, keep it beautiful, and keep the user engaged.
|
||||
|
||||
Reference in New Issue
Block a user