206 lines
5.9 KiB
Markdown
206 lines
5.9 KiB
Markdown
# Robot U Site Agent Guide
|
|
|
|
## Purpose
|
|
|
|
This repository contains the Robot U community site.
|
|
|
|
It is a thin application layer over Forgejo:
|
|
|
|
- Forgejo is the source of truth for authentication, public content repos, and issue-backed discussions.
|
|
- This app provides the web UI, course/lesson browsing, markdown rendering, and ICS calendar ingestion.
|
|
- The current live Forgejo instance is `https://aksal.cloud`.
|
|
|
|
## Stack
|
|
|
|
- Backend: FastAPI
|
|
- Frontend: Preact + TypeScript + Vite
|
|
- Python tooling: `uv`, `ruff`
|
|
- Frontend tooling: `bun`, Biome
|
|
|
|
## Important Files
|
|
|
|
- `app.py`: FastAPI app and SPA/static serving
|
|
- `live_prototype.py`: live payload assembly for courses, lessons, discussions, and events
|
|
- `prototype_cache.py`: server-side cache for the public Forgejo content payload
|
|
- `update_events.py`: in-process SSE broker for content update notifications
|
|
- `forgejo_client.py`: Forgejo API client
|
|
- `calendar_feeds.py`: ICS/webcal feed loading and parsing
|
|
- `settings.py`: env-driven runtime settings
|
|
- `frontend/src/App.tsx`: client routes and page composition
|
|
- `frontend/src/MarkdownContent.tsx`: safe markdown renderer used in lessons and discussions
|
|
- `scripts/start.sh`: main startup command for local runs
|
|
|
|
## Repo Layout Notes
|
|
|
|
- The root repository is the site application.
|
|
- `examples/quadrature-encoder-course/` is a separate nested git repo used as sample content. It is intentionally ignored by the root repo and should stay that way.
|
|
|
|
## First-Time Setup
|
|
|
|
### Python
|
|
|
|
```bash
|
|
python3 -m venv .venv
|
|
.venv/bin/pip install -r requirements.txt
|
|
```
|
|
|
|
### Frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
~/.bun/bin/bun install
|
|
```
|
|
|
|
## Environment
|
|
|
|
Runtime configuration is loaded from shell env, then `.env`, then `.env.local` through `scripts/start.sh`.
|
|
|
|
Recommended local flow:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Useful variables:
|
|
|
|
- `FORGEJO_BASE_URL=https://aksal.cloud`
|
|
- `APP_BASE_URL=http://kacper-dev-pod:8800`
|
|
- `AUTH_SECRET_KEY=...`
|
|
- `AUTH_COOKIE_SECURE=false`
|
|
- `CORS_ALLOW_ORIGINS=http://kacper-dev-pod:8800`
|
|
- `FORGEJO_OAUTH_CLIENT_ID=...`
|
|
- `FORGEJO_OAUTH_CLIENT_SECRET=...`
|
|
- `FORGEJO_OAUTH_SCOPES=openid profile`
|
|
- `FORGEJO_TOKEN=...`
|
|
- `FORGEJO_GENERAL_DISCUSSION_REPO=Robot-U/general_forum`
|
|
- `FORGEJO_WEBHOOK_SECRET=...`
|
|
- `FORGEJO_CACHE_TTL_SECONDS=60.0`
|
|
- `CALENDAR_FEED_URLS=webcal://...`
|
|
- `HOST=0.0.0.0`
|
|
- `PORT=8800`
|
|
|
|
Notes:
|
|
|
|
- Browser sign-in uses Forgejo OAuth/OIDC. `APP_BASE_URL` must match the URL opened in the browser, `CORS_ALLOW_ORIGINS` should include that origin, and the Forgejo OAuth app must include `/api/auth/forgejo/callback` under that base URL.
|
|
- Browser OAuth requests only identity scopes. The backend stores the resulting Forgejo token in an encrypted `HttpOnly` cookie and may use it only after enforcing public-repository checks for writes.
|
|
- `FORGEJO_TOKEN` is optional and should be treated as a read-only local fallback for the public content cache. Browser sessions and API token calls may write issues/comments only after verifying the target repo is public.
|
|
- `/api/prototype` uses a server-side cache for public Forgejo content. `FORGEJO_CACHE_TTL_SECONDS=0` disables it; successful discussion replies invalidate it.
|
|
- General discussion creation requires `FORGEJO_GENERAL_DISCUSSION_REPO`. Linked discussions are created in the content repo and include canonical app URLs in the Forgejo issue body.
|
|
- Forgejo webhooks should POST to `/api/forgejo/webhook`; when `FORGEJO_WEBHOOK_SECRET` is set, the backend validates Forgejo/Gitea-style HMAC headers.
|
|
- API clients can query with `Authorization: token ...` or `Authorization: Bearer ...`.
|
|
- `CALENDAR_FEED_URLS` is optional and accepts comma-separated `webcal://` or `https://` ICS feeds.
|
|
- Do not commit `.env` or `.env.local`.
|
|
|
|
## Main Start Command
|
|
|
|
Use this for the normal local app flow:
|
|
|
|
```bash
|
|
./scripts/start.sh
|
|
```
|
|
|
|
What it does:
|
|
|
|
1. Loads `.env` and `.env.local` if present.
|
|
2. Builds the frontend with `bun`.
|
|
3. Starts FastAPI with `uvicorn`.
|
|
|
|
Override host/port when needed:
|
|
|
|
```bash
|
|
HOST=0.0.0.0 PORT=8800 ./scripts/start.sh
|
|
```
|
|
|
|
## Deployment Commands
|
|
|
|
Bootstrap Forgejo Actions SSH clone credentials:
|
|
|
|
```bash
|
|
export FORGEJO_API_TOKEN=...
|
|
./scripts/bootstrap_ci_clone_key.py
|
|
```
|
|
|
|
Validate production environment before starting:
|
|
|
|
```bash
|
|
./scripts/check_deploy_config.py
|
|
```
|
|
|
|
Container deployment:
|
|
|
|
```bash
|
|
docker compose up --build -d
|
|
curl -fsS http://127.0.0.1:8800/health
|
|
```
|
|
|
|
Non-container production start after building `frontend/dist`:
|
|
|
|
```bash
|
|
HOST=0.0.0.0 PORT=8000 ./scripts/run_prod.sh
|
|
```
|
|
|
|
## Development Commands
|
|
|
|
### Backend only
|
|
|
|
```bash
|
|
.venv/bin/python -m uvicorn app:app --reload
|
|
```
|
|
|
|
### Frontend only
|
|
|
|
```bash
|
|
cd frontend
|
|
~/.bun/bin/bun run dev
|
|
```
|
|
|
|
### Frontend production build
|
|
|
|
```bash
|
|
cd frontend
|
|
~/.bun/bin/bun run build
|
|
```
|
|
|
|
## Quality Checks
|
|
|
|
Run both before pushing:
|
|
|
|
```bash
|
|
./scripts/check_python_quality.sh
|
|
./scripts/check_frontend_quality.sh
|
|
```
|
|
|
|
## Product/Data Model Background
|
|
|
|
- Public non-fork repos are scanned.
|
|
- A repo with `/lessons/` is treated as a course repo.
|
|
- A repo with `/blogs/` is treated as a post repo.
|
|
- Lessons are discovered from `lessons/<chapter>/<lesson>/`.
|
|
- Each lesson folder is expected to contain one markdown file plus optional assets.
|
|
- Frontmatter is used when present for `title` and `summary`.
|
|
- Discussions are loaded from Forgejo issues and comments.
|
|
- Issue bodies are scanned for canonical post/lesson URLs and Forgejo file URLs to connect discussions back to content.
|
|
- Calendar events are loaded from ICS feeds, not managed in-app.
|
|
|
|
## UI Expectations
|
|
|
|
- The UI should not expose Forgejo as a user-facing implementation detail unless necessary for debugging.
|
|
- Course cards should open course pages.
|
|
- Lesson rows should open lesson pages.
|
|
- Discussion pages should focus on one thread at a time.
|
|
- Markdown should render as readable content, not raw source.
|
|
|
|
## Push Workflow
|
|
|
|
The site source repo currently lives at:
|
|
|
|
- `git@aksal.cloud:Robot-U/robot-u-site.git`
|
|
|
|
Typical push flow:
|
|
|
|
```bash
|
|
git status
|
|
git add ...
|
|
git commit -m "..."
|
|
git push origin main
|
|
```
|