KT
Connexion…
📶 Hors ligne — Mode consultation activé · Les données sont sauvegardées localement
Tableau de bord
🔔
Tableau de bord
🏗️
🔔
Local
🏗️
Chantiers actifs
0
📊
Avancement moyen
avancement moyen
💶
Budget consommé
⚠️
Alertes actives
0
aucune alerte
🏦
Santé financière · ISF
Calcul en attente de données
⏱️
Dérive temporelle
Calcul en attente de données
🏗️
Chantiers en cours
créer le premier
Aucun chantier actif
🔔
Alertes & Notifications
💰
Budget global
Détail →
Chargement…
👷
Équipe
Gérer →
Chargement…
Tous (0)
En cours (0)
Planifié (0)
Terminé (0)
Alerte (0)
🏗️
Aucun chantier
Cliquez sur "+ Nouveau chantier" pour commencer
Budget total prévu
Ensemble des postes
Dépenses réelles
Consommé à date
Reste à dépenser
Sur le budget prévu
Écart global
💶
Postes de dépenses
PostePrévuRéelÉcart%
🧾
Dépenses saisies
📊
Consommation par poste — Prévu vs Réel
Compagnons
Sous-traitants
Affectations
Feuilles de temps
COMPAGNONQUALIFICATIONCHANTIER AFFECTÉPRÉSENCE SEMAINEHEURES / SEM.TAUX HORAIRESTATUSACTIONS
Tous
Plans
Devis
Factures
Photos
Chantiers actifs
0
Aucun chantier
Avancement moyen
0%
Tous chantiers actifs
Aucune donnée
Budget consommé
0€
budget non défini
Aucune dépense
Alertes actives
0
Incidents en cours
✓ Tout va bien
📈
Avancement par chantier
🏗️
Aucun chantier — créez votre premier chantier
💹
Rentabilité par chantier
Ajoutez des chantiers pour voir la rentabilité
📊
Analyse des écarts — Vue globale
📊
Chargement…
📐 Cette page documente l'architecture technique complète de Kantiir — schéma de base de données, API endpoints, et recommandations technologiques.
🏛️ Architecture Globale
Architecture 3-tiers découplée : Frontend React/PWA + Backend FastAPI (Python) + PostgreSQL. Déployée sur Docker / Kubernetes avec authentification JWT et rôles (Admin, Conducteur, Chef de chantier, Consultation).
┌─────────────────────────────────────────────────────────────────┐ │ ARCHITECTURE CHANTIERPRO │ └─────────────────────────────────────────────────────────────────┘ Frontend (React 18 / PWA) ├── Dashboard // KPIs temps réel ├── Planning (Gantt.js) // Gantt interactif drag & drop ├── Budget (Chart.js) // Tableaux de coûts ├── Équipes & Présences ├── Documents (PDF viewer) └── Performance (Analytics) Backend (Python FastAPI) ├── /api/v1/auth // JWT + Refresh tokens ├── /api/v1/chantiers // CRUD chantiers ├── /api/v1/taches // Gestion Gantt ├── /api/v1/couts // Budget & dépenses ├── /api/v1/equipes // RH & présences ├── /api/v1/documents // Upload S3/Minio └── /api/v1/rapports // Export PDF/Excel Base de données (PostgreSQL 15) ├── Chantiers, Phases, Taches ├── Couts_Prevus, Couts_Reels ├── Equipes, Membres, Presences └── Documents, Annotations Infrastructure ├── Docker Compose / K8s ├── Redis (cache, sessions) ├── Minio (stockage docs) └── Celery (tâches async: exports PDF)
🗃️ Schéma de Base de Données
-- TABLE: Chantiers CREATE TABLE chantiers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), code VARCHAR(20) UNIQUE NOT NULL, -- CH-2026-001 nom VARCHAR(255) NOT NULL, adresse TEXT, client VARCHAR(255), maitre_oeuvre VARCHAR(255), responsable_id UUID REFERENCES utilisateurs(id), date_debut DATE, date_fin_prevue DATE, date_fin_reelle DATE, statut VARCHAR(20) DEFAULT 'planifie', -- planifie|encours|alerte|termine budget_prevu DECIMAL(15,2), avancement_pct DECIMAL(5,2) DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); -- TABLE: Taches (Gantt) CREATE TABLE taches ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), chantier_id UUID REFERENCES chantiers(id) ON DELETE CASCADE, phase VARCHAR(100), nom VARCHAR(255) NOT NULL, date_debut DATE, date_fin DATE, duree_jours INTEGER, avancement_pct DECIMAL(5,2) DEFAULT 0, statut VARCHAR(20) DEFAULT 'planifie', equipe_id UUID REFERENCES equipes(id), dependances UUID[], -- IDs tâches prérequises est_critique BOOLEAN DEFAULT FALSE, retard_jours INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); -- TABLE: Couts CREATE TABLE couts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), chantier_id UUID REFERENCES chantiers(id) ON DELETE CASCADE, categorie VARCHAR(50), -- materiaux|mdo|sous_traitance|transport|securite libelle VARCHAR(255), montant_prevu DECIMAL(15,2), montant_reel DECIMAL(15,2), ecart DECIMAL(15,2) GENERATED ALWAYS AS (montant_reel - montant_prevu) STORED, fournisseur VARCHAR(255), date_saisie DATE DEFAULT CURRENT_DATE, document_ref UUID REFERENCES documents(id), saisi_par UUID REFERENCES utilisateurs(id) ); -- TABLE: Membres / Équipes CREATE TABLE membres ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), nom VARCHAR(100), prenom VARCHAR(100), qualification VARCHAR(100), -- Maçon N3P2, Grutier CACES... type_membre VARCHAR(20) DEFAULT 'salarie', -- salarie|sous_traitant taux_horaire DECIMAL(8,2), telephone VARCHAR(20), email VARCHAR(255) ); -- TABLE: Presences CREATE TABLE presences ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), membre_id UUID REFERENCES membres(id), chantier_id UUID REFERENCES chantiers(id), date_presence DATE, statut VARCHAR(20), -- present|absent|conge|maladie heure_debut TIME, heure_fin TIME, heures_travail DECIMAL(5,2), UNIQUE(membre_id, chantier_id, date_presence) ); -- TABLE: Documents CREATE TABLE documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), chantier_id UUID REFERENCES chantiers(id), nom_fichier VARCHAR(255), type_doc VARCHAR(30), -- plan|devis|facture|photo|rapport taille_octets BIGINT, chemin_stockage TEXT, -- URL S3/Minio annotations JSONB DEFAULT '[]', -- [{x,y,texte,auteur}] uploade_par UUID REFERENCES utilisateurs(id), uploaded_at TIMESTAMPTZ DEFAULT NOW() );
🔌 API Endpoints (FastAPI)
## AUTH POST /api/v1/auth/login # { email, password } → JWT token POST /api/v1/auth/refresh # Refresh token GET /api/v1/auth/me # Profil utilisateur courant ## CHANTIERS GET /api/v1/chantiers # ?statut=encours&page=1&limit=20 POST /api/v1/chantiers # Créer chantier GET /api/v1/chantiers/{id} # Détail complet + KPIs PUT /api/v1/chantiers/{id} # Modifier DELETE /api/v1/chantiers/{id} # Archiver GET /api/v1/chantiers/{id}/kpis # Dashboard KPIs temps réel ## PLANNING (GANTT) GET /api/v1/chantiers/{id}/taches # Liste tâches Gantt POST /api/v1/chantiers/{id}/taches # Créer tâche PUT /api/v1/taches/{id} # Modifier (drag & drop) PUT /api/v1/taches/{id}/avancement # { pct: 75 } GET /api/v1/chantiers/{id}/chemin-critique# Calcul CPM ## BUDGET & COÛTS GET /api/v1/chantiers/{id}/couts # ?categorie=materiaux&mois=2024-02 POST /api/v1/chantiers/{id}/couts # Saisir dépense GET /api/v1/chantiers/{id}/budget/summary# Prévu vs réel + écarts GET /api/v1/chantiers/{id}/budget/evolution# Courbe S ## ÉQUIPES & PRÉSENCES GET /api/v1/membres # ?chantier={id}&date=2024-02-15 POST /api/v1/presences # Pointer présences du jour GET /api/v1/chantiers/{id}/presences/semaine# Vue semaine GET /api/v1/membres/{id}/temps # Feuille de temps ## DOCUMENTS GET /api/v1/chantiers/{id}/documents # ?type=plan POST /api/v1/chantiers/{id}/documents # multipart/form-data upload POST /api/v1/documents/{id}/annotations # { x, y, texte, auteur } ## RAPPORTS & EXPORTS GET /api/v1/chantiers/{id}/rapport/pdf # Rapport de suivi PDF (Celery async) GET /api/v1/chantiers/{id}/rapport/xlsx # Export Excel budget GET /api/v1/dashboard/kpis # KPIs globaux (admin)
⚙️ Pseudo-code — Calcul automatique des KPIs
# calculer_kpis_chantier(chantier_id) — FastAPI endpoint async def get_kpis(chantier_id: UUID, db: AsyncSession): chantier = await db.get(Chantier, chantier_id) taches = await db.query(Tache).filter(chantier_id=chantier_id).all() couts = await db.query(Cout).filter(chantier_id=chantier_id).all() # Avancement pondéré par durée des tâches avancement = sum(t.avancement_pct * t.duree_jours for t in taches) \ / sum(t.duree_jours for t in taches) # Calcul retard (date fin théorique vs aujourd'hui) retard_jours = (date.today() - chantier.date_fin_prevue).days \ if avancement < 100 else 0 # Écarts budgétaires budget_prevu = sum(c.montant_prevu for c in couts) budget_reel = sum(c.montant_reel for c in couts) depassement = budget_reel - budget_prevu # Indice de performance (IPI) valeur_acquise = budget_prevu * (avancement / 100) ipi = valeur_acquise / budget_reel if budget_reel > 0 else 1.0 # Génération alertes alertes = [] if depassement > budget_prevu * 0.05: alertes.append({"type": "budget", "seuil": ">5%"}) if retard_jours > 5: alertes.append({"type": "delai", "jours": retard_jours}) return KPIsResponse( avancement_pct=round(avancement, 1), retard_jours=retard_jours, budget_prevu=budget_prevu, budget_reel=budget_reel, depassement=depassement, ipi=round(ipi, 3), alertes=alertes )
📱 Wireframes Navigation Utilisateur
Flux principal pour un Conducteur de travaux en mobilité chantier :
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ LOGIN │───>│ DASHBOARD │───>│ CHANTIER │───>│ GANTT │ │ │ │ │ │ DÉTAIL │ │ PLANNING │ │ email/mdp │ │ KPIs globaux│ │ │ │ │ │ 2FA optionnel │ Alertes │ │ Avancement │ │ Drag & drop │ │ │ │ Chantiers │ │ Budget │ │ Dépendances │ │ │ │ Présence/j │ │ Tâches │ │ Chemin crit.│ └─────────────┘ └──────┬──────┘ └──────┬──────┘ └─────────────┘ │ │ ┌─────▼──────┐ ┌──────▼──────┐ ┌─────────────┐ │ POINTAGE │ │ BUDGET │───>│ RAPPORT │ │ PRÉSENCES │ │ DÉPENSES │ │ PDF/Excel │ │ │ │ │ │ │ │ QR code ou │ │ Saisie pose │ │ Période │ │ manuel │ │ Catégorie │ │ Indicateurs │ │ ✓ / ✗ / 🏖 │ │ Montant │ │ Download │ └─────┬──────┘ └──────┬──────┘ └─────────────┘ │ │ ┌─────▼──────┐ ┌──────▼──────┐ │ DOCUMENTS │ │ PERFORMANCE │ │ │ │ │ │ Upload PDF │ │ Productivité│ │ Photos │ │ Rentabilité │ │ Annot. mob.│ │ Écarts │ └────────────┘ └─────────────┘ RÔLES & ACCÈS : Administrateur : Accès total + gestion utilisateurs + paramètres Conducteur : Tous les modules + création chantiers + exports Chef de chantier : Pointage, tâches, documents de son chantier Consultation : Lecture seule tableau de bord + rapports
🎯 Frontend
React 18 · TypeScript · Vite
TailwindCSS · Recharts
Gantt.js / DHTMLX Gantt
React Query (cache API)
PWA offline (Service Worker)
i18n : fr / en
⚙️ Backend
Python 3.12 · FastAPI
SQLAlchemy 2.0 (async)
Alembic (migrations)
Celery + Redis (exports)
WeasyPrint (PDF)
OpenPyXL (Excel)
🗄️ Infrastructure
PostgreSQL 15 (primary DB)
Redis 7 (cache + sessions)
Minio / S3 (documents)
Docker Compose + Nginx
GitHub Actions (CI/CD)
Sentry (monitoring)
Rapports enregistrés
Aucun rapport. Créez-en un nouveau.
💱 Devise
Choisissez la devise utilisée dans les budgets, rapports et exports PDF.
🏢 Logo de l'entreprise
Votre logo apparaîtra dans la sidebar et en haut de vos rapports PDF. Il sera redimensionné à 300px max et compressé automatiquement.
🖼️
Glissez votre logo ici ou cliquez pour sélectionner
PNG, JPG, SVG — redimensionné à 300px max, compressé automatiquement
👤 Compte & Organisation