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>
124 lines
5.7 KiB
Markdown
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)
|
|
```
|