Table of Contents
Documentation DAREWATCH¶
Bienvenue ! Cette documentation couvre tout ce qu'il faut savoir pour travailler sur le projet DAREWATCH.
Sujets couverts¶
- Introduction — Présentation, architecture, organisation du monorepo
- Démarrage — Prérequis, installation, variables d'environnement
- Services — Détail des 3 applications (Group, Tech, Immo)
- Infrastructure — Docker, Nginx, certificats, déploiement
- API Backend — Conventions, endpoints tech/immo, audit dynamique
- Commandes — Toutes les commandes CLI par catégorie
- SEO — Stratégie référencement multi-apps
- FAQ — Réponses aux questions courantes
Les 3 applications¶
| App | Tech | URL local | Git path |
|---|---|---|---|
| Group | Laravel/PHP | http://localhost:8002 | apps/drwh_group/ |
| Tech | Next.js | http://localhost:3000 | apps/drwh_tech/ |
| Immo | Next.js | http://localhost:3001 | apps/drwh_immo/ |
Navigation rapide¶
| Besoin | Aller à |
|---|---|
| Je suis nouveau | Présentation |
| Comment ça marche ? | Architecture |
| Je veux installer | Installation |
| Je dois déployer | Docker & Vercel |
| Je suis dev backend | Conventions API |
| Je cherche les endpoints | API Tech ou API Immo |
| Question ? | FAQ |
Bon développement ! 🚀
Introduction
Présentation de DAREWATCH CONSULTING SARL¶
L'entreprise¶
DAREWATCH CONSULTING SARL est une entreprise camerounaise dont les bureaux se trouvent à Douala, Bonamoussadi. Elle opère dans plusieurs domaines : la technologie, l'immobilier et la formation.
Localisation
Siège social : Douala, Bonamoussadi — Cameroun
Sites web : tech.darewatchgroup.com / immo.darewatchgroup.com / darewatchgroup.com
Les trois pôles de l'entreprise¶
L'entreprise possède trois pôles (divisions), chacun ayant son propre site web et sa propre équipe.
graph LR
D[DAREWATCH\nCONSULTING SARL] --> G[🏠 Darewatch Group\nLanding principale\nLaravel/PHP]
D --> T[💻 Darewatch Tech\nDivision Technologie\nNext.js]
D --> I[🏗️ Darewatch Immo\nDivision Immobilier\nNext.js]
style D fill:#0066FF,color:#fff,stroke:#004E89
style G fill:#e74c3c,color:#fff
style T fill:#27ae60,color:#fff
style I fill:#f39c12,color:#fff
| Pôle | Nom du site | Technologies | URL | Rôle principal |
|---|---|---|---|---|
| 🏠 Principal | Darewatch Group | Laravel + PHP + Livewire | darewatchgroup.com | Vitrine principale, routing vers tech/immo |
| 💻 Technologie | Darewatch Tech | Next.js + React + TypeScript | tech.darewatchgroup.com | Services IT, formations, blog tech, carrières |
| 🏗️ Immobilier | Darewatch Immo | Next.js + React + TypeScript | immo.darewatchgroup.com | Biens immobiliers, projets, lotissements |
Les domaines d'activité¶
-
Technologie Développement web et mobile (React, Next.js, React Native, Flutter) - Conseil et transformation digitale - Infrastructure réseau et cloud computing - Cybersécurité et audit de sécurité - DevOps et infogérance - Data engineering et Intelligence Artificielle - Formations : développement web, DevOps, cybersécurité
-
Immobilier - Vente de villas et appartements - Projets de construction - Lotissements (terrains découpés à vendre) - Accompagnement à l'acquisition immobilière - Promotion immobilière au Cameroun
-
Groupe - Présentation corporative de l'entreprise - Point d'entrée vers les deux divisions - Contact général de l'entreprise - Articles et actualités transversales
Pourquoi trois sites distincts ?¶
Bonne question !
Pourquoi ne pas avoir fait un seul grand site ?
Réponse : Chaque pôle a des besoins très différents :
- Darewatch Tech a besoin d'un site rapide, moderne, avec un blog technique et des pages de services complexes.
- Darewatch Immo a besoin d'un catalogue de biens, de pages de projets détaillées, de formulaires de demande.
- Darewatch Group est une landing page simple qui sert de porte d'entrée.
En séparant les sites, chaque équipe peut travailler indépendamment, déployer à son rythme, et utiliser la technologie la mieux adaptée.
C'est le principe des microservices : des composants indépendants qui coopèrent.
En savoir plus sur l'architecture microservices →
Organisation du code source¶
Tout le code est regroupé dans un seul dépôt appelé monorepo drwh_front.
drwh_front/ ← Racine du monorepo
├── apps/
│ ├── drwh_group/ ← Site principal (Laravel/PHP)
│ ├── drwh_tech/ ← Site Division Tech (Next.js)
│ ├── drwh_tech-e2e/ ← Tests automatisés de drwh_tech
│ ├── drwh_immo/ ← Site Division Immo (Next.js)
│ └── drwh_immo-e2e/ ← Tests automatisés de drwh_immo
├── docs/ ← Cette documentation
├── infra/ ← Configuration Nginx & certificats
├── scripts/ ← Scripts utilitaires (Vercel, etc.)
├── package.json ← Dépendances JavaScript globales
└── nx.json ← Configuration NX (chef d'orchestre)
En savoir plus sur le monorepo & NX →
Liens complémentaires¶
Architecture Microservices¶
C'est quoi un microservice ?¶
Explication simple : Imaginez un centre commercial. Au lieu d'avoir un seul grand magasin qui vend de tout, on a plusieurs boutiques indépendantes côte à côte. Si une boutique ferme ou change son assortiment, les autres continuent de fonctionner normalement. C'est exactement comme ça que fonctionne l'architecture microservices.
Dans notre projet, chaque site (Group, Tech, Immo) est un service indépendant. Chacun peut :
- ✅ Être démarré ou arrêté séparément
- ✅ Utiliser sa propre technologie
- ✅ Être déployé (mis en ligne) indépendamment
- ✅ Avoir sa propre base de données si nécessaire
- ✅ Évoluer sans impacter les autres services
Microservices vs Monolithe — comparaison¶
graph TB
subgraph Monolithe["❌ Architecture Monolithe (une seule app)"]
M[Application unique\nTout dans le même code\nUn seul déploiement\nErreur = tout tombe]
end
subgraph Micro["✅ Architecture Microservices (Darewatch)"]
S1[drwh_group\nLaravel]
S2[drwh_tech\nNext.js]
S3[drwh_immo\nNext.js]
S1 -.Indépendant.- S2
S2 -.Indépendant.- S3
end
style Monolithe fill:#ffebee,stroke:#e74c3c
style Micro fill:#e8f5e9,stroke:#27ae60
style M fill:#e74c3c,color:#fff
style S1 fill:#27ae60,color:#fff
style S2 fill:#27ae60,color:#fff
style S3 fill:#27ae60,color:#fff
| Critère | Monolithe | Microservices (Darewatch) |
|---|---|---|
| Déploiement | Un seul déploiement pour tout | Chaque service se déploie séparément |
| Panne | Si une erreur survient, tout tombe | Une panne sur immo n'affecte pas tech |
| Scalabilité | On scale tout même si seulement une partie est surchargée | On scale uniquement le service surchargé |
| Technologies | Une seule technologie pour tout | Chaque service choisit sa technologie |
| Équipes | Toute l'équipe sur le même code | Chaque équipe travaille sur son service |
Architecture complète de DAREWATCH¶
graph TD
User([👤 Visiteur]) --> GW[🔀 Nginx Gateway\nReverse Proxy\nPort 80 / 443]
GW -->|darewatchgroup.com| G[🏠 drwh_group\nLaravel/PHP\nPort 3001]
GW -->|tech.darewatchgroup.com| T[💻 drwh_tech\nNext.js\nPort 3003]
GW -->|immo.darewatchgroup.com| I[🏗️ drwh_immo\nNext.js\nPort 3002]
G -->|REST/JSON| API[🔧 API Backend\nhttp://api.darewatch.com]
T -->|REST/JSON| API
I -->|REST/JSON| API
API --> DB[(🗄️ Base de données)]
style User fill:#e8f4f8,stroke:#2196F3
style GW fill:#2d2e2e,color:#fff,stroke:#555
style G fill:#e74c3c,color:#fff
style T fill:#0066FF,color:#fff
style I fill:#27ae60,color:#fff
style API fill:#8e44ad,color:#fff
style DB fill:#f39c12,color:#fff
Flux d'une requête utilisateur¶
Lorsqu'un visiteur accède à tech.darewatchgroup.com, voici ce qui se passe :
sequenceDiagram
participant U as 👤 Visiteur
participant N as 🔀 Nginx
participant T as 💻 drwh_tech
participant A as 🔧 API Backend
U->>N: GET https://tech.darewatchgroup.com/services
N->>T: Redirige vers drwh_tech:3003
T->>A: GET /api/v1/services
A-->>T: JSON { services: [...] }
T-->>N: Rendu HTML de la page services
N-->>U: Page HTML finale
Pourquoi cette architecture pour Darewatch ?¶
!!! success "Avantages concrets" - L'équipe immo peut mettre à jour le catalogue immobilier sans toucher au site tech - Si le site immo a une panne, le site tech reste opérationnel - On peut scaler (augmenter les ressources de) uniquement le service le plus sollicité - Chaque service peut utiliser la technologie qui lui convient le mieux
!!! warning "Points d'attention" - La communication entre services se fait via l'API (couplage léger) - Il faut maintenir une API contract claire entre les équipes - Le déploiement est légèrement plus complexe (d'où Docker et Nginx)
Les ports de chaque service en local¶
| Service | URL locale | Port |
|---|---|---|
| drwh_group | http://localhost:8002 | 8000 / 8002 |
| drwh_tech | http://localhost:4201 | 4201 |
| drwh_immo | http://localhost:4200 | 4200 |
| API Backend | http://localhost:3000/api | 3000 |
Liens complémentaires¶
Monorepo & NX¶
C'est quoi un monorepo ?¶
Explication simple : Un monorepo, c'est comme une grande boîte où l'on range tous les projets ensemble. Au lieu d'avoir 3 dossiers séparés sur votre ordinateur (un pour group, un pour tech, un pour immo), tout est au même endroit. C'est plus facile à gérer et à synchroniser.
Polyrepo vs Monorepo — comparaison¶
graph TB
subgraph polyrepo["❌ Polyrepo (3 dépôts séparés)"]
R1[repo: drwh_group]
R2[repo: drwh_tech]
R3[repo: drwh_immo]
end
subgraph monorepo["✅ Monorepo (drwh_front)"]
M[drwh_front/\ndrwh_group\ndrwh_tech\ndrwh_immo]
end
style polyrepo fill:#ffebee,stroke:#e74c3c
style monorepo fill:#e8f5e9,stroke:#27ae60
style R1 fill:#e74c3c,color:#fff
style R2 fill:#e74c3c,color:#fff
style R3 fill:#e74c3c,color:#fff
style M fill:#27ae60,color:#fff
| Critère | Polyrepo | Monorepo (drwh_front) |
|---|---|---|
| Gestion des versions | Chaque repo a sa propre version | Version unifiée pour tous les services |
| Partage de code | Complexe (packages npm privés…) | Facile (import direct depuis lib partagée) |
| Refactoring | Pénible (modifier 3 repos) | Simple (un seul endroit) |
| CI/CD | Pipeline séparé par repo | Un seul pipeline, build intelligent |
| Découverte du code | Chercher dans 3 repos | Tout dans un seul dossier |
Structure du monorepo drwh_front¶
drwh_front/ ← Racine du monorepo
│
├── apps/ ← Les applications
│ ├── drwh_group/ ← Site Group (Laravel/PHP)
│ ├── drwh_tech/ ← Site Tech (Next.js)
│ ├── drwh_tech-e2e/ ← Tests end-to-end de drwh_tech
│ ├── drwh_immo/ ← Site Immo (Next.js)
│ └── drwh_immo-e2e/ ← Tests end-to-end de drwh_immo
│
├── docs/ ← Cette documentation (MkDocs)
│
├── infra/ ← Infrastructure
│ └── nginx/ ← Configuration Nginx
│ ├── nginx.conf
│ ├── conf.d/
│ ├── certs/ ← Certificats TLS
│ └── www/ ← Webroot ACME
│
├── scripts/ ← Scripts utilitaires
│ └── vercel-build.js ← Build Vercel
│
├── nx.json ← Configuration NX
├── package.json ← Dépendances JS globales (racine)
├── tsconfig.base.json ← TypeScript partagé
├── docker-compose.yml ← Orchestration Docker
├── Dockerfile.tech ← Image Docker drwh_tech
├── Dockerfile.immo ← Image Docker drwh_immo
└── Dockerfile.group ← Image Docker drwh_group
NX : le chef d'orchestre¶
Explication simple : NX, c'est comme un chef d'orchestre dans un concert. Les musiciens (les services) jouent chacun leur partition, mais c'est le chef qui dit "maintenant vous démarrez", "maintenant vous vous arrêtez", "maintenant vous passez en production".
graph TD
NX[🎼 NX\nChef d'orchestre] -->|nx run drwh_tech:serve| T[💻 drwh_tech]
NX -->|nx run drwh_immo:build| I[🏗️ drwh_immo]
NX -->|nx run drwh_group:serve| G[🏠 drwh_group]
NX -->|nx affected --target=test| Tests[🧪 Tests intelligents\nSeulement ce qui a changé]
NX -->|nx graph| Graph[📊 Graphe des dépendances\nentre projets]
style NX fill:#0066FF,color:#fff,stroke:#004E89
style T fill:#27ae60,color:#fff
style I fill:#f39c12,color:#fff
style G fill:#e74c3c,color:#fff
style Tests fill:#8e44ad,color:#fff
style Graph fill:#2d2e2e,color:#fff
Ce que NX permet de faire¶
| Fonctionnalité | Description | Commande exemple |
|---|---|---|
| Servir | Lancer un service en mode développement | npx nx serve drwh_tech |
| Builder | Compiler pour la production | npx nx build drwh_immo |
| Tester | Lancer les tests unitaires | npx nx test drwh_tech |
| Linter | Vérifier la qualité du code | npx nx lint drwh_immo |
| Cache intelligent | Ne refait que ce qui a changé | Automatique |
| Graphe | Visualiser les dépendances | npx nx graph |
| Build affecté | Build uniquement les projets impactés | npx nx affected --target=build |
Le fichier nx.json¶
C'est le fichier de configuration principal de NX, situé à la racine du monorepo.
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"defaultBase": "main",
"targetDefaults": {
"build": {
"cache": true,
"dependsOn": ["^build"]
},
"test": {
"cache": true
}
}
}
Le cache NX
NX garde en cache les résultats des builds et tests. Si vous n'avez rien modifié dans un service, NX ne le rebuild pas — il utilise le cache. Cela accélère considérablement les déploiements.
Pour vider le cache : `npx nx reset`
Le fichier project.json¶
Chaque service a son propre fichier project.json qui décrit comment NX doit le gérer.
Exemple pour drwh_tech :
{
"name": "drwh_tech",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/drwh_tech/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nx/next:build",
"options": {
"outputPath": "dist/apps/drwh_tech"
}
},
"serve": {
"executor": "@nx/next:server",
"options": {
"buildTarget": "drwh_tech:build",
"port": 4201
}
}
}
}
Commandes NX essentielles¶
````bash # Lancer tous les services npm run dev
# Lancer un service spécifique
npx nx serve drwh_tech
npx nx serve drwh_immo
# Lancer drwh_group (Laravel, via npm script)
npm run dev:group
```
```bash # Builder tous les services npm run build
# Builder un seul service
npx nx build drwh_tech
npx nx build drwh_immo
# Builder seulement les services affectés par les changements
npx nx affected --target=build
```
```bash # Tous les tests npm run test
# Tests d'un service
npx nx test drwh_tech
# Tests end-to-end
npx nx e2e drwh_tech-e2e
```
```bash # Vider le cache NX (si comportement bizarre) npx nx reset
# Voir le graphe des dépendances (ouvre dans le navigateur)
npx nx graph
# Lister tous les projets du workspace
npx nx show projects
```
Liens complémentaires¶
Démarrage
Prérequis¶
Avant de pouvoir lancer le projet en local, vous devez installer plusieurs outils sur votre machine.
Bonne nouvelle
Tous ces outils sont gratuits et disponibles sur Windows, macOS et Linux.
Outils requis¶
| Outil | Version minimale | Rôle dans le projet | Téléchargement |
|---|---|---|---|
| Node.js | v18+ | Exécution de JavaScript/TypeScript (Tech & Immo) | nodejs.org |
| npm | v9+ | Gestionnaire de paquets JavaScript | Inclus avec Node.js |
| PHP | v8.2+ | Langage du service drwh_group (Laravel) | php.net |
| Composer | v2+ | Gestionnaire de paquets PHP | getcomposer.org |
| Git | Dernière version | Gestion du code source | git-scm.com |
| Docker | Dernière version | (Optionnel) Déploiement conteneurisé | docker.com |
Vérifier que les outils sont installés¶
Ouvrez un terminal (PowerShell sur Windows, Terminal sur macOS/Linux) et exécutez :
node --version # → v18.x.x ou supérieur
npm --version # → 9.x.x ou supérieur
php --version # → PHP 8.2.x ou supérieur
composer --version # → Composer 2.x.x
git --version # → git version 2.x.x
docker --version # → Docker version 24.x.x (si installé)
Si une commande n'est pas reconnue
Si le terminal affiche command not found ou n'est pas reconnu, l'outil n'est pas installé ou n'est pas dans le PATH.
Suivez les liens de téléchargement dans le tableau ci-dessus.
Installation sur Windows¶
=== "Node.js & npm" 1. Téléchargez l'installeur LTS sur nodejs.org 2. Exécutez l'installeur (acceptez toutes les options par défaut) 3. Vérifiez : node --version et npm --version
Option recommandée : XAMPP ou Laragon
- [Laragon](https://laragon.org/download/) : le plus simple pour Windows, inclut PHP 8.2+, MySQL, etc.
- Après installation, PHP est disponible dans le terminal via Laragon
**Option manuelle :**
1. Téléchargez PHP depuis [windows.php.net](https://windows.php.net/download/)
2. Ajoutez le dossier PHP à la variable d'environnement `PATH`
=== "Composer" 1. Téléchargez l'installeur depuis getcomposer.org 2. Exécutez Composer-Setup.exe 3. Vérifiez : composer --version
=== "Git" 1. Téléchargez depuis git-scm.com 2. Exécutez l'installeur (acceptez les options par défaut) 3. Vérifiez : git --version
Installation sur macOS¶
Si vous n'avez pas Homebrew, installez-le d'abord :
bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Ensuite, installez tout en une commande :
```bash
brew install node php composer git
```
bash
node --version
npm --version
php --version
composer --version
git --version
Configuration Git (première fois)¶
Avant d'utiliser Git, configurez votre identité :
Pourquoi ?
Git enregistre votre nom et email dans chaque commit que vous créez.
C'est ainsi que l'équipe sait qui a modifié quoi.
Éditeur de code recommandé¶
Nous recommandons Visual Studio Code (gratuit) :
code.visualstudio.com
Extensions recommandées pour ce projet :
| Extension | Utilité |
|---|---|
| ESLint | Vérification du code JavaScript/TypeScript |
| Prettier | Formatage automatique du code |
| PHP Intelephense | Autocomplétion PHP |
| Tailwind CSS IntelliSense | Autocomplétion Tailwind |
| GitLens | Voir l'historique Git directement dans le code |
Étape suivante¶
Une fois tous les outils installés, passez à :
Installation pas à pas¶
Prérequis
Avant de commencer, assurez-vous d'avoir installé tous les outils requis.
→ Voir la page Prérequis
Vue d'ensemble des étapes¶
flowchart LR
E1[1. Cloner\nle projet] --> E2[2. Installer les\ndépendances JS]
E2 --> E3[3. Installer\nComposer]
E3 --> E4[4. Configurer\n.env]
E4 --> E5[5. project.json\ndrwh_group]
E5 --> E6[6. Reset cache\nNX]
E6 --> OK[✅ Lancer\nnpm run dev]
style E1 fill:#0066FF,color:#fff
style E2 fill:#0066FF,color:#fff
style E3 fill:#0066FF,color:#fff
style E4 fill:#0066FF,color:#fff
style E5 fill:#0066FF,color:#fff
style E6 fill:#0066FF,color:#fff
style OK fill:#27ae60,color:#fff
Étape 1 — Cloner le projet¶
# Télécharger le code depuis le dépôt Git
git clone <URL_DU_DEPOT>
# Entrer dans le dossier racine du monorepo
cd drwh_front
URL du dépôt
L'URL du dépôt GitHub vous est communiquée par le responsable technique de l'équipe.
Étape 2 — Installer les dépendances JavaScript¶
Que fait cette commande ?
Elle télécharge toutes les bibliothèques JavaScript nécessaires pour que drwh_tech et drwh_immo fonctionnent. Les fichiers sont stockés dans le dossiernode_modules/.
Durée
La première installation peut prendre 2 à 5 minutes selon votre connexion internet.
Étape 3 — Installer les dépendances PHP (pour drwh_group)¶
# Entrer dans le dossier du service drwh_group
cd apps/drwh_group
# Installer les bibliothèques PHP
composer install
# Revenir à la racine du monorepo
cd ../..
Étape 4 — Configurer les variables d'environnement¶
→ Guide détaillé des variables d'environnement
Pour drwh_group (Laravel)¶
# Dans le dossier apps/drwh_group
cp apps/drwh_group/.env.example apps/drwh_group/.env
# Générer la clé de l'application Laravel
cd apps/drwh_group
php artisan key:generate
cd ../..
Ouvrez apps/drwh_group/.env et vérifiez ces valeurs :
Pour drwh_tech et drwh_immo (Next.js)¶
Créez un fichier .env.development à la racine du projet :
# À la racine du monorepo drwh_front
cp .env.example .env.development # ou créez le fichier manuellement
Contenu minimal du .env.development :
NEXT_PUBLIC_API_URL=http://localhost:3000/api
NEXT_PUBLIC_ENABLE_MOCKING=false
NEXT_PUBLIC_ENVIRONMENT=development
NEXT_PUBLIC_APP_VERSION=1.0.0
Étape 5 — Créer le project.json pour drwh_group¶
Pourquoi cette étape ?
NX a besoin d'un fichier project.json dans chaque service pour savoir comment le gérer.
Ce fichier n'est pas créé automatiquement pour les projets Laravel.
Créez le fichier apps/drwh_group/project.json avec ce contenu :
{
"name": "drwh_group",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/drwh_group",
"projectType": "application",
"targets": {
"serve": {
"executor": "nx:run-commands",
"options": {
"command": "php artisan serve --port=8002",
"cwd": "apps/drwh_group"
}
}
}
}
Étape 6 — Réinitialiser le cache NX¶
Pourquoi ?
NX garde en mémoire des informations sur les projets. Après avoir ajouté un nouveau service ou modifié project.json, il faut vider ce cache pour qu'il prenne en compte les nouvelles configurations.
Lancer les services en développement¶
Une fois l'installation complète, lancez tout le projet :
Ou lancer service par service¶
# Seulement le site Tech
npm run dev:tech
# Seulement le site Immo
npm run dev:immo
# Seulement le site Group (Laravel)
npm run dev:group
# ou directement
cd apps/drwh_group && php artisan serve
Accéder aux sites en local¶
| Service | URL | Port |
|---|---|---|
| drwh_group | http://localhost:8002 | 8002 |
| drwh_tech | http://localhost:4201 | 4201 |
| drwh_immo | http://localhost:4200 | 4200 |
Résolution de problèmes courants¶
??? question "npm run dev ne fonctionne pas" 1. Vérifiez que Node.js est bien installé : node --version 2. Assurez-vous d'avoir lancé npm install depuis la racine 3. Essayez npx nx reset puis relancez
??? question "composer install échoue" 1. Vérifiez que PHP 8.2+ est installé : php --version 2. Vérifiez que Composer est installé : composer --version 3. Si erreur d'extensions PHP manquantes, activez-les dans php.ini
La page s'affiche mais les données ne chargent pas
Vérifiez que NEXT_PUBLIC_API_URL est correctement configuré dans .env.development.
L'API backend doit être en cours d'exécution à l'URL configurée.
Erreur de permission sur Linux/macOS
bash
chmod -R 755 apps/drwh_group/storage
chmod -R 755 apps/drwh_group/bootstrap/cache
Étape suivante¶
Variables d'environnement¶
C'est quoi une variable d'environnement ?¶
Explication simple : Les variables d'environnement sont des réglages secrets (mots de passe, URLs de serveurs, clés API) que l'on stocke en dehors du code source. Chaque environnement (développement, staging, production) a ses propres valeurs.
Règle de sécurité absolue
Ne jamais committer un fichier .env sur Git. Ces fichiers contiennent des informations sensibles.
Les fichiers .env sont dans .gitignore — c'est intentionnel.
Vue d'ensemble des environnements¶
graph LR
DEV[".env.development\nDéveloppement local\nMocking activé\nAPI locale"] --> STG[".env.staging\nTests d'intégration\nAPI staging"] --> PROD[".env.production\nProduction live\nAPI officielle"]
style DEV fill:#27ae60,color:#fff
style STG fill:#f39c12,color:#fff
style PROD fill:#e74c3c,color:#fff
| Fichier | Usage | API URL |
|---|---|---|
.env.development |
Développement local | http://localhost:3000/api |
.env.staging |
Tests staging | https://api-staging.darewatch.com/api |
.env.production |
Production | https://api.darewatch.com/api |
Variables pour drwh_tech et drwh_immo (Next.js)¶
Fichier .env.development¶
# URL de l'API backend
NEXT_PUBLIC_API_URL=http://localhost:3000/api
# Activer le mode mock (données de démonstration)
# true = les appels API retournent des données fictives
# false = appels API réels
NEXT_PUBLIC_ENABLE_MOCKING=false
NEXT_PUBLIC_MOCK_DELAY=500
# Environnement
NEXT_PUBLIC_ENVIRONMENT=development
NEXT_PUBLIC_APP_VERSION=1.0.0
Fichier .env.staging¶
NEXT_PUBLIC_API_URL=https://api-staging.darewatch.com/api
NEXT_PUBLIC_ENABLE_MOCKING=false
NEXT_PUBLIC_ENVIRONMENT=staging
NEXT_PUBLIC_APP_VERSION=1.0.0
Fichier .env.production (ne jamais versionner)¶
NEXT_PUBLIC_API_URL=https://api.darewatch.com/api
NEXT_PUBLIC_ENABLE_MOCKING=false
NEXT_PUBLIC_ENVIRONMENT=production
NEXT_PUBLIC_APP_VERSION=1.5.0
Les variables NEXT_PUBLIC_
En Next.js, seules les variables préfixées par NEXT_PUBLIC_ sont accessibles côté navigateur.
Les variables sans ce préfixe sont uniquement accessibles côté serveur.
Variables pour drwh_group (Laravel)¶
Fichier apps/drwh_group/.env¶
APP_NAME=DrwhGroup
APP_ENV=local
APP_KEY= # Généré par: php artisan key:generate
APP_DEBUG=true
APP_URL=http://localhost:8002
APP_PORT=8002
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=drwh_group
DB_USERNAME=root
DB_PASSWORD=
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_FROM_ADDRESS="noreply@darewatch.com"
MAIL_FROM_NAME="${APP_NAME}"
Variables importantes de drwh_group¶
| Variable | Usage | Exemple |
|---|---|---|
APP_KEY |
Clé secrète Laravel (chiffrement sessions, cookies) | Générer avec php artisan key:generate |
APP_URL |
URL de l'application | http://localhost:8002 |
DB_* |
Configuration base de données | Selon votre MySQL local |
MAIL_* |
Configuration email | Mailtrap pour tests |
Mode Mock — données de démonstration¶
Le mode mock permet de travailler sans API backend réelle. Les données sont servies localement.
graph LR
APP[Application Next.js] -->|ENABLE_MOCKING=true| MOCK[🎭 Données Mock\nLocales]
APP -->|ENABLE_MOCKING=false| API[🔧 API Backend\nRéelle]
style MOCK fill:#f39c12,color:#fff
style API fill:#0066FF,color:#fff
env
NEXT_PUBLIC_ENABLE_MOCKING=true
NEXT_PUBLIC_MOCK_DELAY=500 # Délai simulé en ms
Usage : quand le backend n'est pas disponible, pour travailler uniquement côté front.
env
NEXT_PUBLIC_ENABLE_MOCKING=false
NEXT_PUBLIC_API_URL=https://api.darewatch.com/api
Usage : quand l'API backend est prête et disponible.
Emplacement des fichiers .env¶
drwh_front/ ← Racine du monorepo
├── .env.development ← Variables Next.js (tech + immo) dev
├── .env.staging ← Variables Next.js staging
├── .env.example ← Exemple à copier (dans Git)
└── apps/
└── drwh_group/
├── .env ← Variables Laravel (PAS dans Git)
└── .env.example ← Exemple Laravel (dans Git)
Liens complémentaires¶
Services
Vue d'ensemble des services¶
Les trois services en un coup d'œil¶
graph TD
subgraph Monorepo["📦 Monorepo drwh_front"]
G[🏠 drwh_group\nLaravel / PHP\nPort 3001]
T[💻 drwh_tech\nNext.js / React\nPort 3003]
I[🏗️ drwh_immo\nNext.js / React\nPort 3002]
end
GW[🔀 Nginx Gateway] --> G
GW --> T
GW --> I
G --> API[🔧 API Backend]
T --> API
I --> API
style G fill:#e74c3c,color:#fff
style T fill:#0066FF,color:#fff
style I fill:#27ae60,color:#fff
style GW fill:#2d2e2e,color:#fff
style API fill:#8e44ad,color:#fff
Tableau comparatif¶
| drwh_group | drwh_tech | drwh_immo | |
|---|---|---|---|
| Rôle | Landing page principale | Site division technologie | Site division immobilière |
| Technologie | Laravel + PHP + Livewire | Next.js + React + TypeScript | Next.js + React + TypeScript |
| Port local | 8002 | 4201 | 4200 |
| Port Docker | 3001 | 3003 | 3002 |
| URL prod | darewatchgroup.com | tech.darewatchgroup.com | immo.darewatchgroup.com |
| Tests | PHPUnit | Jest + Cypress | Jest + Cypress |
| CSS | Bootstrap | Tailwind CSS | Tailwind CSS |
Accès rapide à la documentation de chaque service¶
- 🏠 drwh_group
Site principal Laravel/PHP. Landing page, formulaire de contact, routing vers les autres pôles.
- 💻 drwh_tech
Site Division Technologie. Services IT, blog tech, formations, carrières, contact.
- 🏗️ drwh_immo
Site Division Immobilière. Biens immobiliers, projets, lotissements, blog immo.
Comment les services communiquent-ils ?¶
sequenceDiagram
participant V as Visiteur
participant NG as Nginx
participant T as drwh_tech
participant A as API Backend
V->>NG: https://tech.darewatchgroup.com/blog
NG->>T: Requête vers drwh_tech:3003
T->>A: GET /api/v1/blog/articles
A-->>T: JSON [{ articles }]
T-->>NG: Page HTML rendue
NG-->>V: Page affichée
La communication entre les services frontend et l'API backend se fait via des requêtes HTTP REST.
→ Voir la documentation API
Liens complémentaires¶
drwh_group — Site Principal¶
Rôle du service¶
drwh_group est la vitrine principale de DAREWATCH CONSULTING SARL. Quand un visiteur accède au site principal, il arrive ici. Cette page présente l'entreprise et oriente les visiteurs vers les deux autres pôles (Tech et Immo).
URL
Local : http://localhost:8002
Production : darewatchgroup.com
Stack technique¶
graph LR
PHP[PHP 8.2+] --> LAR[Laravel 11]
LAR --> LW[Livewire]
LAR --> BLADE[Blade\nTemplating]
LAR --> BS[Bootstrap 5\nCSS]
style PHP fill:#8e44ad,color:#fff
style LAR fill:#e74c3c,color:#fff
style LW fill:#f39c12,color:#fff
style BLADE fill:#27ae60,color:#fff
style BS fill:#0066FF,color:#fff
| Couche | Technologie | Rôle |
|---|---|---|
| Language | PHP 8.2+ | Langage backend |
| Framework | Laravel 11 | Structure MVC, routing, validation |
| Interactions | Livewire | Composants dynamiques sans rechargement |
| Vues | Blade | Moteur de templates HTML |
| CSS | Bootstrap 5 | Design et mise en page |
Pages disponibles¶
| Page | URL | Description |
|---|---|---|
| Accueil | / |
Landing page avec hero, statistiques et liens vers Tech & Immo |
| Contact | /contact |
Formulaire de contact dynamique (Livewire) |
| Services | /services |
Présentation des domaines d'activité de Darewatch |
| Articles | /articles |
Articles et actualités de l'entreprise |
Architecture du service¶
apps/drwh_group/
├── app/
│ ├── Http/
│ │ ├── Controllers/
│ │ │ └── PageController.php ← Contrôleur principal des pages
│ │ └── Requests/ ← Validation des formulaires
│ └── Livewire/
│ └── ContactForm.php ← Composant formulaire de contact
├── resources/
│ └── views/
│ ├── layouts/
│ │ └── app.blade.php ← Template de base (navbar + footer)
│ ├── pages/
│ │ ├── home.blade.php ← Page d'accueil
│ │ ├── contact.blade.php ← Page contact
│ │ ├── articles.blade.php ← Page articles
│ │ └── services.blade.php ← Page services
│ ├── composants/ ← Composants réutilisables (cards, boutons…)
│ ├── sections/ ← Grandes sections de page (hero, about…)
│ └── livewire/ ← Vues des composants Livewire
├── routes/
│ └── web.php ← Définition des URLs
├── public/
│ ├── css/ ← Styles compilés
│ ├── js/ ← Scripts compilés
│ └── images/ ← Images statiques
├── config/ ← Configuration Laravel
├── database/
│ ├── migrations/ ← Schéma de base de données
│ └── seeders/ ← Données initiales
└── .env ← Variables d'environnement
Comment fonctionne le formulaire de contact ?¶
sequenceDiagram
participant U as Utilisateur
participant LW as Livewire (Front)
participant LC as ContactForm.php
participant API as API Backend
U->>LW: Remplit le formulaire
LW->>LC: Validation en temps réel
LC-->>LW: Erreurs affichées
U->>LW: Soumet le formulaire
LW->>LC: Données envoyées
LC->>API: POST /api/contact
API-->>LC: 200 OK
LC-->>LW: Message envoyé ✓
LW-->>U: Confirmation affichée
// apps/drwh_group/app/Livewire/ContactForm.php
class ContactForm extends Component
{
public string $name = '';
public string $email = '';
public string $message = '';
public bool $sent = false;
protected $rules = [
'name' => 'required|min:2',
'email' => 'required|email',
'message' => 'required|min:10',
];
public function submit()
{
$this->validate();
// Envoi à l'API backend
$this->sent = true;
$this->reset(['name', 'email', 'message']);
}
}
```
=== "Vue Blade (HTML)"
```html
<!-- resources/views/livewire/contact-form.blade.php -->
<form wire:submit.prevent="submit">
<input wire:model="name" placeholder="Votre nom" />
@error('name') <span>{{ $message }}</span> @enderror
<input wire:model="email" type="email" />
@error('email') <span>{{ $message }}</span> @enderror
<textarea wire:model="message"></textarea>
@error('message') <span>{{ $message }}</span> @enderror
<button type="submit">Envoyer</button>
@if($sent)
<p>Message envoyé avec succès !</p>
@endif
</form>
```
---
## Structure des routes
```php
// apps/drwh_group/routes/web.php
Route::get('/', [PageController::class, 'home'])->name('home');
Route::get('/contact', [PageController::class, 'contact'])->name('contact');
Route::get('/services', [PageController::class, 'services'])->name('services');
Route::get('/articles', [PageController::class, 'articles'])->name('articles');
Lancer le service en local¶
# Depuis la racine du monorepo
cd apps/drwh_group
php artisan serve --port=8002
# Ou via npm (depuis la racine)
npm run dev:group
Le service sera accessible à http://localhost:8002
Modifier le design¶
Pour modifier le menu de navigation :
Pour modifier le contenu d'une page :
Pour modifier les styles :
Liens complémentaires¶
drwh_tech — Division Technologie¶
Rôle du service¶
drwh_tech est le site complet de la division technologie de DAREWATCH CONSULTING. Il présente les services IT, les formations, les offres d'emploi (carrières), le blog technique, et permet aux prospects de prendre contact.
URL
Local : http://localhost:4201
Production : tech.darewatchgroup.com
Stack technique¶
graph LR
TS[TypeScript] --> NEXT[Next.js 14\nApp Router]
NEXT --> REACT[React 18]
NEXT --> TW[Tailwind CSS]
NEXT --> API[API Backend\nREST/JSON]
style TS fill:#2d79c7,color:#fff
style NEXT fill:#2d2e2e,color:#fff
style REACT fill:#0066FF,color:#fff
style TW fill:#27ae60,color:#fff
style API fill:#8e44ad,color:#fff
| Couche | Technologie | Rôle |
|---|---|---|
| Language | TypeScript | Typage statique, détection d'erreurs |
| Framework | Next.js 14 (App Router) | SSR, routage, optimisation |
| UI | React 18 | Composants interactifs |
| CSS | Tailwind CSS | Design utilitaire |
| Tests unitaires | Jest | Tests de composants |
| Tests e2e | Cypress | Tests de navigation |
Pages du site¶
| Page | URL | Description |
|---|---|---|
| Accueil | / |
Hero, services, réalisations, témoignages, blog |
| À Propos | /about |
Histoire, chiffres clés, timeline depuis 2022 |
| Services | /services |
Liste des services IT proposés |
| Carrières | /carriere |
Offres d'emploi (Développeur, Ingénieur Réseaux…) |
| Carrière (détail) | /carriere/[slug] |
Détail d'une offre d'emploi |
| Blog | /blog |
Articles et actualités tech |
| Article (détail) | /blog/[slug] |
Détail d'un article |
| Contact | /contact |
Formulaire de contact + FAQ |
Sections de la page d'accueil¶
La page d'accueil est composée de sections empilées :
graph TD
NAV[🔝 Navbar\nNavigation principale] --> HERO[🦸 HeroSection\nAccroche principale]
HERO --> ABOUT[ℹ️ AboutSection\nPrésentation courte]
ABOUT --> SERV[⚙️ ServicesSection\nAperçu des services]
SERV --> WORKS[🏆 WorksSection\nRéalisations clients]
WORKS --> TESTI[💬 TestimonialsSection\nTémoignages]
TESTI --> BLOG[📝 BlogSection\nDerniers articles]
BLOG --> FOOTER[📋 Footer]
style NAV fill:#2d2e2e,color:#fff
style HERO fill:#0066FF,color:#fff
style ABOUT fill:#27ae60,color:#fff
style SERV fill:#f39c12,color:#fff
style WORKS fill:#8e44ad,color:#fff
style TESTI fill:#e74c3c,color:#fff
style BLOG fill:#2196F3,color:#fff
style FOOTER fill:#2d2e2e,color:#fff
Architecture des fichiers¶
apps/drwh_tech/
├── src/
│ ├── app/ ← Pages (Next.js App Router)
│ │ ├── layout.tsx ← Layout global (head, fonts, analytics)
│ │ ├── page.tsx ← Page d'accueil
│ │ ├── navbar.tsx ← Barre de navigation
│ │ ├── about/
│ │ │ └── page.tsx ← Page À Propos
│ │ ├── services/
│ │ │ └── page.tsx ← Page Services
│ │ ├── carriere/
│ │ │ ├── page.tsx ← Liste des offres d'emploi
│ │ │ └── [slug]/page.tsx ← Détail d'une offre
│ │ ├── blog/
│ │ │ ├── page.tsx ← Liste des articles
│ │ │ └── [slug]/page.tsx ← Détail d'un article
│ │ └── contact/
│ │ └── page.tsx ← Page contact + FAQ
│ │
│ ├── components/ ← Composants réutilisables
│ │ ├── HeroSection.tsx
│ │ ├── AboutSection.tsx
│ │ ├── ServicesSection.tsx
│ │ ├── WorksSection.tsx
│ │ ├── TestimonialsSection.tsx
│ │ ├── BlogSection.tsx
│ │ ├── Header.tsx
│ │ └── Footer.tsx
│ │
│ ├── lib/ ← Utilitaires et services
│ │ ├── public.service.ts ← Appels API backend
│ │ ├── fallback-content.ts ← Données statiques de secours
│ │ └── types.ts ← Types TypeScript
│ │
│ └── types/ ← Interfaces TypeScript globales
│
├── next.config.js ← Configuration Next.js
├── tailwind.config.js ← Configuration Tailwind CSS
├── tsconfig.json ← Configuration TypeScript
└── project.json ← Configuration NX
Charte graphique¶
| Élément | Valeur | Usage |
|---|---|---|
| Couleur principale | #0066FF |
Boutons, liens, accents |
| Couleur secondaire | #004E89 |
Nuances, hover |
| Fond clair | #F7F7F7 |
Arrière-plans clairs |
| Fond sombre | #2D2E2E |
Footer, éléments sombres |
| Police | Inter (Google Fonts) | Tous les textes |
Stratégie de données : API + Fallback¶
flowchart TD
PAGE[Page Next.js] --> CALL[Appel API\npublic.service.ts]
CALL -->|Succès| DATA[✅ Données dynamiques\ndepuis le backend]
CALL -->|Erreur / Vide| FALLBACK[🔄 Données statiques\nfallback-content.ts]
DATA --> RENDER[Rendu de la page]
FALLBACK --> RENDER
style CALL fill:#0066FF,color:#fff
style DATA fill:#27ae60,color:#fff
style FALLBACK fill:#f39c12,color:#fff
Le service appelle d'abord public.service.ts (API backend). Si l'API répond avec une erreur ou des données vides, il bascule automatiquement sur les données de fallback (fallback-content.ts) pour garantir que le site reste fonctionnel.
Lancer le service en local¶
# Depuis la racine du monorepo
npm run dev:tech
# Le service sera disponible sur http://localhost:4201
Tests¶
# Tests unitaires
npm run test:tech
# Tests end-to-end (Cypress)
npm run e2e:tech
# Vérification TypeScript
npm run type-check
Modifier le contenu¶
| Contenu à modifier | Fichier |
|---|---|
| Menu de navigation | src/app/navbar.tsx |
| Page d'accueil | src/app/page.tsx |
| Section services homepage | src/components/ServicesSection.tsx |
| Page services | src/app/services/page.tsx |
| Données statiques (fallback) | src/lib/fallback-content.ts |
| Couleurs Tailwind | tailwind.config.js |
Liens complémentaires¶
drwh_immo — Division Immobilière¶
Rôle du service¶
drwh_immo est le site complet de la division immobilière de DAREWATCH. Il présente les biens immobiliers à vendre, les projets de construction en cours, les lotissements, et permet aux visiteurs de prendre contact.
URL
Local : http://localhost:4200
Production : immo.darewatchgroup.com
Marché ciblé : Promotion immobilière au Cameroun
Stack technique¶
| Couche | Technologie | Rôle |
|---|---|---|
| Language | TypeScript | Typage statique |
| Framework | Next.js 14 (App Router) | SSR, routage |
| UI | React 18 | Composants interactifs |
| CSS | Tailwind CSS | Design utilitaire |
| API Client | Fetch / Axios | Appels API backend |
| Tests | Jest + Cypress | Tests unitaires et e2e |
Pages du site¶
| Page | URL | Description |
|---|---|---|
| Accueil | / |
Landing avec toutes les sections |
| Immobilier | /immobilier |
Catalogue : villas, appartements, terrains |
| Projets | /projets |
Projets de construction en cours |
| Projet (détail) | /projets/[id] |
Fiche détaillée d'un projet |
| Lotissement | /lotissement |
Terrains découpés à vendre |
| Blog | /blog |
Articles et actualités immobilières |
| Article (détail) | /blog/[id] |
Détail d'un article |
| Carrières | /carriere |
Offres d'emploi |
| Carrière (détail) | /carriere/[id] |
Détail d'une offre |
| Contact | /contact |
Formulaire de contact |
| Rédiger | /rediger |
Rédaction d'articles (interface locale) |
Structure de la page d'accueil¶
Les sections sont ordonnées pour convaincre progressivement le visiteur :
graph TD
HERO[🦸 Hero\nPremière impression forte] --> ABOUT[ℹ️ About Us\nQui sommes-nous ?]
ABOUT --> GALLERY[📸 Gallery\nPhotos des biens]
GALLERY --> SPEC[🎯 Specializations\nDomaines d'expertise]
SPEC --> STORY[📖 Our Story\nHistoire & crédibilité]
STORY --> NUMS[📊 Numbers\nChiffres clés]
NUMS --> WHY[✅ Why Choose Us\nArguments différenciants]
WHY --> PROCESS[⚙️ Work Process\nCommment on travaille]
PROCESS --> TESTI[💬 Testimonials\nTémoignages clients]
TESTI --> NEWS[📰 News\nActualités]
NEWS --> CTA[🎯 CTA\nAppel à l'action final]
style HERO fill:#27ae60,color:#fff
style NUMS fill:#f39c12,color:#fff
style CTA fill:#e74c3c,color:#fff
Architecture des fichiers¶
apps/drwh_immo/
├── src/
│ ├── app/ ← Pages (Next.js App Router)
│ │ ├── layout.tsx ← Layout global + SEO
│ │ ├── page.tsx ← Page d'accueil
│ │ ├── sitemap.ts ← Sitemap dynamique
│ │ ├── robots.ts ← Robots.txt
│ │ ├── components/ ← Header, Footer immo
│ │ ├── immobilier/
│ │ │ └── page.tsx ← Catalogue immobilier
│ │ ├── projets/
│ │ │ ├── page.tsx ← Liste des projets
│ │ │ └── [id]/page.tsx ← Détail projet
│ │ ├── lotissement/
│ │ │ └── page.tsx ← Page lotissement
│ │ ├── blog/
│ │ │ ├── page.tsx ← Liste articles
│ │ │ └── [id]/page.tsx ← Détail article
│ │ ├── carriere/
│ │ │ ├── page.tsx ← Offres d'emploi
│ │ │ └── [id]/page.jsx ← Détail offre
│ │ ├── contact/
│ │ │ └── page.tsx ← Contact + FAQ
│ │ └── rediger/
│ │ └── page.tsx ← Éditeur d'articles local
│ │
│ ├── components/
│ │ └── sections/ ← Toutes les sections de page
│ │ ├── HeroSection.tsx
│ │ ├── AboutSection.tsx
│ │ ├── GallerySection.tsx
│ │ ├── NumbersSection.tsx
│ │ └── ...
│ │
│ └── lib/
│ ├── api/
│ │ └── client.ts ← Client API backend
│ ├── data/
│ │ ├── properties.ts ← Données statiques biens
│ │ ├── articles.ts ← Données statiques articles
│ │ └── lots.ts ← Données statiques lots
│ └── constants.ts ← Constantes globales
│
├── next.config.js
├── tailwind.config.js
└── project.json
Client API des propriétés¶
Un client API est en place pour les biens immobiliers :
// src/lib/api/client.ts
// Récupérer toutes les propriétés (paginées)
GET /properties?page=1&pageSize=12
// Récupérer une propriété par ID
GET /properties/:id
// Rechercher des propriétés
GET /properties/search?q=villa&city=Douala&minPrice=10000000&maxPrice=50000000
Mode Mock actif en développement
Les appels API en développement peuvent être redirigés vers des données mock.
Vérifiez la variable NEXT_PUBLIC_ENABLE_MOCKING dans votre .env.development.
SEO dynamique¶
drwh_immo intègre un SEO avancé :
graph TD
SM[sitemap.ts\nGenère les URLs] -->|Projets| P[/projets/[id]]
SM -->|Articles| A[/blog/[id]]
SM -->|Pages statiques| S[/, /immobilier, /contact…]
ROB[robots.ts\nRègles robots] --> ALLOW[Indexation autorisée]
style SM fill:#0066FF,color:#fff
style ROB fill:#27ae60,color:#fff
Lancer le service en local¶
# Depuis la racine du monorepo
npm run dev:immo
# Le service est disponible sur http://localhost:4200
Tests¶
Liens complémentaires¶
Infrastructure
Docker & Déploiement¶
Architecture Docker¶
Le projet contient quatre conteneurs orchestrés via Docker Compose :
graph TD
Internet([Internet]) --> GW[🔀 drwh_gateway\nNginx\nPort 8080/8443]
GW --> G[🏠 drwh_group\nLaravel\nPort 3001]
GW --> T[💻 drwh_tech\nNext.js\nPort 3003]
GW --> I[🏗️ drwh_immo\nNext.js\nPort 3002]
style Internet fill:#e8f4f8
style GW fill:#2d2e2e,color:#fff
style G fill:#e74c3c,color:#fff
style T fill:#0066FF,color:#fff
style I fill:#27ae60,color:#fff
| Conteneur | Service | Port interne | Port hôte par défaut |
|---|---|---|---|
drwh_gateway |
Nginx Reverse Proxy | 80/443 | 8080/8443 |
drwhtch_tech |
Next.js drwh_tech | 3003 | — |
drwh_immo |
Next.js drwh_immo | 3002 | — |
drwh_group |
Laravel drwh_group | 3001 | — (bind local unique) |
Fichiers Docker¶
| Fichier | Rôle |
|---|---|
Dockerfile.tech |
Construction de l'image drwh_tech |
Dockerfile.immo |
Construction de l'image drwh_immo |
Dockerfile.group |
Construction de l'image drwh_group |
docker-compose.yml |
Orchestration des quatre services |
infra/nginx/nginx.conf |
Configuration globale Nginx |
infra/nginx/conf.d/ |
Virtual hosts per service |
infra/nginx/certs/ |
Certificats TLS (fullchain.pem, privkey.pem) |
infra/nginx/www/ |
Webroot ACME (Let's Encrypt) |
Commandes Docker principales¶
bash
# Depuis le dossier drwh_front
cd drwh_front
docker compose up --build
Accès après démarrage :
- HTTP : [http://localhost:8080](http://localhost:8080)
- HTTPS : [https://localhost:8443](https://localhost:8443)
bash
# Exposer sur les ports 80/443 si disponibles
DRWH_GATEWAY_HTTP_PORT=80 DRWH_GATEWAY_HTTPS_PORT=443 \
docker compose up --build
bash
docker compose down
````bash # Tous les services docker compose logs -f
# Un seul service
docker compose logs -f drwh_tech
```
bash
docker compose up --build drwh_tech
Variables d'environnement Docker¶
Les conteneurs Next.js utilisent NODE_ENV=production.
Le conteneur Laravel expose APP_ENV=production, APP_DEBUG=false.
Sécurité
Pour un déploiement réel, ne jamais inclure les secrets dans docker-compose.yml.
Utilisez un fichier .env sécurisé ou un gestionnaire de secrets (Vault, Docker Secrets…).
Créez un fichier .env à la racine avec les variables sensibles :
# drwh_group
DRWH_GROUP_APP_KEY=base64:...
DRWH_GROUP_DB_PASSWORD=motdepassesecret
# Ports gateway (optionnel)
DRWH_GATEWAY_HTTP_PORT=80
DRWH_GATEWAY_HTTPS_PORT=443
````
---
## Structure du `docker-compose.yml`
```yaml
services:
drwh_gateway:
image: nginx:alpine
ports:
- "${DRWH_GATEWAY_HTTP_PORT:-8080}:80"
- "${DRWH_GATEWAY_HTTPS_PORT:-8443}:443"
volumes:
- ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./infra/nginx/conf.d:/etc/nginx/conf.d
- ./infra/nginx/certs:/etc/nginx/certs
- ./infra/nginx/www:/var/www/acme
depends_on:
- drwh_tech
- drwh_immo
- drwh_group
drwhtch_tech:
build:
context: .
dockerfile: Dockerfile.tech
expose:
- "3003"
drwh_immo:
build:
context: .
dockerfile: Dockerfile.immo
expose:
- "3002"
drwh_group:
build:
context: .
dockerfile: Dockerfile.group
expose:
- "3001"
HTTPS avec Let's Encrypt (production)¶
En production, configurez des certificats TLS valides :
flowchart LR
A[Obtenir certificat\nLet's Encrypt] --> B[Copier dans\ninfra/nginx/certs/]
B --> C[Configurer\nnginx.conf HTTPS]
C --> D[docker compose up --build]
style A fill:#27ae60,color:#fff
style D fill:#0066FF,color:#fff
# Avec Certbot (nécessite accès root sur le serveur)
certbot certonly --webroot \
-w ./infra/nginx/www \
-d tech.darewatchgroup.com \
-d immo.darewatchgroup.com \
-d darewatchgroup.com
# Copier les certificats
cp /etc/letsencrypt/live/tech.darewatchgroup.com/fullchain.pem infra/nginx/certs/
cp /etc/letsencrypt/live/tech.darewatchgroup.com/privkey.pem infra/nginx/certs/
Déploiement VPS / Serveur dédié¶
Acheter et configurer un serveur¶
Pour déployer en production, vous avez besoin d'un serveur. Deux options courantes :
Un VPS (Virtual Private Server) est un serveur virtuel chez un hébergeur.
**Fournisseurs recommandés :**
- [OVH Cloud](https://ovh.com) — Très présent en Afrique
- [DigitalOcean](https://digitalocean.com) — Simple et bien documenté
- [Hetzner](https://hetzner.com) — Excellent rapport qualité/prix
**Configuration minimale recommandée :**
- 2 vCPUs
- 4 Go RAM
- 40 Go SSD
- Ubuntu 22.04 LTS
KVM (Kernel-based Virtual Machine) permet de virtualiser à l'échelle d'un serveur physique. Idéal si vous gérez votre propre infrastructure.
Dokploy est un outil de déploiement simplifié basé sur Docker.
**Installation sur votre VPS :**
```bash
curl -sSL https://dokploy.com/install.sh | sh
```
Dokploy fournit une interface web pour :
- Créer et gérer des services Docker
- Gérer les domaines et sous-domaines
- Inviter des membres de l'équipe
- Monitorer les logs et performances
Liens complémentaires¶
Nginx & Reverse Proxy¶
Rôle de Nginx dans l'architecture¶
Nginx joue le rôle de reverse proxy : il reçoit toutes les requêtes entrantes et les redirige vers le bon service selon le nom de domaine.
graph TD
Internet([🌐 Internet]) --> NG[Nginx\nReverse Proxy\nPort 80 / 443]
NG -->|darewatchgroup.com| G[drwh_group\nPort 3001]
NG -->|tech.darewatchgroup.com| T[drwh_tech\nPort 3003]
NG -->|immo.darewatchgroup.com| I[drwh_immo\nPort 3002]
NG -->|HTTP 80| REDIR[Redirection\nvers HTTPS 443]
REDIR --> NG
style Internet fill:#e8f4f8
style NG fill:#2d2e2e,color:#fff
style G fill:#e74c3c,color:#fff
style T fill:#0066FF,color:#fff
style I fill:#27ae60,color:#fff
style REDIR fill:#f39c12,color:#fff
Fichiers de configuration¶
infra/nginx/
├── nginx.conf ← Configuration globale Nginx
├── conf.d/
│ ├── drwh_group.conf ← Virtual host pour drwh_group
│ ├── drwh_tech.conf ← Virtual host pour drwh_tech
│ └── drwh_immo.conf ← Virtual host pour drwh_immo
├── certs/
│ ├── fullchain.pem ← Certificat TLS
│ └── privkey.pem ← Clé privée TLS
└── www/
└── .well-known/
└── acme-challenge/ ← Webroot pour Let's Encrypt
Configuration d'un virtual host¶
Exemple de configuration pour drwh_tech :
# infra/nginx/conf.d/drwh_tech.conf
# Redirection HTTP → HTTPS
server {
listen 80;
server_name tech.darewatchgroup.com;
# Pour Let's Encrypt
location /.well-known/acme-challenge/ {
root /var/www/acme;
}
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS
server {
listen 443 ssl http2;
server_name tech.darewatchgroup.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Proxy vers le conteneur drwh_tech
location / {
proxy_pass http://drwhtch_tech:3003;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}
}
Routing par domaine¶
flowchart LR
A[darewatchgroup.com] -->|Nginx route| G[drwh_group:3001]
B[tech.darewatchgroup.com] -->|Nginx route| T[drwhtch_tech:3003]
C[immo.darewatchgroup.com] -->|Nginx route| I[drwh_immo:3002]
style G fill:#e74c3c,color:#fff
style T fill:#0066FF,color:#fff
style I fill:#27ae60,color:#fff
Gestion des noms de domaine et sous-domaines¶
DNS — Pointage vers le serveur¶
Pour que vos domaines pointent vers votre serveur, configurez les enregistrements DNS chez votre registrar :
| Type | Nom | Valeur | TTL |
|---|---|---|---|
A |
darewatchgroup.com |
IP de votre serveur | 300 |
A |
tech.darewatchgroup.com |
IP de votre serveur | 300 |
A |
immo.darewatchgroup.com |
IP de votre serveur | 300 |
A |
www.immo.darewatchgroup.com |
IP de votre serveur | 300 |
Trouver l'IP de votre serveur
Votre hébergeur (OVH, DigitalOcean…) vous fournit l'adresse IP dans le tableau de bord de votre VPS.
Propagation DNS¶
Après modification des DNS, la propagation peut prendre de quelques minutes à 48 heures.
Renouvellement automatique des certificats TLS¶
En production, configurez un cron pour renouveler automatiquement les certificats :
# Vérifier le renouvellement (dans crontab)
0 3 * * * certbot renew --quiet && docker compose restart drwh_gateway
Liens complémentaires¶
API Backend
API Backend — Conventions & Authentification¶
Vue d'ensemble¶
L'API backend de DAREWATCH est une API REST qui alimente les trois services frontends. Elle suit les conventions JSON standard et utilise JWT pour l'authentification.
graph TD
T[drwh_tech] -->|HTTP REST| API[API Backend]
I[drwh_immo] -->|HTTP REST| API
G[drwh_group] -->|HTTP REST| API
A[drwh_admin] -->|HTTP REST\nJWT Auth| API
API --> DB[(Base de données)]
style API fill:#8e44ad,color:#fff
style DB fill:#f39c12,color:#fff
style A fill:#e74c3c,color:#fff
URLs de base¶
| Environnement | URL de base |
|---|---|
| Production | https://api.darewatch.com/api/v1 |
| Staging | https://api-staging.darewatch.com/api/v1 |
| Développement | http://localhost:3000/api |
En-têtes requis¶
Content-Type: application/json
Authorization: Bearer <JWT_TOKEN> ← Requis pour toutes les routes /admin/*
Format de réponse standard¶
json
{
"success": true,
"data": {
"id": 1,
"title": "Service Web",
"created_at": "2026-04-01T10:00:00Z"
}
}
json
{
"success": true,
"data": [...],
"meta": {
"total": 42,
"page": 1,
"pageSize": 10,
"lastPage": 5
}
}
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Le champ email est requis.",
"details": {
"email": ["Le champ email est requis."]
}
}
}
Codes de réponse HTTP¶
| Code | Signification | Usage |
|---|---|---|
200 OK |
Succès | GET, PUT (mise à jour) |
201 Created |
Ressource créée | POST (création) |
204 No Content |
Suppression réussie | DELETE |
400 Bad Request |
Données invalides | Erreur de validation |
401 Unauthorized |
Non authentifié | Token manquant ou expiré |
403 Forbidden |
Non autorisé | Permissions insuffisantes |
404 Not Found |
Ressource introuvable | ID inexistant |
422 Unprocessable |
Erreur de validation | Données mal formatées |
500 Server Error |
Erreur serveur | Bug côté backend |
Authentification JWT¶
sequenceDiagram
participant C as Client (Admin)
participant A as API Backend
C->>A: POST /auth/login\n{ email, password }
A-->>C: 200 { token, user }
Note over C: Stocke le token JWT
C->>A: GET /admin/services\nAuthorization: Bearer <token>
A-->>C: 200 { data: [...] }
Note over C,A: Token expiré après 24h
C->>A: POST /auth/refresh\n{ refresh_token }
A-->>C: 200 { token, refresh_token }
Endpoint de login¶
POST /auth/login
Content-Type: application/json
{
"email": "admin@darewatch.com",
"password": "motdepasse"
}
Réponse :
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "...",
"expires_in": 86400,
"user": {
"id": 1,
"email": "admin@darewatch.com",
"role": "super_admin"
}
}
}
Matrice des permissions¶
| Route | Public | Admin Tech | Admin Immo | Super Admin |
|---|---|---|---|---|
GET /services |
✅ | ✅ | ✅ | ✅ |
POST /admin/services |
❌ | ✅ | ❌ | ✅ |
GET /properties |
✅ | ✅ | ✅ | ✅ |
POST /admin/properties |
❌ | ❌ | ✅ | ✅ |
DELETE /admin/* |
❌ | ❌ | ❌ | ✅ |
Pagination standard¶
Toutes les routes de liste acceptent ces paramètres de requête :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
page |
integer | 1 | Numéro de page |
pageSize |
integer | 10 | Nombre d'éléments par page |
sort |
string | created_at |
Champ de tri |
order |
string | desc |
Ordre : asc ou desc |
Liens complémentaires¶
Module Tech — Endpoints API¶
Ce module couvre tous les endpoints REST utilisés par le site drwh_tech.
Base URL
https://api.darewatch.com/api/v1
→ Conventions générales
Vue d'ensemble des endpoints Tech¶
graph LR
API[API Backend] --> S[/services\nServices IT]
API --> B[/blog/articles\nBlog Tech]
API --> W[/works\nRéalisations]
API --> J[/careers\nOffres d'emploi]
API --> C[/contact/tech\nContact]
style API fill:#8e44ad,color:#fff
style S fill:#0066FF,color:#fff
style B fill:#27ae60,color:#fff
style W fill:#f39c12,color:#fff
style J fill:#e74c3c,color:#fff
style C fill:#2d2e2e,color:#fff
4.1 Services Tech¶
Lister les services¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Développement Web & Mobile",
"slug": "developpement-web-mobile",
"description": "Applications web et mobiles sur mesure",
"icon": "code",
"features": ["React", "Next.js", "React Native", "Flutter"],
"is_active": true
}
]
}
Récupérer un service par slug¶
4.2 Blog Tech¶
Lister les articles¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Comment déployer Next.js avec Docker",
"slug": "deployer-nextjs-docker",
"excerpt": "Guide complet de déploiement...",
"content": "...",
"author": {
"name": "Équipe Darewatch Tech",
"avatar": "https://..."
},
"category": "DevOps",
"tags": ["docker", "nextjs", "déploiement"],
"published_at": "2026-04-01T10:00:00Z",
"reading_time": 8
}
],
"meta": { "total": 25, "page": 1, "pageSize": 10 }
}
Récupérer un article par slug¶
4.3 Réalisations (Works)¶
Lister les réalisations¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Site E-commerce Cameroun",
"slug": "ecommerce-cameroun",
"description": "Plateforme e-commerce complète",
"image_url": "https://...",
"technologies": ["Next.js", "Stripe", "PostgreSQL"],
"category": "Web",
"client": "Client confidentiel",
"year": 2025
}
]
}
Statistiques globales¶
Réponse :
{
"success": true,
"data": {
"projects_count": 50,
"clients_count": 30,
"years_experience": 4,
"team_size": 12
}
}
4.4 Carrières Tech¶
Lister les offres d'emploi¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Développeur Full Stack React/Node",
"slug": "developpeur-fullstack-react-node",
"type": "CDI",
"location": "Douala, Cameroun",
"description": "...",
"requirements": ["3 ans d'expérience", "Maîtrise React"],
"salary_range": "Selon profil",
"is_active": true,
"published_at": "2026-04-01T10:00:00Z"
}
]
}
Récupérer une offre par slug¶
4.5 Contact Tech¶
Envoyer un message¶
POST /contact/tech
Content-Type: application/json
{
"name": "Jean Dupont",
"email": "jean@exemple.com",
"phone": "+237 691234567",
"subject": "Demande de devis site web",
"message": "Bonjour, je souhaite un devis pour..."
}
Réponse :
{
"success": true,
"data": {
"message": "Votre message a été envoyé avec succès. Nous vous recontacterons sous 48h."
}
}
4.6 Témoignages¶
Lister les témoignages¶
Endpoints Admin Tech (authentification requise)¶
JWT Token requis
Ces routes nécessitent un token JWT dans le header Authorization: Bearer <token>.
→ Voir l'authentification
| Méthode | Route | Action |
|---|---|---|
GET |
/admin/services |
Lister tous les services |
POST |
/admin/services |
Créer un service |
PUT |
/admin/services/:id |
Modifier un service |
DELETE |
/admin/services/:id |
Supprimer un service |
GET |
/admin/blog/articles |
Lister tous les articles |
POST |
/admin/blog/articles |
Créer un article |
PUT |
/admin/blog/articles/:id |
Modifier un article |
DELETE |
/admin/blog/articles/:id |
Supprimer un article |
GET |
/admin/careers |
Lister les offres |
POST |
/admin/careers |
Créer une offre |
PUT |
/admin/careers/:id |
Modifier une offre |
DELETE |
/admin/careers/:id |
Supprimer une offre |
Liens complémentaires¶
Module Immo — Endpoints API¶
Ce module couvre tous les endpoints REST utilisés par le site drwh_immo.
Base URL
https://api.darewatch.com/api/v1
→ Conventions générales
Vue d'ensemble des endpoints Immo¶
graph LR
API[API Backend] --> P[/properties\nBiens immobiliers]
API --> PR[/projects\nProjets construction]
API --> L[/lots\nLotissements]
API --> B[/blog/articles\nBlog Immo]
API --> J[/careers\nCarrières Immo]
API --> C[/contact/immo\nContact]
style API fill:#8e44ad,color:#fff
style P fill:#27ae60,color:#fff
style PR fill:#0066FF,color:#fff
style L fill:#f39c12,color:#fff
style B fill:#e74c3c,color:#fff
style J fill:#9b59b6,color:#fff
3.1 Propriétés (biens immobiliers)¶
Lister les propriétés¶
Paramètres de filtre :
| Paramètre | Type | Description |
|---|---|---|
page |
integer | Numéro de page |
pageSize |
integer | Éléments par page |
type |
string | villa, appartement, terrain |
city |
string | Ville (ex: Douala, Yaoundé) |
minPrice |
integer | Prix minimum (FCFA) |
maxPrice |
integer | Prix maximum (FCFA) |
status |
string | disponible, vendu, en_construction |
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Villa F5 Bonamoussadi",
"slug": "villa-f5-bonamoussadi",
"type": "villa",
"status": "disponible",
"price": 45000000,
"currency": "FCFA",
"surface_m2": 250,
"bedrooms": 5,
"bathrooms": 3,
"location": {
"city": "Douala",
"district": "Bonamoussadi",
"description": "Résidence sécurisée, proche commerces"
},
"images": ["https://...", "https://..."],
"features": ["Piscine", "Jardin", "Garage", "Groupe électrogène"],
"created_at": "2026-03-01T10:00:00Z"
}
],
"meta": { "total": 48, "page": 1, "pageSize": 12 }
}
Récupérer une propriété¶
Rechercher des propriétés¶
3.2 Projets de construction¶
Lister les projets¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Résidence Les Palmiers",
"slug": "residence-les-palmiers",
"description": "Résidence sécurisée de 24 appartements",
"status": "en_cours",
"progress_percent": 65,
"delivery_date": "2026-12-01",
"location": {
"city": "Douala",
"district": "Makepe"
},
"units_total": 24,
"units_available": 8,
"price_from": 18000000,
"images": ["https://..."],
"features": ["Gardiennage 24/7", "Parking", "Groupe électrogène"]
}
]
}
Récupérer un projet¶
3.3 Lotissements¶
Lister les lots disponibles¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"reference": "LOT-DLA-042",
"surface_m2": 500,
"price": 8000000,
"currency": "FCFA",
"is_available": true,
"location": {
"city": "Douala",
"district": "Logpom",
"subdivision": "Lotissement Horizon"
},
"coordinates": {
"lat": 4.0452,
"lng": 9.7122
}
}
]
}
3.4 Blog Immo¶
Lister les articles immobiliers¶
Réponse :
{
"success": true,
"data": [
{
"id": 1,
"title": "Comment financer son premier bien immobilier au Cameroun",
"slug": "financer-premier-bien-cameroun",
"excerpt": "Guide pratique pour obtenir un prêt immobilier...",
"category": "Conseils",
"author": {
"name": "Équipe Darewatch Immo"
},
"published_at": "2026-04-01T10:00:00Z",
"reading_time": 6
}
]
}
3.5 Contact Immo¶
Envoyer une demande¶
POST /contact/immo
Content-Type: application/json
{
"name": "Marie Nkolo",
"email": "marie@exemple.com",
"phone": "+237 677123456",
"subject": "Intérêt pour Villa F5 Bonamoussadi",
"message": "Je souhaite visiter le bien en référence...",
"property_id": 1
}
3.6 Carrières Immo¶
Même format que les carrières Tech avec domain=immo.
Endpoints Admin Immo (authentification requise)¶
| Méthode | Route | Action |
|---|---|---|
GET |
/admin/properties |
Lister tous les biens |
POST |
/admin/properties |
Créer un bien |
PUT |
/admin/properties/:id |
Modifier un bien |
DELETE |
/admin/properties/:id |
Supprimer un bien |
GET |
/admin/projects |
Lister les projets |
POST |
/admin/projects |
Créer un projet |
PUT |
/admin/projects/:id |
Modifier un projet |
GET |
/admin/lots |
Lister les lots |
POST |
/admin/lots |
Créer des lots |
PUT |
/admin/lots/:id |
Modifier un lot |
Liens complémentaires¶
Audit Dynamique Frontend (Tech + Immo)¶
Date d'audit : Mars 2026
Scope :apps/drwh_tech+apps/drwh_immo
Cet audit inventorie les contenus actuellement codés en dur dans les deux sites et ceux qui doivent être exposés via l'API backend pour rendre le site entièrement dynamique.
Résumé exécutif¶
pie title Répartition des contenus (Mars 2026)
"Statique (hardcodé)" : 70
"Dynamique (API réelle)" : 15
"Mock/Simulé" : 15
!!! warning "État actuel" - Les deux frontends utilisent majoritairement des données codées en dur (articles, projets, services, jobs, FAQ, testimonials, stats) - Les formulaires contact et carrière simulent l'envoi (pas d'appel API réel) - Côté Immo, un client API existe pour les propriétés — avec mode mock
État par domaine¶
drwh_tech — Contenus statiques détectés¶
| Contenu | Fichier | Priorité | API à implémenter |
|---|---|---|---|
| Blog listing | src/app/blog/page.tsx |
P1 | GET /blog/articles |
| Blog détail | src/app/blog/[slug]/page.tsx |
P1 | GET /blog/articles/:slug |
| Services | src/app/services/page.tsx |
P1 | GET /services |
| Services section homepage | src/components/ServicesSection.tsx |
P1 | GET /services |
| Réalisations/Works | src/components/WorksSection.tsx |
P2 | GET /works |
| Carrières listing | src/app/carriere/page.tsx |
P1 | GET /careers?domain=tech |
| Carrière détail | src/app/carriere/[slug]/page.tsx |
P1 | GET /careers/:slug |
| Formulaire contact | src/app/contact/page.tsx |
P0 | POST /contact/tech |
| Formulaire carrière | src/app/carriere/[slug]/page.tsx |
P0 | POST /careers/:slug/apply |
| Témoignages | src/components/TestimonialsSection.tsx |
P2 | GET /testimonials?domain=tech |
| Stats (chiffres clés) | src/components/WorksSection.tsx |
P2 | GET /works/stats |
drwh_immo — Contenus statiques détectés¶
| Contenu | Fichier | Priorité | API à implémenter |
|---|---|---|---|
| Propriétés | src/lib/data/properties.ts |
P0 | GET /properties |
| Propriétés constants | src/lib/constants.ts |
P0 | GET /properties/:id |
| Blog listing | src/app/blog/page.tsx |
P1 | GET /blog/articles?category=immo |
| Blog détail | src/app/blog/[id]/page.tsx |
P1 | GET /blog/articles/:id |
| Projets | src/app/projets/page.tsx |
P1 | GET /projects |
| Projet détail | src/app/projets/[id]/page.tsx |
P1 | GET /projects/:id |
| Lots | src/lib/data/lots.ts |
P1 | GET /lots |
| Formulaire contact | src/app/contact/page.tsx |
P0 | POST /contact/immo |
| Formulaire carrière | src/app/carriere/ |
P0 | POST /careers/:id/apply |
Niveaux de priorité¶
graph LR
P0[🔴 P0 — Critique\nFormulaires contact et carrière\nDonnées bloquantes] --> P1[🟠 P1 — Important\nBlog listings et détails\nServices et offres d'emploi]
P1 --> P2[🟡 P2 — Confort\nTémoignages & statistiques\nRéalisations]
style P0 fill:#e74c3c,color:#fff
style P1 fill:#f39c12,color:#fff
style P2 fill:#27ae60,color:#fff
P0 — Bloquants (à implémenter en premier)¶
Ces APIs sont critiques car leur absence bloque des fonctionnalités clés :
| API | Impact si absent |
|---|---|
POST /contact/tech |
Les messages de contact Tech ne partent pas |
POST /contact/immo |
Les messages de contact Immo ne partent pas |
POST /careers/:slug/apply |
Impossible de postuler à une offre |
GET /properties |
Le catalogue immobilier est vide |
P1 — Important¶
| API | Composant impacté |
|---|---|
GET /blog/articles?category=tech |
Blog Tech listing |
GET /blog/articles/:slug |
Détail article Tech |
GET /services |
Page services + homepage |
GET /careers?domain=tech |
Page carrières Tech |
GET /projects |
Liste des projets Immo |
GET /lots |
Lotissement Immo |
P2 — Confort¶
| API | Composant impacté |
|---|---|
GET /testimonials?domain=tech |
Témoignages Tech |
GET /works |
Réalisations Tech |
GET /works/stats |
Chiffres clés homepage |
Variables d'environnement concernées¶
# drwh_tech & drwh_immo
NEXT_PUBLIC_API_URL=http://localhost:3000/api ← Pointe l'API backend
NEXT_PUBLIC_ENABLE_MOCKING=false ← Désactiver le mock
Couches techniques en place¶
drwh_tech¶
src/lib/
├── public.service.ts ← Appels API backend (liste, détail, contact)
└── fallback-content.ts ← Données statiques de secours si API indisponible
Stratégie : Le frontnd appelle d'abord public.service.ts. Si l'API répond avec une erreur ou des données vides, il bascule sur fallback-content.ts.
drwh_immo¶
Feature flags disponibles :
NEXT_PUBLIC_ENABLE_MOCKING— Active les données mockNEXT_PUBLIC_MOCK_DELAY— Délai simulé (ms)
Plan de migration vers 100% dynamique¶
flowchart TD
A[1. Implémenter P0\nAPIs formulaires\ncritiques] --> B[2. Implémenter P1\nBlog + Services\n+ Offres d'emploi]
B --> C[3. Activer les appels\nAPI en production\nENABLE_MOCKING=false]
C --> D[4. Implémenter P2\nTémoignages + Stats\n+ Réalisations]
D --> E[✅ Site 100% dynamique]
style A fill:#e74c3c,color:#fff
style B fill:#f39c12,color:#fff
style C fill:#0066FF,color:#fff
style D fill:#27ae60,color:#fff
style E fill:#8e44ad,color:#fff
Liens complémentaires¶
Commandes — Référence complète¶
Tableau de synthèse¶
| Service | Développement | Build | Lancement prod | Tests |
|---|---|---|---|---|
| Tous | npm run dev |
npm run build |
npm run start |
npm run test |
| drwh_immo | npm run dev:immo |
npm run build:immo |
npm run start:immo |
npm run test:immo |
| drwh_tech | npm run dev:tech |
npm run build:tech |
npm run start:tech |
npm run test:tech |
| drwh_group | npm run dev:group |
— | php artisan serve |
php artisan test |
Commandes de développement¶
bash
# Lance drwh_tech (port 4201) + drwh_immo (port 4200)
npm run dev
````bash # Seulement drwh_immo npm run dev:immo # http://localhost:4200
# Seulement drwh_tech
npm run dev:tech # http://localhost:4201
# Seulement drwh_group (Laravel)
npm run dev:group
# ou directement
cd apps/drwh_group && php artisan serve --port=8002
```
Commandes de build¶
```bash # Build tous les services npm run build
# Build pour staging
npm run build:staging
# Build pour production
npm run build:prod
```
bash
npm run build:immo
npm run build:tech
bash
# Build spécifique pour déploiement Vercel
npm run vercel-build
Commandes de lancement (production)¶
# Lancer tous les services en mode production
npm run start
# Lancer un seul service en production
npm run start:immo
npm run start:tech
````
---
## Tests
=== "Tests unitaires (Jest)"
````bash # Tous les tests
npm run test
# Tests d'un service
npm run test:immo
npm run test:tech
# Mode watch (relance à chaque modification)
npx nx test drwh_tech --watch
```
=== "Tests end-to-end (Cypress)"
```bash # Tests e2e drwh_immo
npm run e2e:immo
# Tests e2e drwh_tech
npm run e2e:tech
```
=== "Tests Laravel"
`bash
cd apps/drwh_group
php artisan test
`
---
## Linting et qualité de code
```bash
# Lint tous les fichiers TypeScript
npm run lint
# Lint par service
npm run lint:immo
npm run lint:tech
# Vérification TypeScript complète
npm run type-check
````
---
## Commandes NX
=== "Graph des dépendances"
`bash
npx nx graph
# Ouvre une interface web pour visualiser les dépendances
`
=== "Vider le cache"
`bash
npx nx reset
# À utiliser si vous avez des comportements inattendus
`
=== "Build affecté (CI)"
`bash
# Build uniquement les projets modifiés depuis main
npx nx affected --target=build --base=main
npx nx affected --target=test --base=main
`
=== "Lister les projets"
`bash
npx nx show projects
`
---
## Commandes Laravel (drwh_group)
=== "Développement"
````bash
cd apps/drwh_group
# Lancer le serveur
php artisan serve --port=8002
# Migrations base de données
php artisan migrate
# Vider tous les caches
php artisan optimize:clear
# Générer clé application
php artisan key:generate
```
=== "Base de données"
```bash # Créer et exécuter les migrations
php artisan migrate
# Revenir en arrière d'une migration
php artisan migrate:rollback
# Mettre à zéro et re-exécuter
php artisan migrate:fresh --seed
# Lancer les seeders
php artisan db:seed
```
=== "Cache"
`bash
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
`
---
## Commandes Docker
```bash
# Démarrer tous les conteneurs
docker compose up --build
# Arrêter tous les conteneurs
docker compose down
# Logs d'un service
docker compose logs -f drwh_tech
# Reconstruire un seul service
docker compose up --build drwh_tech
````
---
## Variables d'environnement — setup
```bash
# Afficher les instructions de configuration
npm run env:setup
Liens complémentaires¶
SEO & Référencement à étages¶
Objectif¶
Mettre en place un référencement cohérent et complémentaire entre les trois applications DAREWATCH :
| Application | URL | Spécialité SEO |
|---|---|---|
| Darewatch Tech | tech.darewatchgroup.com | Services IT, formations, recrutement tech |
| Darewatch Immo | immo.darewatchgroup.com | Immobilier Cameroun, projets, lotissements |
| Darewatch Group | darewatchgroup.com | Marque, corporate, portefeuille |
Le principe des étages SEO¶
graph TD
E1["🏢 Étage 1 — Marque (Brand SEO)\nRequêtes de marque et confiance\n'Darewatch', 'Darewatch Tech', 'Darewatch Immo'"]
E2["🏗️ Étage 2 — Métiers (Piliers)\nPages piliers par domaine\n'/services', '/immobilier', '/blog', '/carriere'"]
E3["🔍 Étage 3 — Longue traîne\nPages détaillées à fort potentiel\nArticles blog, fiches poste, projets, FAQ"]
E1 --> E2
E2 --> E3
style E1 fill:#0066FF,color:#fff
style E2 fill:#27ae60,color:#fff
style E3 fill:#f39c12,color:#fff
Étage 1 — SEO de marque¶
Pages concernées : Page d'accueil de chaque application
Implémentation requise :
tsx
export const metadata: Metadata = {
title: 'Darewatch Tech — Agence Digitale & Informatique Cameroun',
description: 'DAREWATCH TECH : services de développement web, mobile, formation IT, cybersécurité et cloud computing à Douala, Cameroun.',
openGraph: {
title: 'Darewatch Tech',
description: 'Agence digitale à Douala, Cameroun',
url: 'https://tech.darewatchgroup.com',
siteName: 'Darewatch Tech',
locale: 'fr_FR',
type: 'website',
},
};
tsx
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'DAREWATCH CONSULTING SARL',
url: 'https://tech.darewatchgroup.com',
logo: 'https://tech.darewatchgroup.com/logo.png',
address: {
'@type': 'PostalAddress',
addressLocality: 'Douala',
addressRegion: 'Littoral',
addressCountry: 'CM',
},
sameAs: [
'https://immo.darewatchgroup.com',
'https://darewatchgroup.com',
],
};
Étage 2 — Pages piliers¶
Darewatch Tech — Pages piliers¶
| Page pilier | URL | Mots-clés principaux |
|---|---|---|
| Services informatiques | /services |
entreprise informatique douala, agence digitale cameroun |
| À propos | /about |
darewatch tech, société IT douala |
| Carrières | /carriere |
emploi développeur cameroun, recrutement ingénieur devops |
| Blog Tech | /blog |
actualités IT cameroun, formation développement |
| Contact | /contact |
contact agence digitale cameroun |
Darewatch Immo — Pages piliers¶
| Page pilier | URL | Mots-clés principaux |
|---|---|---|
| Immobilier | /immobilier |
immobilier cameroun, villa à vendre douala |
| Projets | /projets |
projets immobiliers douala, résidence construction cameroun |
| Lotissement | /lotissement |
terrain à vendre douala, lotissement cameroun |
| Blog Immo | /blog |
actualités immobilier cameroun |
| Contact | /contact |
contact promoteur immobilier douala |
Étage 3 — Longue traîne¶
Mots-clés Tech (prioritaires)¶
=== "Développement Web" - entreprise informatique cameroun - agence digitale cameroun - développement web cameroun - création site web douala - agence nextjs cameroun - développeur react cameroun - développement application mobile cameroun
=== "Infrastructure & Cloud" - cloud computing cameroun - devops cameroun - infrastructure réseau entreprise - infogérance informatique cameroun - maintenance informatique entreprise
=== "Cybersécurité" - cybersécurité cameroun - audit cybersécurité douala - pentest cameroun - sécurité informatique entreprise
=== "Formation" - formation développement web cameroun - formation devops cameroun - bootcamp développement cameroun - formation cybersécurité cameroun
Mots-clés Immo (prioritaires)¶
=== "Biens immobiliers" - immobilier cameroun - villa à vendre douala - appartement douala - terrain à vendre douala bonamoussadi - maison à vendre yaoundé
=== "Projets & Construction" - projets immobiliers douala - promoteur immobilier cameroun - résidence sécurisée douala - construction immobilière cameroun
=== "Transactionnel" - acheter terrain douala - investissement immobilier cameroun - prix immobilier douala 2026
Implémentation technique — checklist¶
Pour chaque page¶
- [ ]
<title>unique et descriptif (50-60 caractères) - [ ]
<meta description>(150-160 caractères) - [ ] URL canonique
<link rel="canonical"> - [ ] Open Graph tags (og:title, og:description, og:image, og:url)
- [ ] JSON-LD schema (Organization, Article, JobPosting, Product selon le type)
- [ ] Balises
<h1>uniques par page - [ ] Images avec attribut
altdescriptif
Sitemap dynamique (Next.js)¶
// apps/drwh_immo/src/app/sitemap.ts
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const properties = await fetchProperties();
const articles = await fetchArticles();
return [
{
url: "https://immo.darewatchgroup.com",
changeFrequency: "daily",
priority: 1,
},
{
url: "https://immo.darewatchgroup.com/immobilier",
changeFrequency: "daily",
priority: 0.9,
},
...properties.map((p) => ({
url: `https://immo.darewatchgroup.com/immobilier/${p.id}`,
changeFrequency: "weekly",
priority: 0.8,
})),
...articles.map((a) => ({
url: `https://immo.darewatchgroup.com/blog/${a.id}`,
changeFrequency: "monthly",
priority: 0.7,
})),
];
}
Robots.txt¶
// apps/drwh_immo/src/app/robots.ts
export default function robots(): MetadataRoute.Robots {
return {
rules: { userAgent: "*", allow: "/", disallow: ["/api/", "/admin/"] },
sitemap: "https://immo.darewatchgroup.com/sitemap.xml",
};
}
Maillage interne entre les applications¶
graph LR
G[darewatchgroup.com] -->|"Lien → Tech"| T[tech.darewatchgroup.com]
G -->|"Lien → Immo"| I[immo.darewatchgroup.com]
T -->|"Lien → Group"| G
T -->|"Lien → Immo"| I
I -->|"Lien → Group"| G
I -->|"Lien → Tech"| T
Chaque application doit avoir des liens vers les deux autres dans son footer/navigation. Cela renforce l'autorité de domaine de tout l'écosystème Darewatch.
Liens complémentaires¶
FAQ¶
Questions frequentes¶
Pourquoi y a-t-il trois applications au lieu d'un seul site ?¶
Le projet est structure en trois applications pour separer clairement les usages :
drwh_grouppour la vitrine corporate et les contenus institutionnelsdrwh_techpour les services IT, la communication technique et le recrutement techdrwh_immopour les contenus immobiliers, les projets et les fiches de biens
Cette separation simplifie le maintien du code, le SEO par domaine metier et les futurs deploiements.
Pourquoi drwh_group utilise Laravel alors que les autres utilisent Next.js ?¶
drwh_group repose sur Laravel et Livewire pour beneficier d'un back-office PHP coherent avec certains besoins metier et de publication.
drwh_tech et drwh_immo utilisent Next.js pour profiter du rendu hybride, du SEO avance, des routes applicatives et de l'integration frontend moderne.
Comment lancer rapidement le projet en local ?¶
Le chemin le plus simple est :
Pour les autres applications, remplacez simplement le nom du projet par drwh_immo ou utilisez Docker pour lancer l'ensemble.
Consultez aussi :
Ou modifier les contenus visibles sur les sites ?¶
Cela depend du service :
- sur
drwh_group, une partie des contenus provient des vues Blade, composants Livewire et donnees Laravel - sur
drwh_tech, les sections proviennent des composants et des services de contenu danssrc/ - sur
drwh_immo, les pages utilisent des composants Next.js, du contenu dynamique et des endpoints metier
Pour comprendre la structure exacte, voir :
Que faire si npm install ou npm run dev echoue ?¶
Verifiez dans cet ordre :
- La version de Node.js doit etre compatible avec le monorepo.
- Les dependances doivent etre installees depuis la racine
drwh_front. - Le fichier
.envattendu doit exister pour l'application concernee. - Les ports utilises ne doivent pas deja etre occupes.
Commandes utiles :
A quoi servent les fichiers .env ?¶
Les fichiers .env contiennent les variables d'environnement : URLs d'API, cles, mode mock, configuration applicative.
Ils ne doivent pas etre partages publiquement car ils peuvent contenir des informations sensibles ou specifiques a un environnement.
Voir : Variables d'environnement
Comment savoir si une page consomme de vraies donnees backend ou un fallback ?¶
Il faut verifier le service de contenu ou le client API utilise par la page. Certaines pages utilisent un mode fallback ou mock lorsque l'API n'est pas disponible.
La page suivante detaille l'etat actuel : Audit dynamique frontend
Comment imprimer une page de la documentation ?¶
Le plugin print-site ajoute une vue d'impression/export. Vous pouvez aussi utiliser l'impression du navigateur sur une page precise.
Par ou commencer quand on rejoint le projet ?¶
L'ordre recommande est le suivant :
- Lire Presentation de Darewatch
- Lire Architecture Microservices
- Lire Monorepo & NX
- Suivre Prerequis puis Installation pas a pas