atlas-academy/docs/ARCHITECTURE.md
Atlas Developer 03829a38b2 feat: Atlas Academy — Odoo eLearning platform, full fusion
9-course Dutch e-learning platform fused onto atlasacademy.nl via Caddy
reverse proxy. Odoo 19 Community as course engine (website_slides), static
HTML for marketing front. Single Odoo account system.

- static/: 8 marketing pages (index, pricing, coaching, leerpad, over, shop, bisl, esf)
- backend/odoo_relay.py: lead relay Flask service (POST /academy-lead → Odoo CRM)
- caddy/academy.caddyfile: full Caddy config with Odoo proxy + auth rewrites
- docs/: ARCHITECTURE, USERFLOW, COURSES, DEPLOYMENT, SECURITY, ODOO

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 00:48:45 +02:00

124 lines
5.7 KiB
Markdown

# Architectuur — Atlas Academy
## Overzicht
Atlas Academy is een **gefused platform**: één domein (`atlasacademy.nl`), twee lagen — statische HTML voor marketing, Odoo eLearning voor de cursusengine. Caddy verbindt beide transparant.
## Componenten
### 1. Caddy (reverse proxy + static server)
- Host: `atlas-01` (Hetzner CPX32, 178.105.85.200)
- Config: `/etc/caddy/Caddyfile`
- Rol: TLS terminatie, static files serveren, Odoo proxyen
```
atlasacademy.nl, www.atlasacademy.nl {
root * /var/www/atlasacademy.nl
encode gzip
@odoo_elearning path /slides /slides/* /web/assets/* /web/image/*
/web/static/* /website_slides/* /web/session/*
/web/dataset/call_kw* /web/login* /web/signup*
/web/reset_password*
route @odoo_elearning {
reverse_proxy 100.93.16.81:8069 {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto https
}
}
redir /cursussen /slides 302
redir /login /web/login?redirect=%2Fslides 302
redir /register /web/signup?redirect=%2Fslides 302
file_server
}
```
**Kritisch:** `header_up X-Forwarded-Host {host}` is verplicht. Odoo (`proxy_mode=True`) leest de website-routing uit `X-Forwarded-Host`. Zonder dit serveert Odoo altijd website 1 (corp) in plaats van website 3 (academy).
### 2. Statische marketinglaag
- Pad: `/var/www/atlasacademy.nl/`
- Pagina's: `index.html`, `pricing.html`, `coaching.html`, `leerpad.html`, `over.html`, `shop.html`, `bisl.html`, `esf.html`
- Stijl: dark theme (`--bg: hsl(222,48%,8%)`), Atlas blue (`#2E80FF`), gold (`#D4A24C`)
- GA4: `G-JBWZWZMKBC` + rollup `GT-MR2TH3RQ` in `<head>` van alle pagina's
### 3. Odoo 19 Community (eLearning)
- Container: `atlas-odoo` (Docker op atlas-01)
- Database: `atlas`
- Interne URL: `http://localhost:8069` (op atlas-01) / `http://100.93.16.81:8069` (tailnet)
- Modules: `website_slides`, `website`, `crm`, `auth_signup`
- Website 3: "Atlas Academy", `domain='https://atlasacademy.nl'`
- Website 1: "Atlas Corporation", `domain=False` (default fallback)
**Multi-website routing:** Odoo leest `X-Forwarded-Host` en matcht op `website.domain`. `_get_current_website_id` is ORM-gecached — na website-aanmaken altijd `docker restart atlas-odoo`.
### 4. Lead Relay (`odoo_relay.py`)
- Service: `atlas-academy-relay` (systemd)
- Bindt op: `127.0.0.1:7793`
- Caddy proxiet: `/academy-lead → 127.0.0.1:7793`
- Input: `POST {name, email, interest, source}`
- Actie: maakt `crm.lead` aan in Odoo + email-fallback via SMTP
- Secrets: `/etc/atlas/academy-relay.env` (root 600)
## Datamodel (ERD)
```
┌─────────────┐ ┌──────────────────┐ ┌───────────────┐
│ res.users │────<│ slide.channel │────<│ slide.slide │
│ (Odoo) │ │ (cursus) │ │ (les/sectie) │
│ │ │ │ │ │
│ name │ │ name │ │ name │
│ email │ │ website_id = 3 │ │ html_content │
│ password │ │ website_slug │ │ slide_categ. │
│ partner_id │ │ cover_properties│ │ is_category │
└─────────────┘ │ auth_signup_inv.│ │ sequence │
└──────────────────┘ └───────┬───────┘
┌───────▼───────┐
│ slide.question │
│ (quizvraag) │
│ question │
│ slide_id │
└───────┬───────┘
┌───────▼───────┐
│ slide.answer │
│ text_value │
│ is_correct │
│ comment │
└───────────────┘
┌──────────────┐
│ crm.lead │ ← aangemaakt via odoo_relay.py
│ name │
│ email_from │
│ description │
│ source │
└──────────────┘
```
## Omgevingsvariabelen
| Bestand | Variabele | Gebruik |
|---------|-----------|---------|
| `/etc/atlas/academy-relay.env` | `ODOO_RELAY_LOGIN` | XML-RPC login voor lead-relay |
| `/etc/atlas/academy-relay.env` | `ODOO_RELAY_PASS` | XML-RPC wachtwoord |
| `/etc/atlas/academy-relay.env` | `ACADEMY_ADMIN_PASS` | Beheerder-endpoint authenticatie |
| `/etc/atlas/academy-relay.env` | `LEAD_SMTP_PASS` | Gmail app-wachtwoord voor email-fallback |
Alle bestanden: `root:root 600`. Nooit in source committen.
## Deployment diagram
```
[Dev/Operator]
├── scp *.html → atlas-01:/var/www/atlasacademy.nl/
├── scp script.py → atlas-01:/tmp/
│ ssh atlas-01 "docker exec -i atlas-odoo odoo shell -d atlas --no-http < /tmp/script.py"
└── caddy reload --config /etc/caddy/Caddyfile (na Caddyfile-wijziging)
```