# Manuel Technique — Plateforme ACX
**Version** : 1.0.0  
**Date** : Avril 2026  
**Auteur** : ACREMAC  
**Confidentialité** : Usage interne

---

## Table des matières

1. [Vue d'ensemble de l'architecture](#1-vue-densemble-de-larchitecture)
2. [Backend Django](#2-backend-django)
3. [Frontend Next.js](#3-frontend-nextjs)
4. [Infrastructure de production](#4-infrastructure-de-production)
5. [Authentification & Sécurité](#5-authentification--sécurité)
6. [Base de données](#6-base-de-données)
7. [Déploiement & Mise à jour](#7-déploiement--mise-à-jour)
8. [Variables d'environnement](#8-variables-denvironnement)
9. [Monitoring & Maintenance](#9-monitoring--maintenance)
10. [API Reference](#10-api-reference)

---

## 1. Vue d'ensemble de l'architecture

### Schéma global

```
Internet
    │
    ▼
[Apache2 / SSL DigiCert *.acx-acremac.net]
    │
    ├─── acx-acremac.net  ──────► [Gunicorn] ──► [Django 4.2]
    │                                                   │
    │                                               [PostgreSQL]
    │
    └─── app.acx-acremac.net ───► [PM2 / Node.js] ──► [Next.js 16]
```

### Composants principaux

| Composant | Technologie | Version | Rôle |
|-----------|------------|---------|------|
| API Backend | Django + DRF | 4.2.7 | Logique métier, API REST |
| Frontend | Next.js | 16.0.10 | Interface utilisateur SPA/SSR |
| Base de données | PostgreSQL | 16 | Persistance des données |
| Serveur web | Apache2 | 2.4.58 | Reverse proxy + SSL |
| Process manager | PM2 | — | Gestion processus Node.js |
| WSGI server | Gunicorn | 21.2.0 | Serveur WSGI Python |

### Domaines

| Domaine | Service | Description |
|---------|---------|-------------|
| `acx-acremac.net` | Backend Django | API REST + Admin Django |
| `app.acx-acremac.net` | Frontend Next.js | Application web |

---

## 2. Backend Django

### Structure des modules

```
acx/                          ← Racine du projet
├── acx/
│   ├── settings.py           ← Paramètres développement
│   ├── settings_prod.py      ← Paramètres production (django-environ)
│   └── urls.py               ← Routage principal
├── accounts/                 ← Gestion utilisateurs, rôles, memberships, audit
├── tenancy/                  ← Multi-tenancy : modèle Tenant, dashboard super admin
├── cases/                    ← Dossiers de recouvrement, débiteurs, portfolios
├── customers/                ← Clients (créanciers), tickets support
├── collections_management/   ← Cycle de recouvrement, paiements, emails
├── treasury_management/      ← Comptabilité : comptes, mouvements, reversements
├── templates/emails/         ← Templates HTML/texte emails transactionnels
└── deploy/                   ← Fichiers de déploiement (Apache, systemd, scripts)
```

### Modèles de données clés

#### Tenant
```
Tenant
├── name, slug, legal_name, industry
├── contact_name, email, phone, website
├── country, city, timezone, locale, currency
├── status (active | suspended)
├── plan (starter | business | enterprise)
└── created_at, updated_at
```

#### User / Membership
```
User (AbstractUser)
├── email (unique), telephone, departement
└── must_change_password

Membership
├── tenant → Tenant
├── user → User
├── roles → Role[]
├── status (invited | active | suspended)
└── is_owner
```

#### Case (Dossier)
```
Case
├── tenant, portfolio, debtor, customer
├── reference (unique par tenant)
├── status (open | in_progress | closed | cancelled)
├── original_amount, balance_amount, currency
├── opened_at, closed_at, due_date
└── priority, metadata
```

#### CollectionCase
```
CollectionCase
├── case → Case
├── status (new | contacted | promised | paid | disputed | closed)
├── assigned_to → User
└── actions[], emails[], payments[]
```

### Endpoints API principaux

| Méthode | Endpoint | Description |
|---------|----------|-------------|
| POST | `/api/auth/token/` | Obtenir JWT (admin/agent) |
| POST | `/api/auth/token/refresh/` | Renouveler le JWT |
| GET | `/api/auth/me/` | Profil utilisateur connecté |
| GET/POST | `/api/tenants/` | Gestion des tenants (superuser) |
| GET | `/api/admin-dashboard/` | Stats dashboard super admin |
| GET/POST | `/api/cases/` | Dossiers du tenant |
| GET/POST | `/api/collection-cases/` | Dossiers de recouvrement |
| GET/POST | `/api/payments/` | Paiements |
| GET/POST | `/api/treasury-accounts/` | Comptes trésorerie |
| GET/POST | `/api/treasury-movements/` | Mouvements financiers |
| GET | `/api/treasury-movements/summary/` | Résumé financier |
| GET/POST | `/api/remittances/` | Reversements clients |
| GET/POST | `/api/customers/` | Clients (créanciers) |

### Permissions

| Rôle | Valeur | Droits |
|------|--------|--------|
| Personnel entreprise | 1 | Lecture seule |
| Personnel ACREMAC | 2 | Lecture + écriture |
| Administrateur entreprise | 3 | Gestion tenant |
| Administrateur | 4 | Gestion complète |
| Superuser Django | — | Accès total + dashboard super admin |

---

## 3. Frontend Next.js

### Structure des routes

```
app/[locale]/
├── (public)/
│   └── login/               ← Connexion admin/agent
├── (app)/                   ← Espace tenant (agents/admins)
│   ├── dashboard/           ← Tableau de bord
│   ├── cases/               ← Dossiers
│   ├── collections/cases/   ← Recouvrement
│   ├── customers/           ← Clients
│   ├── communications/      ← Messagerie
│   ├── portfolio/           ← Portfolios
│   └── treasury/            ← Trésorerie
├── (admin)/admin/           ← Super administration
│   ├── page.tsx             ← Dashboard super admin (données API réelles)
│   ├── tenants/             ← Gestion tenants
│   ├── users/               ← Gestion utilisateurs
│   └── security/            ← RBAC
└── (client)/client/         ← Portail client (débiteurs)
    ├── dashboard/
    ├── cases/
    ├── messages/
    └── support/
```

### Architecture des services API

```
src/lib/api/
├── client.ts        ← Fetch wrapper avec refresh JWT automatique
├── auth.ts          ← Login / logout / refresh
├── storage.ts       ← Stockage tokens (localStorage)
├── admin.ts         ← Dashboard super admin
├── treasury.ts      ← Trésorerie
└── ...
```

### Internationalisation

- Langues supportées : **fr** (défaut), **en**
- Fichiers de traductions : `messages/fr.json`, `messages/en.json`
- Librairie : `next-intl`

### Variables d'environnement frontend

```env
NEXT_PUBLIC_API_BASE_URL=https://acx-acremac.net/api
```

---

## 4. Infrastructure de production

### Serveur

| Paramètre | Valeur |
|-----------|--------|
| OS | Ubuntu 24.04 LTS |
| IP | 198.46.170.30 |
| CPU | 1 vCPU |
| RAM | 2 GB |
| Stockage | 40 GB SSD |

### Apache2 — Virtual Hosts

#### Backend (`/etc/apache2/sites-available/acx.conf`)
```apache
<VirtualHost *:443>
    ServerName acx-acremac.net
    SSLEngine on
    SSLCertificateFile    /etc/ssl/acx/acx-acremac.crt
    SSLCertificateKeyFile /etc/ssl/acx/acx-acremac.key

    ProxyPass /static/ !
    Alias /static/ /var/www/html/acx/staticfiles/

    ProxyPass / unix:/run/acx-gunicorn.sock|http://localhost/
    ProxyPassReverse / unix:/run/acx-gunicorn.sock|http://localhost/
</VirtualHost>
```

#### Frontend (`/etc/apache2/sites-available/acx-app.conf`)
```apache
<VirtualHost *:443>
    ServerName app.acx-acremac.net
    SSLEngine on
    SSLCertificateFile    /etc/ssl/acx/acx-acremac.crt
    SSLCertificateKeyFile /etc/ssl/acx/acx-acremac.key

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
```

### Gunicorn — Service systemd

```
/etc/systemd/system/acx-gunicorn.service
├── WorkingDirectory=/var/www/html/acx
├── ExecStart=venv/bin/gunicorn acx.wsgi:application
│            --bind unix:/run/acx-gunicorn.sock
│            --workers 3
├── EnvironmentFile=/var/www/html/acx/.env
└── MPLBACKEND=Agg (headless matplotlib)
```

### PM2 — Next.js

```javascript
// deploy/pm2.config.js
{
  name: "acx-front",
  script: "node_modules/.bin/next",
  args: "start",
  cwd: "/var/www/html/front-acx",
  env: { NODE_ENV: "production", PORT: 3000 }
}
```

---

## 5. Authentification & Sécurité

### Flux JWT

```
Client → POST /api/auth/token/
       ← { access (30 min), refresh (30 jours) }

Client → GET /api/... + Authorization: Bearer <access>
       ← données

# Si 401 → refresh automatique côté frontend
Client → POST /api/auth/token/refresh/ + { refresh }
       ← { access }
```

### Portail client

Le portail client utilise un endpoint dédié :
```
POST /api/auth/client-portal/token/
```
Seuls les utilisateurs ayant une `CustomerMembership` active peuvent s'y connecter. Les admins/agents sont bloqués.

### Certificat SSL

- **Type** : DigiCert wildcard `*.acx-acremac.net`
- **Chemin** : `/etc/ssl/acx/`
- **Couverture** : `acx-acremac.net` + `app.acx-acremac.net`

### Mesures de sécurité en place

- Headers HTTP : `Strict-Transport-Security`, `X-Content-Type-Options`, `Referrer-Policy`
- HTTPS forcé via redirect HTTP → HTTPS
- CORS restreint aux origines autorisées
- JWT avec rotation automatique
- `DEBUG=False` en production
- Variables sensibles dans `.env` (exclu du git)

---

## 6. Base de données

### Connexion

```
Host     : 127.0.0.1
Port     : 5432
Database : acx_db
User     : acx_user
```

### Accès distant (pgAdmin via SSH tunnel)

```bash
ssh -L 5433:127.0.0.1:5432 root@198.46.170.30
# Puis dans pgAdmin : host=127.0.0.1, port=5433
```

### Migrations

Les migrations sont **générées en production** (pas versionnées dans git).

```bash
cd /var/www/html/acx
source venv/bin/activate
export DJANGO_SETTINGS_MODULE=acx.settings_prod
python manage.py makemigrations
python manage.py migrate
```

---

## 7. Déploiement & Mise à jour

### Mise à jour backend

```bash
cd /var/www/html/acx
git pull
source venv/bin/activate
export DJANGO_SETTINGS_MODULE=acx.settings_prod
pip install -r requirements.txt
python manage.py migrate
python manage.py collectstatic --noinput
systemctl restart acx-gunicorn
```

### Mise à jour frontend

```bash
cd /var/www/html/front-acx
git pull
npm install
npm run build
pm2 restart acx-front
```

### Script automatisé (backend)

```bash
bash /var/www/html/acx/deploy/update.sh
```

---

## 8. Variables d'environnement

### Backend (`.env`)

```env
# Django
SECRET_KEY=<clé-secrète-aléatoire>
DEBUG=False
ALLOWED_HOSTS=acx-acremac.net,www.acx-acremac.net,app.acx-acremac.net,198.46.170.30

# Base de données (encoder les caractères spéciaux : @ → %40, $ → %24)
DATABASE_URL=postgres://acx_user:<password>@127.0.0.1:5432/acx_db

# CORS
CORS_ALLOWED_ORIGINS=https://acx-acremac.net,https://app.acx-acremac.net

# Email SMTP
EMAIL_HOST=<smtp-host>
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=acx@acremac.com
EMAIL_HOST_PASSWORD=<password>
DEFAULT_FROM_EMAIL=acx@acremac.com

# URLs
FRONTEND_BASE_URL=https://app.acx-acremac.net
FRONTEND_CLIENT_PORTAL_BASE_URL=https://app.acx-acremac.net/fr

# Settings Django
DJANGO_SETTINGS_MODULE=acx.settings_prod
```

### Frontend (`.env.production`)

```env
NEXT_PUBLIC_API_BASE_URL=https://acx-acremac.net/api
```

---

## 9. Monitoring & Maintenance

### Commandes utiles

```bash
# Statut des services
systemctl status acx-gunicorn
pm2 status

# Logs en temps réel
journalctl -u acx-gunicorn -f
pm2 logs acx-front --lines 100

# Logs Apache
tail -f /var/log/apache2/acx-error.log
tail -f /var/log/apache2/acx-access.log

# Redémarrage complet
systemctl restart acx-gunicorn
pm2 restart acx-front
systemctl reload apache2
```

### Sauvegardes base de données

```bash
# Export
pg_dump -U acx_user -h 127.0.0.1 acx_db > backup_$(date +%Y%m%d).sql

# Import
psql -U acx_user -h 127.0.0.1 acx_db < backup_20260101.sql
```

### Alertes à surveiller

| Indicateur | Seuil d'alerte |
|------------|----------------|
| Mémoire Gunicorn | > 512 MB par worker |
| Espace disque | < 20% libre |
| Uptime PM2 | redémarrages fréquents |
| Logs Apache | erreurs 500 répétées |

---

## 10. API Reference

### Authentification

Toutes les requêtes authentifiées requièrent :
```
Authorization: Bearer <access_token>
```

### Codes de réponse

| Code | Signification |
|------|--------------|
| 200 | Succès |
| 201 | Créé |
| 204 | Supprimé (no content) |
| 400 | Données invalides |
| 401 | Non authentifié / Token expiré |
| 403 | Accès refusé |
| 404 | Ressource introuvable |
| 500 | Erreur serveur |

### Format des erreurs

```json
{
  "detail": "Message d'erreur lisible",
  "code": "error_code",
  "messages": [...]
}
```

### Pagination

Les listes paginées retournent :
```json
{
  "count": 150,
  "next": "https://acx-acremac.net/api/cases/?page=2",
  "previous": null,
  "results": [...]
}
```

---

*Document généré par ACREMAC — Toute reproduction à des fins commerciales est interdite.*
