CRM ETASCOM V3 est un système de gestion industrielle complet développé pour l'usine ETASCOM Automotive (fabrication de mousse de protection et adhésifs). Cette application Next.js moderne intègre tous les aspects de la gestion industrielle : des achats et matières premières à la production et livraison des produits finis.
Frontend:
├── Next.js 15.3.4 (App Router)
├── React 19.1.0
├── TypeScript 5.8.3
├── Tailwind CSS 4.1.11
├── React Hook Form 7.59.0
├── TanStack React Query 5.81.5 (State Management)
├── React Aria Components 1.10.1
├── Radix UI 1.4.2 (Composants)
├── Lucide React 0.525.0 (Icônes)
├── ApexCharts 4.7.0 (Graphiques)
├── Recharts 2.15.1 (Graphiques)
├── React Leaflet 5.0.0 (Cartes)
├── Next Themes 0.4.6 (Dark/Light Mode)
├── i18next 25.2.1 (Internationalisation)
└── Motion 12.19.2 (Animations)
Backend:
├── Next.js API Routes
├── Prisma 6.10.1 (ORM)
├── PostgreSQL 15
├── NextAuth.js 4.24.11
├── AWS SDK S3 3.839.0 (Storage)
├── Nodemailer 7.0.4 (Email)
├── Bcrypt 6.0.0 (Hashing)
└── Zod 3.25.67 (Validation)
Infrastructure:
├── Docker (optionnel)
├── Vercel/Netlify (déploiement)
├── Supabase/Neon (base de données)
└── AWS S3 (stockage fichiers)
Qualité de Code:
├── ESLint 9.30.0 (Linting)
├── Prettier 3.6.2 (Formatage)
├── TypeScript 5.8.3 (Type Safety)
└── Autoprefixer 10.4.21 (CSS)
UI/UX Libraries:
├── React Aria Components 1.10.1 (Accessibilité)
├── Radix UI 1.4.2 (Composants primitifs)
├── Lucide React 0.525.0 (Icônes)
├── Remix Icons 4.6.0 (Icônes supplémentaires)
├── Class Variance Authority 0.7.1 (Variants CSS)
├── Tailwind Merge 3.3.1 (Fusion classes)
├── CLSX 2.1.1 (Classes conditionnelles)
└── Vaul 1.1.2 (Drawer/Modal)
Formulaires & Validation:
├── React Hook Form 7.59.0 (Gestion formulaires)
├── Hookform Resolvers 5.1.1 (Résolveurs)
├── Zod 3.25.67 (Validation schémas)
├── Input OTP 1.4.2 (Codes OTP)
└── React Day Picker 9.7.0 (Sélecteur dates)
État & Données:
├── TanStack React Query 5.81.5 (Server State)
├── TanStack React Table 8.21.3 (Tableaux)
├── React Wrap Balancer 1.1.1 (Texte équilibré)
└── React Resizable Panels 3.0.3 (Panneaux)
Graphiques & Visualisation:
├── ApexCharts 4.7.0 (Graphiques avancés)
├── React ApexCharts 1.7.0 (Wrapper React)
├── Recharts 2.15.1 (Graphiques React)
└── React Leaflet 5.0.0 (Cartes interactives)
Animations & Interactions:
├── Motion 12.19.2 (Animations)
├── DND Kit 6.3.1 (Drag & Drop)
├── Embla Carousel 8.6.0 (Carrousels)
├── React Aspect Ratio 1.1.9 (Ratios)
└── Sonner 2.0.5 (Notifications)
Internationalisation:
├── i18next 25.2.1 (i18n core)
├── React i18next 15.5.3 (React integration)
├── Next i18next 15.4.2 (Next.js integration)
└── i18next Browser Language Detector 8.2.0
Utilitaires:
├── Date-fns 4.1.0 (Manipulation dates)
├── CMDK 1.1.1 (Command palette)
├── Faker.js 9.8.0 (Données de test)
└── Headless Tree 1.2.0 (Arbres)
src/app/(protected)/
├── sales/ # Module Commercial
│ ├── offres/ # Gestion des offres
│ ├── projets/ # Gestion des projets
│ └── clients/ # Gestion des clients
├── production/ # Module Production
│ ├── ordres/ # Ordres de fabrication
│ ├── operations/ # Opérations
│ └── qualite/ # Contrôles qualité
├── achat/ # Module Achats
│ ├── commandes/ # Bons de commande
│ ├── fournisseurs/ # Gestion fournisseurs
│ └── factures/ # Factures
├── stock/ # Module Stock
│ ├── niveaux/ # Niveaux de stock
│ ├── mouvements/ # Mouvements
│ └── emplacements/ # Gestion des zones
└── raws/ # Matières Premières
├── reception/ # Réceptions
├── stock/ # Stock MP
└── batches/ # Gestion des lots
├── communication/ # Communication Interne
├── actualites/ # Actualités et posts
├── faq/ # Questions fréquentes
├── documentation/ # Centre d'aide
└── demandes/ # Système de demandes
├── etiquettes/ # Système d'Étiquettes
├── generation/ # Génération d'étiquettes
├── impression/ # Impression et statuts
└── tracabilite/ # Traçabilité des produits
git clone https://github.com/yboulhilat/ETASCOM_CRM_V3.git
cd CRM_ETASCOM_V2
npm install
# ou
yarn install
cp .env.example .env.local
Éditer le fichier .env.local :
DATABASE_URL="postgresql://postgres.uxaispxvqujpswfyupdk:[YOUR-PASSWORD]@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres?pgbouncer=true"
# Direct connection to the database. Used for migrations.
DIRECT_URL="postgresql://postgres.uxaispxvqujpswfyupdk:[YOUR-PASSWORD]@aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres"
# Next Auth Config #
NEXT_PUBLIC_API_URL=http://localhost:3000/api
NEXT_PUBLIC_BASE_PATH=http://localhost:3000/
NEXTAUTH_URL=http://localhost:3000/
NEXTAUTH_SECRET=N3G2xT44ovZWp24HUQE54JRJq63ZOhhOHe1uQnsQxs4=
GOOGLE_CLIENT_ID=your_gogle_oauth2_client_id
GOOGLE_CLIENT_SECRET=your_gogle_oauth2_secret_key
# Storage Configuration (AWS S3 or DigitalOcean Spaces)
STORAGE_TYPE=aws
STORAGE_ACCESS_KEY_ID=AKIAZBA3WKIG3F3OSOR7
STORAGE_SECRET_ACCESS_KEY=G1Bg1Ns4ORPo/R0u+qyXf7tsLH/x+fIGyRRWsbDI
STORAGE_REGION=eu-north-1
STORAGE_BUCKET=etascom
STORAGE_ENDPOINT=https://etascom.s3.eu-north-1.amazonaws.com/
STORAGE_FORCE_PATH_STYLE=true
STORAGE_CDN_URL=https://etascom.s3.eu-north-1.amazonaws.com/
# SMTP Credentials
SMTP_HOST=your_smtp_host
SMTP_PORT=your_smtp_port
SMTP_SECURE=false
SMTP_USER=no-reply@domain.com
SMTP_PASS=your_smtp_pass
# Additional Optional Settings
SMTP_SENDER=Metronic
SMTP_FROM=no-reply@domain.com
# Google reCAPTCHA v2
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=6LdHvcQrAAAAANBIIOmFRX0co60rvwD6u3qZbsPR
RECAPTCHA_SECRET_KEY=6LdHvcQrAAAAAEz8HcOxwB5NU74XUqjGVxP8EMik
# Générer le client Prisma
npx prisma generate
# Appliquer les migrations
npx prisma migrate deploy
# (Optionnel) Peupler avec des données de test
npx prisma db seed
npm run dev
# ou
yarn dev
# ou
pnpm dev
L'application sera accessible sur http://localhost:3000
# Développement
npm run dev # Serveur de développement Next.js
npm run build # Build de production
npm run start # Serveur de production
npm run build:staging # Build pour staging
# Qualité de code
npm run lint # Linting ESLint
npm run format # Formatage Prettier
# Base de données
npm run prisma:generate # Générer le client Prisma
npm run prisma:push # Pousser le schéma vers la DB
npm run prisma:migrate # Créer une migration
npm run prisma:seed # Peupler la DB avec des données
npm run prisma:setup # Configuration initiale
# Générer le client Prisma
npx prisma generate
# Appliquer les migrations
npx prisma migrate dev --name "add_erp_models"
# Pousser le schéma (développement)
npx prisma db push
# Peupler avec des données de test
npx prisma db seed
# Ouvrir Prisma Studio
npx prisma studio
# Vérifier le schéma
npx prisma validate
# 1. Générer le client Prisma
npx prisma generate
# 2. Créer la migration
npx prisma migrate dev --name "add_erp_models"
# 3. Vérifier le schéma
npx prisma db push
# 4. Lancer l'application
npm run dev
# Vérifier la validité du schéma
npx prisma validate
# Visualiser la base de données
npx prisma studio
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ PLANIFICATION │───▶│ COMMANDE MP │───▶│ RÉCEPTION │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ CRÉATION OF │◀───│ MOUVEMENT STOCK │◀───│ CRÉATION LOT │
│ │ │ ENTRÉE │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ CONSOMMATION MP │───▶│ EXÉCUTION OPS │───▶│ CONTRÔLE QUAL │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ PRODUCTION PF │───▶│ MOUVEMENT STOCK │───▶│ STOCKAGE PF │
│ │ │ SORTIE │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
Supplier)model Supplier {
id String @id @default(cuid())
code String @unique
name String
type String @default("SUPPLIER") // SUPPLIER, SUBCONTRACTOR
phone String?
email String?
website String?
currencyId String? // Devise préférée
isActive Boolean @default(true)
// Relations
rawMaterials RawMaterial[]
purchaseOrders PurchaseOrder[]
receptionNotes ReceptionNote[]
stockMovements StockMovement[]
addresses Address[]
contacts Contact[]
legalIdentifiers LegalIdentifier[]
}
PurchaseOrder)model PurchaseOrder {
id String @id @default(cuid())
number String @unique
supplierId String
orderDate DateTime @default(now())
expectedDate DateTime?
status String @default("DRAFT") // DRAFT, CONFIRMED, PARTIALLY_RECEIVED, RECEIVED, CANCELLED
totalAmount Float @default(0)
currencyId String?
notes String?
// Relations
supplier Supplier
lines PurchaseOrderLine[]
stockMovements StockMovement[]
}
PurchaseOrderLine)model PurchaseOrderLine {
id String @id @default(cuid())
purchaseOrderId String
rawMaterialId String
quantity Float
unitPrice Float
totalPrice Float
receivedQuantity Float @default(0)
remainingQuantity Float // Calculé : quantity - receivedQuantity
notes String?
}
ReceptionNote)model ReceptionNote {
id String @id @default(cuid())
number String @unique
supplierId String
receptionDate DateTime @default(now())
status String @default("DRAFT") // DRAFT, RECEIVED, VALIDATED
notes String?
// Relations
supplier Supplier
files File[]
}
DeliveryNote)model DeliveryNote {
id String @id @default(cuid())
number String @unique
clientId String
transporterId String?
deliveryDate DateTime
status String @default("DRAFT") // DRAFT, CONFIRMED, SHIPPED, DELIVERED
notes String?
// Relations
client Client
transporter Transporter?
files File[]
}
StockMovementType)enum StockMovementType {
// MOUVEMENTS D'ENTRÉE
IN // Entrée générale
SUPPLIER_RECEIPT // Réception fournisseur
RETURN_FROM_SUPPLIER // Retour fournisseur
PRODUCTION // Production (création produit fini)
ADJUSTMENT_IN // Ajustement d'inventaire (entrée)
// MOUVEMENTS DE SORTIE
OUT // Sortie générale
CUSTOMER_DELIVERY // Livraison client
RETURN_TO_SUPPLIER // Retour fournisseur (défectueux)
CONSUMPTION // Consommation (matière première vers production)
ADJUSTMENT_OUT // Ajustement d'inventaire (sortie)
// MOUVEMENTS DE TRANSFERT
TRANSFER // Transfert interne
WAREHOUSE_TRANSFER // Transfert entre entrepôts
LOCATION_TRANSFER // Transfert entre emplacements
// MOUVEMENTS SPÉCIAUX
CUSTOMER_RETURN // Retour client
DAMAGED // Produit endommagé
EXPIRED // Produit expiré
LOST // Produit perdu
STOLEN // Produit volé
QUALITY_REJECT // Rejet qualité
SCRAP // Mise au rebut
}
1. Création Commande d'Achat (PurchaseOrder)
↓
2. Confirmation avec Fournisseur
↓
3. Réception Marchandise (ReceptionNote)
↓
4. Validation Qualité
↓
5. Mise en Stock (StockMovement: SUPPLIER_RECEIPT)
↓
6. Facturation Fournisseur
1. Commande Client (SalesOrder)
↓
2. Préparation Commande
↓
3. Création Bon de Livraison (DeliveryNote)
↓
4. Expédition (StockMovement: CUSTOMER_DELIVERY)
↓
5. Livraison Client
↓
6. Facturation Client
RETOUR CLIENT:
- StockMovement: CUSTOMER_RETURN
- Réintégration en stock
RETOUR FOURNISSEUR:
- StockMovement: RETURN_TO_SUPPLIER
- Sortie de stock
- Crédit fournisseur
app/(protected)/stock/movements/page.tsx - Mouvements de stockapp/(protected)/stock/lots/page.tsx - Gestion des lotsapp/(protected)/stock/locations/page.tsx - Emplacementsapp/(protected)/purchases/orders/page.tsx - VIDE (à implémenter)app/(protected)/purchases/suppliers/page.tsx - Gestion fournisseursapp/(protected)/purchases/receptions/page.tsx - Réceptionsapp/(protected)/sales/deliveries/page.tsx - Livraisonsapp/(protected)/purchases/returns/page.tsx - Retours fournisseursapp/(protected)/sales/returns/page.tsx - Retours clientsLe système est très complet au niveau du schéma mais nécessite l'implémentation des interfaces utilisateur ! 🚀
ETASCOM_CRM_V3_NEXT_JS/
├── app/ # Next.js App Router
│ ├── (auth)/ # Pages d'authentification
│ ├── (protected)/ # Pages protégées
│ └── api/ # API Routes
├── components/ # Composants réutilisables
│ ├── ui/ # Composants UI de base
│ ├── common/ # Composants communs
│ └── keenicons/ # Icônes
├── prisma/ # Schéma et migrations
│ ├── schema.prisma # ✅ Schéma ERP complet (30+ modèles)
│ ├── data/ # Données de seed
│ └── migrations/ # Migrations DB
├── lib/ # Utilitaires
├── providers/ # Context providers
├── hooks/ # Hooks React
├── i18n/ # Internationalisation
└── public/ # Assets statiques
🏭 RÉFÉRENTIELS DE BASE
├── Company (multi-tenant)
├── RawMaterial (complet avec prix/taxes)
├── FinishedProduct (complet avec prix/taxes)
├── Equipment
├── Client, Supplier, Transporter (avec adresses)
└── Lead (prospects)
🏷️ CATÉGORIES & CLASSIFICATIONS
├── RawMaterialCategory (hiérarchique)
├── FinishedProductCategory (hiérarchique)
└── Tax (TVA, taxes de vente)
📍 ADRESSES & CONTACTS
├── Address (polymorphe)
├── Contact (polymorphe)
└── LegalIdentifier (ICE, RC, SIRET, DUNS)
📦 STOCK & LOGISTIQUE
├── Warehouse, StockLocation
├── StockMovement, StockLot, StockLabel
└── DeliveryNote, ReceptionNote
🏗️ PRODUCTION & FABRICATION
├── WorkCenter (postes de travail)
├── BillOfMaterial (nomenclature enrichie)
├── Routing, Operation (gammes de fabrication)
├── WorkOrder, WorkOrderStep (ordres de fabrication)
└── Equipment (machines et outillages)
💼 COMMERCIAL
├── SalesOffer, SalesOfferLine (Kanban)
├── SalesOrder, SalesOrderLine
└── Invoice
🏷️ SYSTÈME D'ÉTIQUETTES
├── ProductLabel (étiquettes complètes)
├── LabelType (RAW_MATERIAL, FINISHED_PRODUCT, etc.)
└── LabelStatus (DRAFT, PRINTED, APPLIED, etc.)
💬 COMMUNICATION INTERNE
├── Post, PostComment, PostLike (actualités)
├── FAQ, HelpDocument (documentation)
├── PasswordVault (mots de passe)
├── Request, RequestComment (demandes)
└── RequestType, RequestStatus (workflow)
💱 SYSTÈME DE DEVISES
├── Currency (devises internationales)
└── CurrencyExchangeRate (taux de change historiques)
📁 FICHIERS
└── File (polymorphe avec S3)
# Fournisseurs
GET /api/suppliers # Liste des fournisseurs
POST /api/suppliers # Créer un fournisseur
PUT /api/suppliers/[id] # Modifier un fournisseur
DELETE /api/suppliers/[id] # Supprimer un fournisseur
# Commandes d'achat
GET /api/purchase-orders # Liste des bons de commande
POST /api/purchase-orders # Créer un bon de commande
PUT /api/purchase-orders/[id] # Modifier un bon de commande
DELETE /api/purchase-orders/[id] # Supprimer un bon de commande
# Réceptions
GET /api/reception-notes # Liste des réceptions
POST /api/reception-notes # Créer une réception
PUT /api/reception-notes/[id] # Modifier une réception
DELETE /api/reception-notes/[id] # Supprimer une réception
# Livraisons
GET /api/delivery-notes # Liste des livraisons
POST /api/delivery-notes # Créer une livraison
PUT /api/delivery-notes/[id] # Modifier une livraison
DELETE /api/delivery-notes/[id] # Supprimer une livraison
# Offres commerciales
GET /api/sales-offers # Liste des offres
POST /api/sales-offers # Créer une offre
PUT /api/sales-offers/[id] # Modifier une offre
PUT /api/sales-offers/[id]/status # Changer le statut (Kanban)
# Commandes clients
GET /api/sales-orders # Liste des commandes
POST /api/sales-orders # Créer une commande
PUT /api/sales-orders/[id] # Modifier une commande
# Clients et leads
GET /api/clients # Liste des clients
POST /api/clients # Créer un client
GET /api/leads # Liste des leads
POST /api/leads # Créer un lead
PUT /api/leads/[id]/convert # Convertir lead en client
# Mouvements de stock
GET /api/stock-movements # Mouvements de stock
POST /api/stock-movements # Créer un mouvement
PUT /api/stock-movements/[id] # Modifier un mouvement
DELETE /api/stock-movements/[id] # Supprimer un mouvement
# Niveaux de stock
GET /api/stock-levels # Niveaux de stock
GET /api/stock-lots # Gestion des lots
POST /api/stock-lots # Créer un lot
PUT /api/stock-lots/[id] # Modifier un lot
# Entrepôts et emplacements
GET /api/warehouses # Liste des entrepôts
POST /api/warehouses # Créer un entrepôt
GET /api/stock-locations # Emplacements de stock
POST /api/stock-locations # Créer un emplacement
GET /api/manufacturing-orders # Ordres de fabrication
POST /api/manufacturing-orders # Créer un OF
PUT /api/manufacturing-orders/[id] # Modifier un OF
# Matières premières et produits
GET /api/raw-materials # Liste des matières premières
POST /api/raw-materials # Créer une matière première
GET /api/finished-products # Liste des produits finis
POST /api/finished-products # Créer un produit fini
# Catégories
GET /api/raw-material-categories # Catégories matières premières
GET /api/finished-product-categories # Catégories produits finis
# Taxes
GET /api/taxes # Liste des taxes
POST /api/taxes # Créer une taxe
# Adresses et contacts
GET /api/addresses # Adresses d'une entité
POST /api/addresses # Créer une adresse
GET /api/contacts # Contacts d'une entité
POST /api/contacts # Créer un contact
# Système d'étiquettes
GET /api/product-labels # Liste des étiquettes
POST /api/product-labels # Créer une étiquette
PUT /api/product-labels/[id] # Modifier une étiquette
PUT /api/product-labels/[id]/status # Changer le statut
GET /api/product-labels/[id]/print # Générer pour impression
# Communication interne
GET /api/posts # Actualités et posts
POST /api/posts # Créer un post
GET /api/faq # Questions fréquentes
POST /api/faq # Créer une FAQ
GET /api/help-documents # Documentation d'aide
POST /api/help-documents # Créer un document
# Système de demandes
GET /api/requests # Liste des demandes
POST /api/requests # Créer une demande
PUT /api/requests/[id] # Modifier une demande
PUT /api/requests/[id]/status # Changer le statut
GET /api/requests/[id]/comments # Commentaires d'une demande
# Gestion des mots de passe
GET /api/password-vault # Mots de passe (utilisateur)
POST /api/password-vault # Ajouter un mot de passe
PUT /api/password-vault/[id] # Modifier un mot de passe
DELETE /api/password-vault/[id] # Supprimer un mot de passe
# Système de devises
GET /api/currencies # Liste des devises
POST /api/currencies # Créer une devise
GET /api/exchange-rates # Taux de change
POST /api/exchange-rates # Ajouter un taux de change
GET /api/exchange-rates/convert # Convertir un montant
# Production & Fabrication
GET /api/equipments # Liste des équipements
POST /api/equipments # Créer un équipement
GET /api/work-centers # Liste des postes de travail
POST /api/work-centers # Créer un poste de travail
GET /api/bill-of-materials # Nomenclatures enrichies
POST /api/bill-of-materials # Créer une nomenclature
GET /api/routings # Gammes de fabrication
POST /api/routings # Créer une gamme
GET /api/operations # Opérations de production
POST /api/operations # Créer une opération
GET /api/work-orders # Ordres de fabrication
POST /api/work-orders # Créer un ordre de fabrication
PUT /api/work-orders/[id]/status # Changer le statut d'un OF
GET /api/work-order-steps # Étapes d'un OF
PUT /api/work-order-steps/[id] # Mettre à jour une étape
const response = await fetch('/api/raw-materials', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: 'MP001',
name: 'Mousse PE réticulée 30kg/m³',
categoryId: 'cat-foam-pe',
productType: 'STOCKABLE',
billingPolicy: 'ORDERED',
unitOfMeasure: 'm²',
unitOfPurchase: 'm²',
unitOfStock: 'm²',
sellingPrice: 45.5,
cost: 23.58,
costPerUnit: 'par m²',
salesTaxId: 'tax-tva20',
internalReference: 'PA00003',
barcode: '1234567890123',
supplierCode: 'SUP-MP001',
density: 30,
thickness: 10,
width: 1000,
length: 2000,
color: 'Blanc',
internalNotes: 'Mousse de protection automobile',
tags: 'automobile,protection,pe',
supplierId: 'supplier-id',
minStockLevel: 100,
maxStockLevel: 500,
reorderPoint: 150,
}),
});
const response = await fetch('/api/sales-offers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
number: 'OFF-2025-001',
clientId: 'client-id',
projectName: 'Protection pare-chocs BMW',
internalDesignation: 'PROJ-BMW-2025',
annualVolume: 10000,
annualAmount: 455000,
currency: 'MAD',
validityDate: '2025-12-31',
priority: 1,
status: 'DRAFT',
protoTotalPrice: 5000,
seriesUnitPrice: '45.50',
firstOrderLeadTime: 15,
incoterms: 'FOB',
destinationCountry: 'Maroc',
lines: [
{
finishedProductId: 'product-id',
description: 'Mousse protection pare-chocs',
quantity: 1000,
unitPrice: 45.5,
totalPrice: 45500,
},
],
}),
});
const response = await fetch('/api/product-labels', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
labelType: 'FINISHED_PRODUCT',
productName: 'Protection Pare-chocs BMW',
productCode: 'PROT-BMW-001',
quantity: 100,
unit: 'PCS',
warehouseId: 'warehouse-id',
locationId: 'location-id',
clientId: 'client-id',
clientName: 'YAZAKI',
lotNumber: 'LOT-2025-001',
productionDate: '2025-01-15',
shippingDate: '2025-01-20',
destinationCountry: 'France',
destinationCity: 'Paris',
}),
});
const response = await fetch('/api/requests', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'PURCHASE',
title: 'Achat PC portable pour développement',
description:
"Besoin d'un PC portable pour le développement de l'application",
priority: 'NORMAL',
amount: 15000,
currencyId: 'currency-mad-id',
approverId: 'manager-id',
}),
});
const response = await fetch('/api/exchange-rates/convert', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
params: new URLSearchParams({
amount: '1000',
fromCurrencyId: 'currency-eur-id',
toCurrencyId: 'currency-mad-id',
date: '2025-01-15',
}),
});
const result = await response.json();
// { convertedAmount: 10500, rate: 10.5, source: "Manual" }
const response = await fetch('/api/currencies', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: 'MAD',
name: 'Dirham Marocain',
symbol: 'د.م.',
decimalPlaces: 2,
position: 'AFTER',
isDefault: true,
}),
});
const response = await fetch('/api/work-centers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: 'LAMINEUSE_1',
name: 'Lamineuse principale',
description: 'Lamineuse automatique pour mousse PE',
capacity: 1200.0, // unités/heure
costPerHour: 45.5, // coût horaire du poste
equipmentId: 'equipment-lamineuse-id', // Lien vers l'équipement (optionnel)
}),
});
const response = await fetch('/api/equipments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code: 'LAMINEUSE_001',
name: 'Lamineuse automatique PE',
type: 'Machine de production',
description: 'Lamineuse pour mousse PE réticulée',
brand: 'ETASCOM',
model: 'LAM-PE-2024',
serialNumber: 'SN-LAM-001',
location: 'Atelier Production A',
}),
});
const response = await fetch('/api/bill-of-materials', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
finishedProductId: 'product-id',
rawMaterialId: 'material-id',
quantity: 0.202,
unit: 'm²',
operationSequence: 10,
efficiency: 1.0,
unitCost: 1.23,
coefficient: 1.1,
isConsumable: true,
scrapRate: 2.5,
}),
});
const response = await fetch('/api/operations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
routingId: 'routing-id',
workCenterId: 'workcenter-id',
sequence: 1,
name: 'LAMINATION',
instructions: "Régler la température à 180°C, vérifier l'épaisseur",
durationType: 'CADENCE',
ratePerHour: 1200.0,
qualityChecks: "Mesurer l'épaisseur, vérifier la couleur",
requiredTools: 'Règle de mesure, thermomètre',
safetyNotes: 'Porter des gants de protection',
}),
});
Company - Gestion multi-tenant avec adresses et contactsRawMaterial - Matières premières complètes (prix, taxes, codes, notes)FinishedProduct - Produits finis avec gestion avancéeEquipment - Machines et outillagesClient, Supplier, Transporter - Entités avec adresses multiplesLead - Prospects avec conversion vers clientsRawMaterialCategory - Catégories hiérarchiques matières premièresFinishedProductCategory - Catégories hiérarchiques produits finisTax - Gestion des taxes (TVA, taxes de vente, etc.)Address - Adresses multiples par entité (facturation, livraison)Contact - Contacts multiples avec postes et coordonnéesLegalIdentifier - Identifiants légaux (ICE, RC, SIRET, DUNS, etc.)Warehouse - EntrepôtsStockLocation - Emplacements détaillés (zone, allée, rayonnage)StockMovement - Mouvements traçables (IN, OUT, TRANSFER, etc.)StockLot - Gestion des lots avec dates d'expirationStockLabel - Étiquettes et codes-barresDeliveryNote / ReceptionNote - Bons de livraison et réceptionPurchaseOrder / PurchaseOrderLine - Commandes d'achatSupplier - Fournisseurs avec adresses et contactsTransporter - Transporteurs pour les livraisonsWorkCenter - Postes de travail avec capacités et coûts (liés aux équipements)Equipment - Machines et outillages de production (liés aux postes de travail)BillOfMaterial - Nomenclatures enrichies (coûts, efficacité, opérations)Routing - Gammes de fabrication avec séquencesOperation - Opérations détaillées (consignes, cadences, qualité)WorkOrder - Ordres de fabrication avec planificationWorkOrderStep - Suivi opérateur et performance en temps réelSalesOffer / SalesOfferLine - Offres commerciales avec statuts KanbanSalesOrder / SalesOrderLine - Commandes clientsInvoice - Facturation complèteProductLabel - Étiquettes complètes avec informations produit, stockage, fournisseur/clientLabelType - Types d'étiquettes (RAW_MATERIAL, FINISHED_PRODUCT, SHIPPING, etc.)LabelStatus - Statuts des étiquettes (DRAFT, PRINTED, APPLIED, etc.)Post - Actualités et posts d'entreprise avec likes et commentairesPostComment - Commentaires hiérarchiques sur les postsPostLike - Système de likes pour les postsFAQ - Questions fréquentes organisées par catégoriesHelpDocument - Documentation d'aide avec sectionsPasswordVault - Gestion sécurisée des mots de passeRequest - Système de demandes avec workflow d'approbationRequestComment - Commentaires sur les demandes (internes/externes)Currency - Devises internationales avec formats et symbolesCurrencyExchangeRate - Taux de change historiques avec sourcesFile - Modèle central pour S3 avec relations polymorphes# Variables d'environnement requises
DATABASE_URL=postgresql://...
NEXTAUTH_SECRET=your-secret
NEXTAUTH_URL=https://your-domain.vercel.app
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
# Build de production
npm run build
# Démarrage en production
npm start
# Linting
npm run lint
# Tests
npm run test
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)feat: ajouter gestion des étiquettes OF
fix: corriger calcul des coûts de production
docs: mettre à jour la documentation API
style: améliorer l'interface des tableaux
refactor: optimiser les requêtes Prisma
test: ajouter tests pour le module stock
Ce projet est propriétaire et confidentiel. Tous droits réservés à ETASCOM.