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

5.7 KiB

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)