chore(ci): ajout workflow publish + nettoyage services + conf hosts
Some checks failed
publish-images / docker-build-and-push (push) Failing after 23s
Some checks failed
publish-images / docker-build-and-push (push) Failing after 23s
This commit is contained in:
parent
fddfa6f7bf
commit
f50481cc38
64
.gitea/workflows/publish.yml
Normal file
64
.gitea/workflows/publish.yml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
name: publish-images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ dev, main ]
|
||||||
|
tags: [ 'v*' ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: git.4nkweb.com
|
||||||
|
IMAGE_OWNER: 4nk
|
||||||
|
IMAGE_REPO: 4NK_IA_back
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ secrets.USER }}
|
||||||
|
password: ${{ secrets.TOKEN }}
|
||||||
|
|
||||||
|
- name: Compute tags
|
||||||
|
id: meta
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
|
||||||
|
VERSION_TAG="${GITHUB_REF_NAME}"
|
||||||
|
else
|
||||||
|
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-8)
|
||||||
|
VERSION_TAG="sha-${SHORT_SHA}"
|
||||||
|
fi
|
||||||
|
echo "version=${VERSION_TAG}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Build & Push host-api
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ./docker/host-api
|
||||||
|
file: ./docker/host-api/Dockerfile
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64
|
||||||
|
tags: |
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.IMAGE_REPO }}/host-api:${{ steps.meta.outputs.version }}
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.IMAGE_REPO }}/host-api:latest
|
||||||
|
|
||||||
|
- name: Build & Push worker
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./docker/worker/Dockerfile
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64
|
||||||
|
tags: |
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.IMAGE_REPO }}/worker:${{ steps.meta.outputs.version }}
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.IMAGE_REPO }}/worker:latest
|
@ -1,67 +0,0 @@
|
|||||||
SHELL := /bin/bash
|
|
||||||
ENV ?= infra/.env
|
|
||||||
|
|
||||||
# Charger les variables d'environnement
|
|
||||||
include $(ENV)
|
|
||||||
export
|
|
||||||
|
|
||||||
.PHONY: help up down start-simple logs ps clean restart
|
|
||||||
|
|
||||||
help: ## Afficher l'aide
|
|
||||||
@echo "Commandes disponibles :"
|
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
|
||||||
|
|
||||||
up: ## Démarrer tous les services (version complète)
|
|
||||||
cd infra && docker compose up -d
|
|
||||||
|
|
||||||
up-simple: ## Démarrer les services simplifiés (sans IA)
|
|
||||||
cd infra && docker compose -f docker-compose.simple.yml up -d
|
|
||||||
|
|
||||||
down: ## Arrêter tous les services
|
|
||||||
cd infra && docker compose down
|
|
||||||
|
|
||||||
down-simple: ## Arrêter les services simplifiés
|
|
||||||
cd infra && docker compose -f docker-compose.simple.yml down
|
|
||||||
|
|
||||||
start-simple: ## Initialiser l'infrastructure simplifiée
|
|
||||||
bash ops/start-simple.sh
|
|
||||||
|
|
||||||
logs: ## Afficher les logs
|
|
||||||
cd infra && docker compose logs -f --tail=200
|
|
||||||
|
|
||||||
logs-simple: ## Afficher les logs (version simplifiée)
|
|
||||||
cd infra && docker compose -f docker-compose.simple.yml logs -f --tail=200
|
|
||||||
|
|
||||||
ps: ## Afficher le statut des services
|
|
||||||
cd infra && docker compose ps
|
|
||||||
|
|
||||||
ps-simple: ## Afficher le statut des services (version simplifiée)
|
|
||||||
cd infra && docker compose -f docker-compose.simple.yml ps
|
|
||||||
|
|
||||||
clean: ## Nettoyer les volumes et images
|
|
||||||
cd infra && docker compose down -v
|
|
||||||
docker system prune -f
|
|
||||||
|
|
||||||
restart: ## Redémarrer tous les services
|
|
||||||
cd infra && docker compose restart
|
|
||||||
|
|
||||||
build: ## Reconstruire les images
|
|
||||||
cd infra && docker compose build --no-cache
|
|
||||||
|
|
||||||
build-simple: ## Reconstruire les images (version simplifiée)
|
|
||||||
cd infra && docker compose -f docker-compose.simple.yml build --no-cache
|
|
||||||
|
|
||||||
test-api: ## Tester l'API
|
|
||||||
curl -F "file=@tests/data/sample.pdf" \
|
|
||||||
-F "id_dossier=D-2025-001" \
|
|
||||||
-F "source=upload" \
|
|
||||||
-F "etude_id=E-001" \
|
|
||||||
-F "utilisateur_id=U-123" \
|
|
||||||
http://localhost:8000/api/import
|
|
||||||
|
|
||||||
status: ## Vérifier le statut de tous les services
|
|
||||||
@echo "=== Statut des services ==="
|
|
||||||
@make ps-simple
|
|
||||||
@echo ""
|
|
||||||
@echo "=== Test de connectivité ==="
|
|
||||||
@curl -s http://localhost:8000/api/health || echo "API non accessible"
|
|
@ -1,88 +0,0 @@
|
|||||||
version: "3.9"
|
|
||||||
|
|
||||||
# Configuration de développement avec volumes montés et debugging
|
|
||||||
services:
|
|
||||||
host-api:
|
|
||||||
build:
|
|
||||||
context: ./docker/host-api
|
|
||||||
volumes:
|
|
||||||
- ./services/host_api:/app
|
|
||||||
- ./ops/seed:/seed:ro
|
|
||||||
environment:
|
|
||||||
- DEBUG=true
|
|
||||||
- LOG_LEVEL=debug
|
|
||||||
ports:
|
|
||||||
- "8000:8000"
|
|
||||||
command: ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
|
||||||
depends_on:
|
|
||||||
- postgres
|
|
||||||
- redis
|
|
||||||
- minio
|
|
||||||
|
|
||||||
worker:
|
|
||||||
build:
|
|
||||||
context: ./docker/worker
|
|
||||||
volumes:
|
|
||||||
- ./services/worker:/app
|
|
||||||
- ./ops/seed:/seed:ro
|
|
||||||
environment:
|
|
||||||
- DEBUG=true
|
|
||||||
- LOG_LEVEL=debug
|
|
||||||
command: ["celery", "-A", "worker", "worker", "--loglevel=debug"]
|
|
||||||
depends_on:
|
|
||||||
- host-api
|
|
||||||
|
|
||||||
postgres:
|
|
||||||
image: postgres:16
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: notariat
|
|
||||||
POSTGRES_PASSWORD: notariat_pwd
|
|
||||||
POSTGRES_DB: notariat
|
|
||||||
volumes:
|
|
||||||
- pgdata_dev:/var/lib/postgresql/data
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
command: ["redis-server", "--appendonly", "yes"]
|
|
||||||
volumes:
|
|
||||||
- redis_dev:/data
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
|
|
||||||
minio:
|
|
||||||
image: minio/minio:RELEASE.2025-01-13T00-00-00Z
|
|
||||||
command: server /data --console-address ":9001"
|
|
||||||
environment:
|
|
||||||
MINIO_ROOT_USER: minio
|
|
||||||
MINIO_ROOT_PASSWORD: minio_pwd
|
|
||||||
volumes:
|
|
||||||
- minio_dev:/data
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
- "9001:9001"
|
|
||||||
|
|
||||||
ollama:
|
|
||||||
image: ollama/ollama:latest
|
|
||||||
volumes:
|
|
||||||
- ollama_dev:/root/.ollama
|
|
||||||
ports:
|
|
||||||
- "11434:11434"
|
|
||||||
environment:
|
|
||||||
- OLLAMA_HOST=0.0.0.0
|
|
||||||
|
|
||||||
anythingsqlite:
|
|
||||||
image: kevincharm/anythingllm:latest
|
|
||||||
environment:
|
|
||||||
- DISABLE_AUTH=true
|
|
||||||
ports:
|
|
||||||
- "3001:3001"
|
|
||||||
depends_on:
|
|
||||||
- ollama
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
pgdata_dev:
|
|
||||||
redis_dev:
|
|
||||||
minio_dev:
|
|
||||||
ollama_dev:
|
|
@ -1,58 +0,0 @@
|
|||||||
version: "3.9"
|
|
||||||
|
|
||||||
# Configuration pour les tests d'intégration
|
|
||||||
services:
|
|
||||||
postgres-test:
|
|
||||||
image: postgres:16
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: test_notariat
|
|
||||||
POSTGRES_PASSWORD: test_pwd
|
|
||||||
POSTGRES_DB: test_notariat
|
|
||||||
volumes:
|
|
||||||
- pgdata_test:/var/lib/postgresql/data
|
|
||||||
ports:
|
|
||||||
- "5433:5432"
|
|
||||||
|
|
||||||
redis-test:
|
|
||||||
image: redis:7
|
|
||||||
command: ["redis-server", "--appendonly", "yes"]
|
|
||||||
volumes:
|
|
||||||
- redis_test:/data
|
|
||||||
ports:
|
|
||||||
- "6380:6379"
|
|
||||||
|
|
||||||
minio-test:
|
|
||||||
image: minio/minio:RELEASE.2025-01-13T00-00-00Z
|
|
||||||
command: server /data --console-address ":9001"
|
|
||||||
environment:
|
|
||||||
MINIO_ROOT_USER: test_minio
|
|
||||||
MINIO_ROOT_PASSWORD: test_minio_pwd
|
|
||||||
volumes:
|
|
||||||
- minio_test:/data
|
|
||||||
ports:
|
|
||||||
- "9002:9000"
|
|
||||||
- "9003:9001"
|
|
||||||
|
|
||||||
ollama-test:
|
|
||||||
image: ollama/ollama:latest
|
|
||||||
volumes:
|
|
||||||
- ollama_test:/root/.ollama
|
|
||||||
ports:
|
|
||||||
- "11435:11434"
|
|
||||||
environment:
|
|
||||||
- OLLAMA_HOST=0.0.0.0
|
|
||||||
|
|
||||||
anythingsqlite-test:
|
|
||||||
image: kevincharm/anythingllm:latest
|
|
||||||
environment:
|
|
||||||
- DISABLE_AUTH=true
|
|
||||||
ports:
|
|
||||||
- "3002:3001"
|
|
||||||
depends_on:
|
|
||||||
- ollama-test
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
pgdata_test:
|
|
||||||
redis_test:
|
|
||||||
minio_test:
|
|
||||||
ollama_test:
|
|
452
docker-compose.yml
Normal file
452
docker-compose.yml
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
x-env: &default-env
|
||||||
|
TZ: ${TZ}
|
||||||
|
PUID: "1000"
|
||||||
|
PGID: "1000"
|
||||||
|
|
||||||
|
# Configuration DNS et réseau pour 4NK_IA_back
|
||||||
|
x-4nk-ia-extra-hosts: &x-4nk-ia-extra-hosts
|
||||||
|
extra_hosts:
|
||||||
|
- "4nk-ia-api.local:172.23.0.10"
|
||||||
|
- "4nk-ia-worker.local:172.23.0.11"
|
||||||
|
- "4nk-ia-postgres.local:172.23.0.12"
|
||||||
|
- "4nk-ia-redis.local:172.23.0.13"
|
||||||
|
- "4nk-ia-minio.local:172.23.0.14"
|
||||||
|
- "4nk-ia-ollama.local:172.23.0.15"
|
||||||
|
- "4nk-ia-anythingllm.local:172.23.0.16"
|
||||||
|
- "4nk-ia-neo4j.local:172.23.0.17"
|
||||||
|
- "4nk-ia-opensearch.local:172.23.0.18"
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
# ==================== SERVICES DE BASE ====================
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: postgres:16
|
||||||
|
container_name: 4nk-ia-postgres.local
|
||||||
|
hostname: 4nk-ia-postgres.local
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1 # Gateway Docker pour accéder à dnsmasq
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.12
|
||||||
|
|
||||||
|
postgres-test:
|
||||||
|
image: postgres:16
|
||||||
|
container_name: 4nk-ia-postgres-test.local
|
||||||
|
hostname: 4nk-ia-postgres-test.local
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: test_notariat
|
||||||
|
POSTGRES_PASSWORD: test_pwd
|
||||||
|
POSTGRES_DB: test_notariat
|
||||||
|
volumes:
|
||||||
|
- pgdata_test:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5433:5432"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["test"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.22
|
||||||
|
|
||||||
|
redis:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: redis:7
|
||||||
|
container_name: 4nk-ia-redis.local
|
||||||
|
hostname: 4nk-ia-redis.local
|
||||||
|
command: ["redis-server", "--appendonly", "yes"]
|
||||||
|
volumes:
|
||||||
|
- redis:/data
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.13
|
||||||
|
|
||||||
|
redis-test:
|
||||||
|
image: redis:7
|
||||||
|
container_name: 4nk-ia-redis-test.local
|
||||||
|
hostname: 4nk-ia-redis-test.local
|
||||||
|
command: ["redis-server", "--appendonly", "yes"]
|
||||||
|
volumes:
|
||||||
|
- redis_test:/data
|
||||||
|
ports:
|
||||||
|
- "6380:6379"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["test"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.23
|
||||||
|
|
||||||
|
minio:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: minio/minio:latest
|
||||||
|
container_name: 4nk-ia-minio.local
|
||||||
|
hostname: 4nk-ia-minio.local
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
||||||
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- minio:/data
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
- "9001:9001"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.14
|
||||||
|
|
||||||
|
minio-test:
|
||||||
|
image: minio/minio:latest
|
||||||
|
container_name: 4nk-ia-minio-test.local
|
||||||
|
hostname: 4nk-ia-minio-test.local
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: test_minio
|
||||||
|
MINIO_ROOT_PASSWORD: test_minio_pwd
|
||||||
|
volumes:
|
||||||
|
- minio_test:/data
|
||||||
|
ports:
|
||||||
|
- "9002:9000"
|
||||||
|
- "9003:9001"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["test"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.24
|
||||||
|
|
||||||
|
# ==================== SERVICES IA ET RAG ====================
|
||||||
|
|
||||||
|
ollama:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: 4nk-ia-ollama.local
|
||||||
|
hostname: 4nk-ia-ollama.local
|
||||||
|
volumes:
|
||||||
|
- ollama:/root/.ollama
|
||||||
|
ports:
|
||||||
|
- "11435:11434" # Port modifié pour éviter les conflits
|
||||||
|
environment:
|
||||||
|
- OLLAMA_HOST=0.0.0.0
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.15
|
||||||
|
|
||||||
|
ollama-test:
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: 4nk-ia-ollama-test.local
|
||||||
|
hostname: 4nk-ia-ollama-test.local
|
||||||
|
volumes:
|
||||||
|
- ollama_test:/root/.ollama
|
||||||
|
ports:
|
||||||
|
- "11436:11434"
|
||||||
|
environment:
|
||||||
|
- OLLAMA_HOST=0.0.0.0
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["test"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.25
|
||||||
|
|
||||||
|
anythingsqlite:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: mintplexlabs/anythingllm:latest
|
||||||
|
container_name: 4nk-ia-anythingllm.local
|
||||||
|
hostname: 4nk-ia-anythingllm.local
|
||||||
|
environment:
|
||||||
|
- DISABLE_AUTH=true
|
||||||
|
- STORAGE_DIR=/app/server/storage
|
||||||
|
depends_on:
|
||||||
|
- ollama
|
||||||
|
ports:
|
||||||
|
- "3001:3001"
|
||||||
|
volumes:
|
||||||
|
- anythingllm:/app/server/storage
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.16
|
||||||
|
|
||||||
|
anythingsqlite-test:
|
||||||
|
image: mintplexlabs/anythingllm:latest
|
||||||
|
container_name: 4nk-ia-anythingllm-test.local
|
||||||
|
hostname: 4nk-ia-anythingllm-test.local
|
||||||
|
environment:
|
||||||
|
- DISABLE_AUTH=true
|
||||||
|
- STORAGE_DIR=/app/server/storage
|
||||||
|
depends_on:
|
||||||
|
- ollama-test
|
||||||
|
ports:
|
||||||
|
- "3002:3001"
|
||||||
|
volumes:
|
||||||
|
- anythingllm_test:/app/server/storage
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["test"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.26
|
||||||
|
|
||||||
|
# ==================== SERVICES DE DONNÉES ====================
|
||||||
|
|
||||||
|
neo4j:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: neo4j:5
|
||||||
|
container_name: 4nk-ia-neo4j.local
|
||||||
|
hostname: 4nk-ia-neo4j.local
|
||||||
|
environment:
|
||||||
|
- NEO4J_AUTH=${NEO4J_AUTH}
|
||||||
|
volumes:
|
||||||
|
- neo4j:/data
|
||||||
|
ports:
|
||||||
|
- "7474:7474"
|
||||||
|
- "7687:7687"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.17
|
||||||
|
|
||||||
|
opensearch:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
image: opensearchproject/opensearch:2.14.0
|
||||||
|
container_name: 4nk-ia-opensearch.local
|
||||||
|
hostname: 4nk-ia-opensearch.local
|
||||||
|
environment:
|
||||||
|
- discovery.type=single-node
|
||||||
|
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=OpenSearch2025!
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
volumes:
|
||||||
|
- opensearch:/usr/share/opensearch/data
|
||||||
|
ports:
|
||||||
|
- "9200:9200"
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production", "development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.18
|
||||||
|
|
||||||
|
# ==================== SERVICES APPLICATIFS ====================
|
||||||
|
|
||||||
|
host-api:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
build:
|
||||||
|
context: ./docker/host-api
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 4nk-ia-api.local
|
||||||
|
hostname: 4nk-ia-api.local
|
||||||
|
labels:
|
||||||
|
- logging=promtail
|
||||||
|
- project=4nk_ia_back
|
||||||
|
env_file: ./.env
|
||||||
|
environment:
|
||||||
|
<<: *default-env
|
||||||
|
DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@4nk-ia-postgres.local:5432/$POSTGRES_DB
|
||||||
|
REDIS_URL: redis://4nk-ia-redis.local:6379/0
|
||||||
|
MINIO_ENDPOINT: 4nk-ia-minio.local:9000
|
||||||
|
MINIO_BUCKET: ${MINIO_BUCKET}
|
||||||
|
ANYLLM_BASE_URL: http://4nk-ia-anythingllm.local:3001
|
||||||
|
ANYLLM_API_KEY: ${ANYLLM_API_KEY}
|
||||||
|
OLLAMA_BASE_URL: http://4nk-ia-ollama.local:11434
|
||||||
|
OPENSEARCH_URL: http://4nk-ia-opensearch.local:9200
|
||||||
|
NEO4J_URL: bolt://4nk-ia-neo4j.local:7687
|
||||||
|
NEO4J_AUTH: ${NEO4J_AUTH}
|
||||||
|
# Configuration de l'API
|
||||||
|
API_HOST: 0.0.0.0
|
||||||
|
API_PORT: 8000
|
||||||
|
API_WORKERS: 4
|
||||||
|
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
||||||
|
LOG_FORMAT: ${LOG_FORMAT:-json}
|
||||||
|
# Sécurité
|
||||||
|
SECRET_KEY: ${SECRET_KEY:-your_secret_key_here}
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-30}
|
||||||
|
volumes:
|
||||||
|
- ./services/host_api:/app
|
||||||
|
- ./ops/seed:/seed:ro
|
||||||
|
- ./ops/seed/schemas:/schemas:ro
|
||||||
|
- api_logs:/app/logs
|
||||||
|
ports:
|
||||||
|
- "8001:8000" # Port externe 8001 pour éviter les conflits
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_started
|
||||||
|
minio:
|
||||||
|
condition: service_started
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.10
|
||||||
|
|
||||||
|
host-api-dev:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
build:
|
||||||
|
context: ./docker/host-api
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 4nk-ia-api-dev.local
|
||||||
|
hostname: 4nk-ia-api-dev.local
|
||||||
|
volumes:
|
||||||
|
- ./services/host_api:/app
|
||||||
|
- ./ops/seed:/seed:ro
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
- LOG_LEVEL=debug
|
||||||
|
- DATABASE_URL=postgresql+psycopg://notariat:notariat_pwd@4nk-ia-postgres.local:5432/notariat
|
||||||
|
- REDIS_URL=redis://4nk-ia-redis.local:6379/0
|
||||||
|
ports:
|
||||||
|
- "8000:8000" # Port de développement
|
||||||
|
command: ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
|
- minio
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.30
|
||||||
|
|
||||||
|
worker:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: docker/worker/Dockerfile
|
||||||
|
container_name: 4nk-ia-worker.local
|
||||||
|
hostname: 4nk-ia-worker.local
|
||||||
|
labels:
|
||||||
|
- logging=promtail
|
||||||
|
- project=4nk_ia_back
|
||||||
|
env_file: ./.env
|
||||||
|
environment:
|
||||||
|
<<: *default-env
|
||||||
|
DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@4nk-ia-postgres.local:5432/$POSTGRES_DB
|
||||||
|
REDIS_URL: redis://4nk-ia-redis.local:6379/0
|
||||||
|
MINIO_ENDPOINT: 4nk-ia-minio.local:9000
|
||||||
|
MINIO_BUCKET: ${MINIO_BUCKET}
|
||||||
|
ANYLLM_BASE_URL: http://4nk-ia-anythingllm.local:3001
|
||||||
|
ANYLLM_API_KEY: ${ANYLLM_API_KEY}
|
||||||
|
OLLAMA_BASE_URL: http://4nk-ia-ollama.local:11434
|
||||||
|
OPENSEARCH_URL: http://4nk-ia-opensearch.local:9200
|
||||||
|
NEO4J_URL: bolt://4nk-ia-neo4j.local:7687
|
||||||
|
NEO4J_AUTH: ${NEO4J_AUTH}
|
||||||
|
volumes:
|
||||||
|
- ./services/worker:/app
|
||||||
|
- ./ops/seed:/seed:ro
|
||||||
|
depends_on:
|
||||||
|
- host-api
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["production"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.11
|
||||||
|
|
||||||
|
worker-dev:
|
||||||
|
<<: *x-4nk-ia-extra-hosts
|
||||||
|
build:
|
||||||
|
context: ./docker/worker
|
||||||
|
container_name: 4nk-ia-worker-dev.local
|
||||||
|
hostname: 4nk-ia-worker-dev.local
|
||||||
|
volumes:
|
||||||
|
- ./services/worker:/app
|
||||||
|
- ./ops/seed:/seed:ro
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
- LOG_LEVEL=debug
|
||||||
|
- DATABASE_URL=postgresql+psycopg://notariat:notariat_pwd@4nk-ia-postgres.local:5432/notariat
|
||||||
|
- REDIS_URL=redis://4nk-ia-redis.local:6379/0
|
||||||
|
command: ["celery", "-A", "worker", "worker", "--loglevel=debug"]
|
||||||
|
depends_on:
|
||||||
|
- host-api-dev
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles: ["development"]
|
||||||
|
dns:
|
||||||
|
- 172.23.0.1
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
ipv4_address: 172.23.0.31
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# Volumes de production/développement
|
||||||
|
pgdata:
|
||||||
|
redis:
|
||||||
|
minio:
|
||||||
|
ollama:
|
||||||
|
neo4j:
|
||||||
|
opensearch:
|
||||||
|
anythingllm:
|
||||||
|
api_logs:
|
||||||
|
|
||||||
|
# Volumes de test
|
||||||
|
pgdata_test:
|
||||||
|
redis_test:
|
||||||
|
minio_test:
|
||||||
|
ollama_test:
|
||||||
|
anythingllm_test:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
4nk_ia_network:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.23.0.0/16
|
||||||
|
gateway: 172.23.0.1
|
@ -11,4 +11,4 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||||||
|
|
||||||
COPY services/worker /app
|
COPY services/worker /app
|
||||||
|
|
||||||
CMD ["python", "worker.py"]
|
CMD ["celery", "-A", "worker", "worker", "--loglevel=info"]
|
||||||
|
@ -209,9 +209,7 @@ curl "http://localhost:8000/api/notary/document/{document_id}/analysis"
|
|||||||
cd services/host_api
|
cd services/host_api
|
||||||
uvicorn app:app --host 0.0.0.0 --port 8000
|
uvicorn app:app --host 0.0.0.0 --port 8000
|
||||||
|
|
||||||
# Démarrer l'interface web (dans un autre terminal)
|
# L'interface web est gérée par le projet 4NK_IA_front séparé
|
||||||
cd services/web_interface
|
|
||||||
python start_web.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Accès
|
#### Accès
|
||||||
|
@ -440,9 +440,7 @@ cd services/worker
|
|||||||
source ../../venv/bin/activate
|
source ../../venv/bin/activate
|
||||||
celery -A worker worker --loglevel=info &
|
celery -A worker worker --loglevel=info &
|
||||||
|
|
||||||
# Démarrage de l'interface web
|
# L'interface web est gérée par le projet 4NK_IA_front séparé
|
||||||
cd services/web_interface
|
|
||||||
python3 start_web.py 8081 &
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### **3. Vérification du Démarrage**
|
### **3. Vérification du Démarrage**
|
||||||
|
9
hosts.4nk-ia
Normal file
9
hosts.4nk-ia
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
172.23.0.10 4nk-ia-api.local
|
||||||
|
172.23.0.11 4nk-ia-worker.local
|
||||||
|
172.23.0.12 4nk-ia-postgres.local
|
||||||
|
172.23.0.13 4nk-ia-redis.local
|
||||||
|
172.23.0.14 4nk-ia-minio.local
|
||||||
|
172.23.0.15 4nk-ia-ollama.local
|
||||||
|
172.23.0.16 4nk-ia-anythingllm.local
|
||||||
|
172.23.0.17 4nk-ia-neo4j.local
|
||||||
|
172.23.0.18 4nk-ia-opensearch.local
|
24
hosts.merge
Normal file
24
hosts.merge
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
172.23.0.10 4nk-ia-api.local
|
||||||
|
172.23.0.11 4nk-ia-worker.local
|
||||||
|
172.23.0.12 4nk-ia-postgres.local
|
||||||
|
172.23.0.13 4nk-ia-redis.local
|
||||||
|
172.23.0.14 4nk-ia-minio.local
|
||||||
|
172.23.0.15 4nk-ia-ollama.local
|
||||||
|
172.23.0.16 4nk-ia-anythingllm.local
|
||||||
|
172.23.0.17 4nk-ia-neo4j.local
|
||||||
|
172.23.0.18 4nk-ia-opensearch.local
|
||||||
|
172.20.0.10 tor.local
|
||||||
|
172.20.0.11 bitcoin.local
|
||||||
|
172.20.0.12 blindbit-oracle.local
|
||||||
|
172.20.0.13 sdk-storage.local
|
||||||
|
172.20.0.14 sdk-relay1.local
|
||||||
|
172.20.0.15 sdk-relay2.local
|
||||||
|
172.20.0.16 sdk-relay3.local
|
||||||
|
172.20.0.17 sdk-signer.local
|
||||||
|
172.20.0.18 ihm-client.local
|
||||||
|
172.20.0.32 coffre-front.local
|
||||||
|
172.20.0.33 coffre-back-mini.local
|
||||||
|
172.20.0.50 grafana-central.local
|
||||||
|
172.20.0.51 loki.local
|
||||||
|
172.20.0.52 prometheus.local
|
||||||
|
172.20.0.53 promtail.local
|
15
hosts.sdk
Normal file
15
hosts.sdk
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
172.20.0.10 tor.local
|
||||||
|
172.20.0.11 bitcoin.local
|
||||||
|
172.20.0.12 blindbit-oracle.local
|
||||||
|
172.20.0.13 sdk-storage.local
|
||||||
|
172.20.0.14 sdk-relay1.local
|
||||||
|
172.20.0.15 sdk-relay2.local
|
||||||
|
172.20.0.16 sdk-relay3.local
|
||||||
|
172.20.0.17 sdk-signer.local
|
||||||
|
172.20.0.18 ihm-client.local
|
||||||
|
172.20.0.32 coffre-front.local
|
||||||
|
172.20.0.33 coffre-back-mini.local
|
||||||
|
172.20.0.50 grafana-central.local
|
||||||
|
172.20.0.51 loki.local
|
||||||
|
172.20.0.52 prometheus.local
|
||||||
|
172.20.0.53 promtail.local
|
@ -1,71 +0,0 @@
|
|||||||
# Configuration du projet
|
|
||||||
PROJECT_NAME=notariat
|
|
||||||
DOMAIN=localhost
|
|
||||||
TZ=Europe/Paris
|
|
||||||
|
|
||||||
# Base de données PostgreSQL
|
|
||||||
POSTGRES_USER=notariat
|
|
||||||
POSTGRES_PASSWORD=notariat_pwd
|
|
||||||
POSTGRES_DB=notariat
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
REDIS_PASSWORD=
|
|
||||||
|
|
||||||
# MinIO (Stockage S3-compatible)
|
|
||||||
MINIO_ROOT_USER=minio
|
|
||||||
MINIO_ROOT_PASSWORD=minio_pwd
|
|
||||||
MINIO_BUCKET=ingest
|
|
||||||
|
|
||||||
# AnythingLLM
|
|
||||||
ANYLLM_API_KEY=change_me
|
|
||||||
ANYLLM_BASE_URL=http://anythingllm:3001
|
|
||||||
ANYLLM_WORKSPACE_NORMES=workspace_normes
|
|
||||||
ANYLLM_WORKSPACE_TRAMES=workspace_trames
|
|
||||||
ANYLLM_WORKSPACE_ACTES=workspace_actes
|
|
||||||
|
|
||||||
# Ollama (LLM local)
|
|
||||||
OLLAMA_BASE_URL=http://ollama:11434
|
|
||||||
OLLAMA_MODELS=llama3:8b,mistral:7b
|
|
||||||
|
|
||||||
# Neo4j (Graphe de connaissances)
|
|
||||||
NEO4J_AUTH=neo4j/neo4j_pwd
|
|
||||||
|
|
||||||
# OpenSearch (Recherche plein-texte)
|
|
||||||
OPENSEARCH_PASSWORD=opensearch_pwd
|
|
||||||
|
|
||||||
# Traefik (Passerelle HTTP)
|
|
||||||
TRAEFIK_ACME_EMAIL=ops@example.org
|
|
||||||
|
|
||||||
# Configuration de l'API
|
|
||||||
API_HOST=0.0.0.0
|
|
||||||
API_PORT=8000
|
|
||||||
API_WORKERS=1
|
|
||||||
|
|
||||||
# Configuration des workers
|
|
||||||
WORKER_CONCURRENCY=2
|
|
||||||
WORKER_LOGLEVEL=info
|
|
||||||
|
|
||||||
# Seuils de qualité
|
|
||||||
OCR_CONFIDENCE_THRESHOLD=0.75
|
|
||||||
CLASSIFICATION_CONFIDENCE_THRESHOLD=0.75
|
|
||||||
MANUAL_REVIEW_CER_THRESHOLD=0.08
|
|
||||||
|
|
||||||
# URLs des APIs externes
|
|
||||||
CADASTRE_API_URL=https://apicarto.ign.fr/api/cadastre
|
|
||||||
GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
|
|
||||||
BODACC_API_URL=https://bodacc-datadila.opendatasoft.com/api
|
|
||||||
INFOGREFFE_API_URL=https://entreprise.api.gouv.fr/v2/infogreffe
|
|
||||||
RBE_API_URL=https://www.data.gouv.fr/api/1/datasets/registre-des-beneficiaires-effectifs
|
|
||||||
|
|
||||||
# Configuration de sécurité
|
|
||||||
JWT_SECRET_KEY=your-secret-key-change-in-production
|
|
||||||
ENCRYPTION_KEY=your-encryption-key-change-in-production
|
|
||||||
|
|
||||||
# Configuration de monitoring
|
|
||||||
PROMETHEUS_ENABLED=true
|
|
||||||
GRAFANA_ENABLED=true
|
|
||||||
SENTRY_DSN=
|
|
||||||
|
|
||||||
# Configuration de logs
|
|
||||||
LOG_LEVEL=INFO
|
|
||||||
LOG_FORMAT=json
|
|
@ -1,21 +0,0 @@
|
|||||||
# Configuration simplifiée sans IA
|
|
||||||
PROJECT_NAME=notariat
|
|
||||||
DOMAIN=localhost
|
|
||||||
TZ=Europe/Paris
|
|
||||||
|
|
||||||
# Base de données PostgreSQL
|
|
||||||
POSTGRES_USER=notariat
|
|
||||||
POSTGRES_PASSWORD=notariat_pwd
|
|
||||||
POSTGRES_DB=notariat
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
REDIS_PASSWORD=
|
|
||||||
|
|
||||||
# MinIO (stockage objet)
|
|
||||||
MINIO_ROOT_USER=minio
|
|
||||||
MINIO_ROOT_PASSWORD=minio_pwd
|
|
||||||
MINIO_BUCKET=ingest
|
|
||||||
|
|
||||||
# Configuration de développement
|
|
||||||
DEBUG=true
|
|
||||||
LOG_LEVEL=debug
|
|
17
infra/dnsmasq-4nk-ia.conf
Normal file
17
infra/dnsmasq-4nk-ia.conf
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# dnsmasq config for 4NK_IA_back - listens on all interfaces:53
|
||||||
|
no-dhcp-interface=
|
||||||
|
port=53
|
||||||
|
interface=*
|
||||||
|
bind-interfaces
|
||||||
|
log-queries
|
||||||
|
|
||||||
|
# 4NK_IA_back Docker hosts
|
||||||
|
address=/4nk-ia-api.local/172.23.0.10
|
||||||
|
address=/4nk-ia-worker.local/172.23.0.11
|
||||||
|
address=/4nk-ia-postgres.local/172.23.0.12
|
||||||
|
address=/4nk-ia-redis.local/172.23.0.13
|
||||||
|
address=/4nk-ia-minio.local/172.23.0.14
|
||||||
|
address=/4nk-ia-ollama.local/172.23.0.15
|
||||||
|
address=/4nk-ia-anythingllm.local/172.23.0.16
|
||||||
|
address=/4nk-ia-neo4j.local/172.23.0.17
|
||||||
|
address=/4nk-ia-opensearch.local/172.23.0.18
|
@ -1,182 +0,0 @@
|
|||||||
x-env: &default-env
|
|
||||||
TZ: ${TZ}
|
|
||||||
PUID: "1000"
|
|
||||||
PGID: "1000"
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
postgres:
|
|
||||||
image: postgres:16
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
|
||||||
volumes:
|
|
||||||
- pgdata:/var/lib/postgresql/data
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
command: ["redis-server", "--appendonly", "yes"]
|
|
||||||
volumes:
|
|
||||||
- redis:/data
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
minio:
|
|
||||||
image: minio/minio:latest
|
|
||||||
command: server /data --console-address ":9001"
|
|
||||||
environment:
|
|
||||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
|
||||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- minio:/data
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
- "9001:9001"
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
anythingsqlite:
|
|
||||||
image: mintplexlabs/anythingllm:latest
|
|
||||||
environment:
|
|
||||||
- DISABLE_AUTH=true
|
|
||||||
depends_on:
|
|
||||||
- ollama
|
|
||||||
ports:
|
|
||||||
- "3001:3001"
|
|
||||||
volumes:
|
|
||||||
- anythingllm:/app/server/storage
|
|
||||||
container_name: anythingllm
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
ollama:
|
|
||||||
image: ollama/ollama:latest
|
|
||||||
volumes:
|
|
||||||
- ollama:/root/.ollama
|
|
||||||
ports:
|
|
||||||
- "11434:11434"
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
neo4j:
|
|
||||||
image: neo4j:5
|
|
||||||
environment:
|
|
||||||
- NEO4J_AUTH=${NEO4J_AUTH}
|
|
||||||
volumes:
|
|
||||||
- neo4j:/data
|
|
||||||
ports:
|
|
||||||
- "7474:7474"
|
|
||||||
- "7687:7687"
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
opensearch:
|
|
||||||
image: opensearchproject/opensearch:2.14.0
|
|
||||||
environment:
|
|
||||||
- discovery.type=single-node
|
|
||||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
ulimits:
|
|
||||||
memlock:
|
|
||||||
soft: -1
|
|
||||||
hard: -1
|
|
||||||
volumes:
|
|
||||||
- opensearch:/usr/share/opensearch/data
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
host-api:
|
|
||||||
build:
|
|
||||||
context: ../docker/host-api
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
labels:
|
|
||||||
- logging=promtail
|
|
||||||
- project=4nk_ia_back
|
|
||||||
env_file: ./.env
|
|
||||||
environment:
|
|
||||||
<<: *default-env
|
|
||||||
DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB
|
|
||||||
REDIS_URL: redis://redis:6379/0
|
|
||||||
MINIO_ENDPOINT: minio:9000
|
|
||||||
MINIO_BUCKET: ${MINIO_BUCKET}
|
|
||||||
ANYLLM_BASE_URL: ${ANYLLM_BASE_URL}
|
|
||||||
ANYLLM_API_KEY: ${ANYLLM_API_KEY}
|
|
||||||
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL}
|
|
||||||
OPENSEARCH_URL: http://opensearch:9200
|
|
||||||
NEO4J_URL: bolt://neo4j:7687
|
|
||||||
NEO4J_AUTH: ${NEO4J_AUTH}
|
|
||||||
# Configuration de l'API
|
|
||||||
API_HOST: 0.0.0.0
|
|
||||||
API_PORT: 8000
|
|
||||||
API_WORKERS: 4
|
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
|
||||||
LOG_FORMAT: ${LOG_FORMAT:-json}
|
|
||||||
# Sécurité
|
|
||||||
SECRET_KEY: ${SECRET_KEY:-your_secret_key_here}
|
|
||||||
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-30}
|
|
||||||
volumes:
|
|
||||||
- ../services/host_api:/app
|
|
||||||
- ../ops/seed:/seed:ro
|
|
||||||
- ../ops/seed/schemas:/schemas:ro
|
|
||||||
- api_logs:/app/logs
|
|
||||||
ports:
|
|
||||||
- "8000:8000"
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_started
|
|
||||||
minio:
|
|
||||||
condition: service_started
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
worker:
|
|
||||||
build:
|
|
||||||
context: ../
|
|
||||||
dockerfile: docker/worker/Dockerfile
|
|
||||||
labels:
|
|
||||||
- logging=promtail
|
|
||||||
- project=4nk_ia_back
|
|
||||||
env_file: ./.env
|
|
||||||
environment:
|
|
||||||
<<: *default-env
|
|
||||||
DATABASE_URL: postgresql+psycopg://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB
|
|
||||||
REDIS_URL: redis://redis:6379/0
|
|
||||||
MINIO_ENDPOINT: minio:9000
|
|
||||||
MINIO_BUCKET: ${MINIO_BUCKET}
|
|
||||||
ANYLLM_BASE_URL: ${ANYLLM_BASE_URL}
|
|
||||||
ANYLLM_API_KEY: ${ANYLLM_API_KEY}
|
|
||||||
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL}
|
|
||||||
OPENSEARCH_URL: http://opensearch:9200
|
|
||||||
NEO4J_URL: bolt://neo4j:7687
|
|
||||||
NEO4J_AUTH: ${NEO4J_AUTH}
|
|
||||||
volumes:
|
|
||||||
- ../services/worker:/app
|
|
||||||
- ../ops/seed:/seed:ro
|
|
||||||
depends_on:
|
|
||||||
- host-api
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
pgdata:
|
|
||||||
redis:
|
|
||||||
minio:
|
|
||||||
ollama:
|
|
||||||
neo4j:
|
|
||||||
opensearch:
|
|
||||||
anythingllm:
|
|
||||||
api_logs:
|
|
43
infra/setup-dnsmasq.sh
Executable file
43
infra/setup-dnsmasq.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script de configuration dnsmasq pour 4NK_IA_back
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "🔧 Configuration de dnsmasq pour 4NK_IA_back"
|
||||||
|
|
||||||
|
# Vérifier si dnsmasq est installé
|
||||||
|
if ! command -v dnsmasq &> /dev/null; then
|
||||||
|
echo "📦 Installation de dnsmasq..."
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y dnsmasq
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Créer le répertoire de configuration
|
||||||
|
sudo mkdir -p /etc/dnsmasq.d
|
||||||
|
|
||||||
|
# Copier la configuration 4NK_IA_back
|
||||||
|
echo "📝 Copie de la configuration dnsmasq..."
|
||||||
|
sudo cp dnsmasq-4nk-ia.conf /etc/dnsmasq.d/4nk-ia.conf
|
||||||
|
|
||||||
|
# Redémarrer dnsmasq
|
||||||
|
echo "🔄 Redémarrage de dnsmasq..."
|
||||||
|
sudo systemctl restart dnsmasq
|
||||||
|
sudo systemctl enable dnsmasq
|
||||||
|
|
||||||
|
# Vérifier le statut
|
||||||
|
echo "✅ Vérification du statut de dnsmasq..."
|
||||||
|
sudo systemctl status dnsmasq --no-pager -l
|
||||||
|
|
||||||
|
echo "🎉 Configuration dnsmasq terminée !"
|
||||||
|
echo ""
|
||||||
|
echo "📋 Services disponibles :"
|
||||||
|
echo " - 4nk-ia-api.local:172.21.0.10"
|
||||||
|
echo " - 4nk-ia-worker.local:172.21.0.11"
|
||||||
|
echo " - 4nk-ia-postgres.local:172.21.0.12"
|
||||||
|
echo " - 4nk-ia-redis.local:172.21.0.13"
|
||||||
|
echo " - 4nk-ia-minio.local:172.21.0.14"
|
||||||
|
echo " - 4nk-ia-ollama.local:172.21.0.15"
|
||||||
|
echo " - 4nk-ia-anythingllm.local:172.21.0.16"
|
||||||
|
echo " - 4nk-ia-neo4j.local:172.21.0.17"
|
||||||
|
echo " - 4nk-ia-opensearch.local:172.21.0.18"
|
||||||
|
|
218
manage.sh
Executable file
218
manage.sh
Executable file
@ -0,0 +1,218 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script de gestion principal pour 4NK_IA_back
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Couleurs pour les messages
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Fonction d'affichage des messages
|
||||||
|
log_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction d'aide
|
||||||
|
show_help() {
|
||||||
|
cat << EOF
|
||||||
|
🔧 Gestionnaire 4NK_IA_back
|
||||||
|
|
||||||
|
Usage: $0 <command> [options]
|
||||||
|
|
||||||
|
COMMANDES PRINCIPALES:
|
||||||
|
up [profile] Démarrer les services (production|development|test)
|
||||||
|
down Arrêter tous les services
|
||||||
|
restart [profile] Redémarrer les services
|
||||||
|
status Afficher le statut des services
|
||||||
|
logs [service] Afficher les logs des services
|
||||||
|
shell [service] Ouvrir un shell dans un conteneur
|
||||||
|
clean Nettoyer les conteneurs et volumes
|
||||||
|
setup-dns Configurer dnsmasq pour les noms .local
|
||||||
|
|
||||||
|
PROFILS DISPONIBLES:
|
||||||
|
production Services de production (défaut)
|
||||||
|
development Services de développement avec volumes montés
|
||||||
|
test Services de test isolés
|
||||||
|
|
||||||
|
EXEMPLES:
|
||||||
|
$0 up # Démarrer en production
|
||||||
|
$0 up development # Démarrer en développement
|
||||||
|
$0 logs api # Voir les logs de l'API
|
||||||
|
$0 shell postgres # Ouvrir un shell PostgreSQL
|
||||||
|
$0 clean # Nettoyer tout
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour démarrer les services
|
||||||
|
start_services() {
|
||||||
|
local profile=${1:-production}
|
||||||
|
|
||||||
|
log_info "Démarrage des services avec le profil: $profile"
|
||||||
|
|
||||||
|
case $profile in
|
||||||
|
production|development|test)
|
||||||
|
docker-compose --profile "$profile" up -d
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "Profil invalide: $profile. Utilisez: production, development, ou test"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log_success "Services démarrés avec le profil: $profile"
|
||||||
|
log_info "Vérification du statut..."
|
||||||
|
docker-compose ps
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour arrêter les services
|
||||||
|
stop_services() {
|
||||||
|
log_info "Arrêt des services..."
|
||||||
|
docker-compose down
|
||||||
|
log_success "Services arrêtés"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour redémarrer les services
|
||||||
|
restart_services() {
|
||||||
|
local profile=${1:-production}
|
||||||
|
log_info "Redémarrage des services avec le profil: $profile"
|
||||||
|
stop_services
|
||||||
|
start_services "$profile"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour afficher le statut
|
||||||
|
show_status() {
|
||||||
|
log_info "Statut des services:"
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_info "Réseaux Docker:"
|
||||||
|
docker network ls | grep 4nk_ia
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_info "Volumes Docker:"
|
||||||
|
docker volume ls | grep 4nk_ia
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour afficher les logs
|
||||||
|
show_logs() {
|
||||||
|
local service=${1:-}
|
||||||
|
|
||||||
|
if [[ -n "$service" ]]; then
|
||||||
|
log_info "Logs du service: $service"
|
||||||
|
docker-compose logs -f "$service"
|
||||||
|
else
|
||||||
|
log_info "Logs de tous les services:"
|
||||||
|
docker-compose logs -f
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour ouvrir un shell
|
||||||
|
open_shell() {
|
||||||
|
local service=${1:-host-api}
|
||||||
|
|
||||||
|
log_info "Ouverture d'un shell dans le service: $service"
|
||||||
|
docker-compose exec "$service" /bin/bash
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction de nettoyage
|
||||||
|
clean_all() {
|
||||||
|
log_warning "Cette action va supprimer tous les conteneurs, réseaux et volumes 4NK_IA_back"
|
||||||
|
read -p "Êtes-vous sûr ? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log_info "Nettoyage en cours..."
|
||||||
|
docker-compose down -v --remove-orphans
|
||||||
|
docker system prune -f
|
||||||
|
log_success "Nettoyage terminé"
|
||||||
|
else
|
||||||
|
log_info "Nettoyage annulé"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour configurer dnsmasq
|
||||||
|
setup_dns() {
|
||||||
|
log_info "Configuration de dnsmasq pour les noms .local"
|
||||||
|
|
||||||
|
if [[ -f "./infra/setup-dnsmasq.sh" ]]; then
|
||||||
|
sudo ./infra/setup-dnsmasq.sh
|
||||||
|
else
|
||||||
|
log_error "Script setup-dnsmasq.sh non trouvé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour tester l'API
|
||||||
|
test_api() {
|
||||||
|
log_info "Test de l'API..."
|
||||||
|
|
||||||
|
# Attendre que l'API soit prête
|
||||||
|
log_info "Attente du démarrage de l'API..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Test de santé
|
||||||
|
if curl -s http://localhost:8001/api/health > /dev/null; then
|
||||||
|
log_success "API accessible sur http://localhost:8001"
|
||||||
|
curl -s http://localhost:8001/api/health | jq .
|
||||||
|
else
|
||||||
|
log_error "API non accessible"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gestion des arguments
|
||||||
|
case "${1:-help}" in
|
||||||
|
up)
|
||||||
|
start_services "${2:-production}"
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
stop_services
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
restart_services "${2:-production}"
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
show_logs "${2:-}"
|
||||||
|
;;
|
||||||
|
shell)
|
||||||
|
open_shell "${2:-host-api}"
|
||||||
|
;;
|
||||||
|
clean)
|
||||||
|
clean_all
|
||||||
|
;;
|
||||||
|
setup-dns)
|
||||||
|
setup_dns
|
||||||
|
;;
|
||||||
|
test)
|
||||||
|
test_api
|
||||||
|
;;
|
||||||
|
help|--help|-h)
|
||||||
|
show_help
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "Commande inconnue: $1"
|
||||||
|
echo ""
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
370
services/web_interface/bootstrap.min.css
vendored
370
services/web_interface/bootstrap.min.css
vendored
@ -1,370 +0,0 @@
|
|||||||
/* Bootstrap CSS minimal pour 4NK Notariat */
|
|
||||||
:root {
|
|
||||||
--bs-blue: #0d6efd;
|
|
||||||
--bs-indigo: #6610f2;
|
|
||||||
--bs-purple: #6f42c1;
|
|
||||||
--bs-pink: #d63384;
|
|
||||||
--bs-red: #dc3545;
|
|
||||||
--bs-orange: #fd7e14;
|
|
||||||
--bs-yellow: #ffc107;
|
|
||||||
--bs-green: #198754;
|
|
||||||
--bs-teal: #20c997;
|
|
||||||
--bs-cyan: #0dcaf0;
|
|
||||||
--bs-white: #fff;
|
|
||||||
--bs-gray: #6c757d;
|
|
||||||
--bs-gray-dark: #343a40;
|
|
||||||
--bs-primary: #0d6efd;
|
|
||||||
--bs-secondary: #6c757d;
|
|
||||||
--bs-success: #198754;
|
|
||||||
--bs-info: #0dcaf0;
|
|
||||||
--bs-warning: #ffc107;
|
|
||||||
--bs-danger: #dc3545;
|
|
||||||
--bs-light: #f8f9fa;
|
|
||||||
--bs-dark: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #212529;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 15px;
|
|
||||||
padding-left: 15px;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-right: -15px;
|
|
||||||
margin-left: -15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-2, .col-md-4, .col-md-6, .col-md-8, .col-md-9, .col-md-10 {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 15px;
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-2 { flex: 0 0 16.666667%; max-width: 16.666667%; }
|
|
||||||
.col-md-4 { flex: 0 0 33.333333%; max-width: 33.333333%; }
|
|
||||||
.col-md-6 { flex: 0 0 50%; max-width: 50%; }
|
|
||||||
.col-md-8 { flex: 0 0 66.666667%; max-width: 66.666667%; }
|
|
||||||
.col-md-9 { flex: 0 0 75%; max-width: 75%; }
|
|
||||||
.col-md-10 { flex: 0 0 83.333333%; max-width: 83.333333%; }
|
|
||||||
|
|
||||||
.card {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-width: 0;
|
|
||||||
word-wrap: break-word;
|
|
||||||
background-color: #fff;
|
|
||||||
background-clip: border-box;
|
|
||||||
border: 1px solid rgba(0,0,0,.125);
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
padding: 0.75rem 1.25rem;
|
|
||||||
margin-bottom: 0;
|
|
||||||
background-color: rgba(0,0,0,.03);
|
|
||||||
border-bottom: 1px solid rgba(0,0,0,.125);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-body {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
padding: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
display: inline-block;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #212529;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
padding: 0.375rem 0.75rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #0d6efd;
|
|
||||||
border-color: #0d6efd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #0b5ed7;
|
|
||||||
border-color: #0a58ca;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-primary {
|
|
||||||
color: #0d6efd;
|
|
||||||
border-color: #0d6efd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #0d6efd;
|
|
||||||
border-color: #0d6efd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-danger {
|
|
||||||
color: #dc3545;
|
|
||||||
border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-danger:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #dc3545;
|
|
||||||
border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-secondary {
|
|
||||||
color: #6c757d;
|
|
||||||
border-color: #6c757d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-secondary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #6c757d;
|
|
||||||
border-color: #6c757d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-sm {
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-group {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
position: relative;
|
|
||||||
padding: 0.75rem 1.25rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-success {
|
|
||||||
color: #0f5132;
|
|
||||||
background-color: #d1e7dd;
|
|
||||||
border-color: #badbcc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-danger {
|
|
||||||
color: #842029;
|
|
||||||
background-color: #f8d7da;
|
|
||||||
border-color: #f5c2c7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-warning {
|
|
||||||
color: #664d03;
|
|
||||||
background-color: #fff3cd;
|
|
||||||
border-color: #ffecb5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-info {
|
|
||||||
color: #055160;
|
|
||||||
background-color: #cff4fc;
|
|
||||||
border-color: #b6effb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.35em 0.65em;
|
|
||||||
font-size: 0.75em;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 1;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: baseline;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-success { background-color: #198754 !important; }
|
|
||||||
.bg-danger { background-color: #dc3545 !important; }
|
|
||||||
.bg-warning { background-color: #ffc107 !important; }
|
|
||||||
.bg-info { background-color: #0dcaf0 !important; }
|
|
||||||
.bg-primary { background-color: #0d6efd !important; }
|
|
||||||
.bg-secondary { background-color: #6c757d !important; }
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-brand {
|
|
||||||
padding-top: 0.3125rem;
|
|
||||||
padding-bottom: 0.3125rem;
|
|
||||||
margin-right: 1rem;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
color: rgba(0,0,0,.9);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding-left: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
display: block;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
color: #0d6efd;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link:hover {
|
|
||||||
color: #0a58ca;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link.active {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #0d6efd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
|
||||||
display: flex;
|
|
||||||
height: 1rem;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
background-color: #e9ecef;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
background-color: #0d6efd;
|
|
||||||
transition: width .6s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center { text-align: center !important; }
|
|
||||||
.text-muted { color: #6c757d !important; }
|
|
||||||
.text-primary { color: #0d6efd !important; }
|
|
||||||
.text-success { color: #198754 !important; }
|
|
||||||
.text-danger { color: #dc3545 !important; }
|
|
||||||
|
|
||||||
.mb-0 { margin-bottom: 0 !important; }
|
|
||||||
.mb-1 { margin-bottom: 0.25rem !important; }
|
|
||||||
.mb-2 { margin-bottom: 0.5rem !important; }
|
|
||||||
.mb-3 { margin-bottom: 1rem !important; }
|
|
||||||
.mb-4 { margin-bottom: 1.5rem !important; }
|
|
||||||
.mb-5 { margin-bottom: 3rem !important; }
|
|
||||||
|
|
||||||
.mt-2 { margin-top: 0.5rem !important; }
|
|
||||||
.mt-3 { margin-top: 1rem !important; }
|
|
||||||
.mt-4 { margin-top: 1.5rem !important; }
|
|
||||||
|
|
||||||
.me-2 { margin-right: 0.5rem !important; }
|
|
||||||
.ms-2 { margin-left: 0.5rem !important; }
|
|
||||||
|
|
||||||
.py-5 { padding-top: 3rem !important; padding-bottom: 3rem !important; }
|
|
||||||
|
|
||||||
.img-thumbnail {
|
|
||||||
padding: 0.25rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded {
|
|
||||||
border-radius: 0.375rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border {
|
|
||||||
border: 1px solid #dee2e6 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.d-none { display: none !important; }
|
|
||||||
|
|
||||||
.list-unstyled {
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-left: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
color: #212529;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid rgba(0,0,0,.125);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item:first-child {
|
|
||||||
border-top-left-radius: inherit;
|
|
||||||
border-top-right-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item:last-child {
|
|
||||||
border-bottom-right-radius: inherit;
|
|
||||||
border-bottom-left-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive */
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.col-md-2, .col-md-4, .col-md-6, .col-md-8, .col-md-9, .col-md-10 {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
150
services/web_interface/chart.min.js
vendored
150
services/web_interface/chart.min.js
vendored
@ -1,150 +0,0 @@
|
|||||||
// Chart.js minimal pour 4NK Notariat
|
|
||||||
window.Chart = class Chart {
|
|
||||||
constructor(ctx, config) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.config = config;
|
|
||||||
this.destroyed = false;
|
|
||||||
|
|
||||||
// Créer un canvas simple si Chart.js n'est pas disponible
|
|
||||||
this.createSimpleChart();
|
|
||||||
}
|
|
||||||
|
|
||||||
createSimpleChart() {
|
|
||||||
if (this.destroyed) return;
|
|
||||||
|
|
||||||
const canvas = this.ctx;
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
const config = this.config;
|
|
||||||
|
|
||||||
// Effacer le canvas
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
if (config.type === 'doughnut') {
|
|
||||||
this.drawDoughnutChart(ctx, config);
|
|
||||||
} else if (config.type === 'line') {
|
|
||||||
this.drawLineChart(ctx, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drawDoughnutChart(ctx, config) {
|
|
||||||
const data = config.data;
|
|
||||||
const labels = data.labels || [];
|
|
||||||
const values = data.datasets[0].data || [];
|
|
||||||
const colors = data.datasets[0].backgroundColor || ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF'];
|
|
||||||
|
|
||||||
const canvas = this.ctx;
|
|
||||||
const centerX = canvas.width / 2;
|
|
||||||
const centerY = canvas.height / 2;
|
|
||||||
const radius = Math.min(centerX, centerY) - 20;
|
|
||||||
|
|
||||||
const total = values.reduce((sum, val) => sum + val, 0);
|
|
||||||
let currentAngle = 0;
|
|
||||||
|
|
||||||
// Dessiner les segments
|
|
||||||
values.forEach((value, index) => {
|
|
||||||
const sliceAngle = (value / total) * 2 * Math.PI;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(centerX, centerY);
|
|
||||||
ctx.arc(centerX, centerY, radius, currentAngle, currentAngle + sliceAngle);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.fillStyle = colors[index % colors.length];
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
currentAngle += sliceAngle;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dessiner la légende
|
|
||||||
let legendY = 20;
|
|
||||||
labels.forEach((label, index) => {
|
|
||||||
ctx.fillStyle = colors[index % colors.length];
|
|
||||||
ctx.fillRect(10, legendY, 15, 15);
|
|
||||||
ctx.fillStyle = '#333';
|
|
||||||
ctx.font = '12px Arial';
|
|
||||||
ctx.fillText(label, 30, legendY + 12);
|
|
||||||
legendY += 20;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
drawLineChart(ctx, config) {
|
|
||||||
const data = config.data;
|
|
||||||
const labels = data.labels || [];
|
|
||||||
const values = data.datasets[0].data || [];
|
|
||||||
const color = data.datasets[0].borderColor || '#007bff';
|
|
||||||
|
|
||||||
const canvas = this.ctx;
|
|
||||||
const padding = 40;
|
|
||||||
const chartWidth = canvas.width - 2 * padding;
|
|
||||||
const chartHeight = canvas.height - 2 * padding;
|
|
||||||
|
|
||||||
const maxValue = Math.max(...values);
|
|
||||||
const minValue = Math.min(...values);
|
|
||||||
const valueRange = maxValue - minValue || 1;
|
|
||||||
|
|
||||||
// Dessiner les axes
|
|
||||||
ctx.strokeStyle = '#ddd';
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(padding, padding);
|
|
||||||
ctx.lineTo(padding, canvas.height - padding);
|
|
||||||
ctx.lineTo(canvas.width - padding, canvas.height - padding);
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
// Dessiner la ligne
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.beginPath();
|
|
||||||
|
|
||||||
values.forEach((value, index) => {
|
|
||||||
const x = padding + (index / (values.length - 1)) * chartWidth;
|
|
||||||
const y = canvas.height - padding - ((value - minValue) / valueRange) * chartHeight;
|
|
||||||
|
|
||||||
if (index === 0) {
|
|
||||||
ctx.moveTo(x, y);
|
|
||||||
} else {
|
|
||||||
ctx.lineTo(x, y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
// Dessiner les points
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
values.forEach((value, index) => {
|
|
||||||
const x = padding + (index / (values.length - 1)) * chartWidth;
|
|
||||||
const y = canvas.height - padding - ((value - minValue) / valueRange) * chartHeight;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x, y, 4, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dessiner les labels
|
|
||||||
ctx.fillStyle = '#333';
|
|
||||||
ctx.font = '10px Arial';
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
labels.forEach((label, index) => {
|
|
||||||
const x = padding + (index / (values.length - 1)) * chartWidth;
|
|
||||||
ctx.fillText(label, x, canvas.height - 10);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.destroyed = true;
|
|
||||||
if (this.ctx && this.ctx.clearRect) {
|
|
||||||
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
if (!this.destroyed) {
|
|
||||||
this.createSimpleChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Simuler les options globales
|
|
||||||
window.Chart.defaults = {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false
|
|
||||||
};
|
|
25
services/web_interface/fontawesome.min.css
vendored
25
services/web_interface/fontawesome.min.css
vendored
@ -1,25 +0,0 @@
|
|||||||
/* Font Awesome minimal pour 4NK Notariat */
|
|
||||||
.fas, .fa {
|
|
||||||
font-family: "Font Awesome 5 Free";
|
|
||||||
font-weight: 900;
|
|
||||||
display: inline-block;
|
|
||||||
font-style: normal;
|
|
||||||
font-variant: normal;
|
|
||||||
text-rendering: auto;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa-cloud-upload-alt:before { content: "☁"; }
|
|
||||||
.fa-folder-open:before { content: "📁"; }
|
|
||||||
.fa-file:before { content: "📄"; }
|
|
||||||
.fa-file-pdf:before { content: "📕"; }
|
|
||||||
.fa-file-alt:before { content: "📄"; }
|
|
||||||
.fa-upload:before { content: "⬆"; }
|
|
||||||
.fa-times:before { content: "✕"; }
|
|
||||||
.fa-eye:before { content: "👁"; }
|
|
||||||
.fa-search:before { content: "🔍"; }
|
|
||||||
.fa-download:before { content: "⬇"; }
|
|
||||||
.fa-upload:before { content: "⬆"; }
|
|
||||||
.fa-3x { font-size: 3em; }
|
|
||||||
.fa-4x { font-size: 4em; }
|
|
||||||
.fa-2x { font-size: 2em; }
|
|
@ -1,441 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>4NK Notariat - Traitement de Documents</title>
|
|
||||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📄</text></svg>">
|
|
||||||
<link href="bootstrap.min.css" rel="stylesheet">
|
|
||||||
<link href="fontawesome.min.css" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
.upload-area {
|
|
||||||
border: 2px dashed #007bff;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 40px;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
.upload-area:hover {
|
|
||||||
border-color: #0056b3;
|
|
||||||
background-color: #e3f2fd;
|
|
||||||
}
|
|
||||||
.upload-area.dragover {
|
|
||||||
border-color: #28a745;
|
|
||||||
background-color: #d4edda;
|
|
||||||
}
|
|
||||||
.document-card {
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
}
|
|
||||||
.document-card:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
.status-badge {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
.progress-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.analysis-section {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.entity-item {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
border-left: 4px solid #007bff;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
|
||||||
.verification-item {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
border-left: 4px solid #28a745;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
|
||||||
.verification-item.error {
|
|
||||||
border-left-color: #dc3545;
|
|
||||||
}
|
|
||||||
.verification-item.warning {
|
|
||||||
border-left-color: #ffc107;
|
|
||||||
}
|
|
||||||
.sidebar {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
.main-content {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="col-md-3 sidebar p-3">
|
|
||||||
<h4 class="mb-4">
|
|
||||||
<i class="fas fa-balance-scale text-primary"></i>
|
|
||||||
4NK Notariat
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<nav class="nav flex-column">
|
|
||||||
<a class="nav-link active" href="#upload" data-section="upload">
|
|
||||||
<i class="fas fa-upload"></i> Upload Document
|
|
||||||
</a>
|
|
||||||
<a class="nav-link" href="#documents" data-section="documents">
|
|
||||||
<i class="fas fa-file-alt"></i> Documents
|
|
||||||
</a>
|
|
||||||
<a class="nav-link" href="#stats" data-section="stats">
|
|
||||||
<i class="fas fa-chart-bar"></i> Statistiques
|
|
||||||
</a>
|
|
||||||
<a class="nav-link" href="#settings" data-section="settings">
|
|
||||||
<i class="fas fa-cog"></i> Paramètres
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<h6>Statut du Système</h6>
|
|
||||||
<div id="system-status">
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span>API:</span>
|
|
||||||
<span class="badge bg-success" id="api-status">Connecté</span>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span>LLM:</span>
|
|
||||||
<span class="badge bg-success" id="llm-status">Disponible</span>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span>APIs Externes:</span>
|
|
||||||
<span class="badge bg-success" id="external-apis-status">OK</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<div class="col-md-9 main-content">
|
|
||||||
<!-- Upload Section -->
|
|
||||||
<div id="upload-section" class="content-section">
|
|
||||||
<h2 class="mb-4">
|
|
||||||
<i class="fas fa-upload text-primary"></i>
|
|
||||||
Upload de Document Notarial
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<form id="upload-form">
|
|
||||||
<div class="upload-area" id="upload-area">
|
|
||||||
<i class="fas fa-cloud-upload-alt fa-3x text-primary mb-3"></i>
|
|
||||||
<h5>Glissez-déposez votre document ici</h5>
|
|
||||||
<p class="text-muted">ou cliquez pour sélectionner un fichier</p>
|
|
||||||
<input type="file" id="file-input" class="d-none" accept=".pdf,.jpg,.jpeg,.png,.tiff,.heic">
|
|
||||||
<button type="button" class="btn btn-primary" onclick="document.getElementById('file-input').click()">
|
|
||||||
<i class="fas fa-folder-open"></i> Sélectionner un fichier
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<label for="id-dossier" class="form-label">ID Dossier *</label>
|
|
||||||
<input type="text" class="form-control" id="id-dossier" required>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<label for="etude-id" class="form-label">ID Étude *</label>
|
|
||||||
<input type="text" class="form-control" id="etude-id" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-3">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<label for="utilisateur-id" class="form-label">ID Utilisateur *</label>
|
|
||||||
<input type="text" class="form-control" id="utilisateur-id" required>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<label for="type-document" class="form-label">Type de Document Attendu</label>
|
|
||||||
<select class="form-select" id="type-document">
|
|
||||||
<option value="">Auto-détection</option>
|
|
||||||
<option value="acte_vente">Acte de Vente</option>
|
|
||||||
<option value="acte_donation">Acte de Donation</option>
|
|
||||||
<option value="acte_succession">Acte de Succession</option>
|
|
||||||
<option value="cni">Carte d'Identité</option>
|
|
||||||
<option value="contrat">Contrat</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<button type="submit" class="btn btn-success btn-lg">
|
|
||||||
<i class="fas fa-play"></i> Traiter le Document
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- Progress -->
|
|
||||||
<div class="progress-container mt-4">
|
|
||||||
<div class="progress">
|
|
||||||
<div class="progress-bar progress-bar-striped progress-bar-animated"
|
|
||||||
role="progressbar" style="width: 0%"></div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-2">
|
|
||||||
<small class="text-muted" id="progress-text">Initialisation...</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6><i class="fas fa-info-circle"></i> Informations</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<h6>Formats supportés:</h6>
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li><i class="fas fa-file-pdf text-danger"></i> PDF</li>
|
|
||||||
<li><i class="fas fa-file-image text-primary"></i> JPEG, PNG</li>
|
|
||||||
<li><i class="fas fa-file-image text-info"></i> TIFF, HEIC</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h6 class="mt-3">Traitement:</h6>
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li><i class="fas fa-eye"></i> OCR et extraction de texte</li>
|
|
||||||
<li><i class="fas fa-tags"></i> Classification automatique</li>
|
|
||||||
<li><i class="fas fa-search"></i> Extraction d'entités</li>
|
|
||||||
<li><i class="fas fa-check-circle"></i> Vérifications externes</li>
|
|
||||||
<li><i class="fas fa-brain"></i> Analyse LLM</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Documents Section -->
|
|
||||||
<div id="documents-section" class="content-section" style="display: none;">
|
|
||||||
<h2 class="mb-4">
|
|
||||||
<i class="fas fa-file-alt text-primary"></i>
|
|
||||||
Documents Traités
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input type="text" class="form-control" id="search-documents" placeholder="Rechercher un document...">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<select class="form-select" id="filter-status">
|
|
||||||
<option value="">Tous les statuts</option>
|
|
||||||
<option value="processing">En cours</option>
|
|
||||||
<option value="completed">Terminé</option>
|
|
||||||
<option value="error">Erreur</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<select class="form-select" id="filter-type">
|
|
||||||
<option value="">Tous les types</option>
|
|
||||||
<option value="acte_vente">Acte de Vente</option>
|
|
||||||
<option value="acte_donation">Acte de Donation</option>
|
|
||||||
<option value="acte_succession">Acte de Succession</option>
|
|
||||||
<option value="cni">Carte d'Identité</option>
|
|
||||||
<option value="contrat">Contrat</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="documents-list">
|
|
||||||
<!-- Documents will be loaded here -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Statistics Section -->
|
|
||||||
<div id="stats-section" class="content-section" style="display: none;">
|
|
||||||
<h2 class="mb-4">
|
|
||||||
<i class="fas fa-chart-bar text-primary"></i>
|
|
||||||
Statistiques
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<i class="fas fa-file-alt fa-2x text-primary mb-2"></i>
|
|
||||||
<h4 id="total-documents">0</h4>
|
|
||||||
<p class="text-muted">Documents traités</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<i class="fas fa-clock fa-2x text-warning mb-2"></i>
|
|
||||||
<h4 id="processing-documents">0</h4>
|
|
||||||
<p class="text-muted">En cours</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<i class="fas fa-check-circle fa-2x text-success mb-2"></i>
|
|
||||||
<h4 id="success-rate">0%</h4>
|
|
||||||
<p class="text-muted">Taux de réussite</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<i class="fas fa-stopwatch fa-2x text-info mb-2"></i>
|
|
||||||
<h4 id="avg-time">0s</h4>
|
|
||||||
<p class="text-muted">Temps moyen</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-4">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6>Types de Documents</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<canvas id="document-types-chart"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6>Évolution Temporelle</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<canvas id="timeline-chart"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Settings Section -->
|
|
||||||
<div id="settings-section" class="content-section" style="display: none;">
|
|
||||||
<h2 class="mb-4">
|
|
||||||
<i class="fas fa-cog text-primary"></i>
|
|
||||||
Paramètres
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6>Configuration API</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="api-url" class="form-label">URL de l'API</label>
|
|
||||||
<input type="text" class="form-control" id="api-url" value="http://localhost:8000">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="llm-model" class="form-label">Modèle LLM</label>
|
|
||||||
<select class="form-select" id="llm-model">
|
|
||||||
<option value="llama3:8b">Llama 3 8B</option>
|
|
||||||
<option value="mistral:7b">Mistral 7B</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" onclick="testConnection()">
|
|
||||||
<i class="fas fa-plug"></i> Tester la Connexion
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6>APIs Externes</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" id="enable-cadastre" checked>
|
|
||||||
<label class="form-check-label" for="enable-cadastre">
|
|
||||||
Cadastre
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" id="enable-georisques" checked>
|
|
||||||
<label class="form-check-label" for="enable-georisques">
|
|
||||||
Géorisques
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" id="enable-bodacc" checked>
|
|
||||||
<label class="form-check-label" for="enable-bodacc">
|
|
||||||
BODACC
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" id="enable-gel-avoirs" checked>
|
|
||||||
<label class="form-check-label" for="enable-gel-avoirs">
|
|
||||||
Gel des Avoirs
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Document Analysis Modal -->
|
|
||||||
<div class="modal fade" id="analysisModal" tabindex="-1">
|
|
||||||
<div class="modal-dialog modal-xl">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">
|
|
||||||
<i class="fas fa-search"></i> Analyse du Document
|
|
||||||
</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div id="analysis-content">
|
|
||||||
<!-- Analysis content will be loaded here -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
|
||||||
<button type="button" class="btn btn-primary" onclick="downloadReport()">
|
|
||||||
<i class="fas fa-download"></i> Télécharger le Rapport
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="chart.min.js"></script>
|
|
||||||
<script src="app.js"></script>
|
|
||||||
<script>
|
|
||||||
// Initialisation de l'application après chargement de app.js
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
if (typeof NotaryApp !== 'undefined') {
|
|
||||||
window.notaryApp = new NotaryApp();
|
|
||||||
} else {
|
|
||||||
console.error('NotaryApp class not found');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Serveur web simple pour l'interface 4NK Notariat
|
|
||||||
"""
|
|
||||||
import http.server
|
|
||||||
import socketserver
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
def start_web_server(port=8080):
|
|
||||||
"""Démarre le serveur web pour l'interface"""
|
|
||||||
|
|
||||||
# Répertoire de l'interface web
|
|
||||||
web_dir = Path(__file__).parent
|
|
||||||
|
|
||||||
# Changement vers le répertoire web
|
|
||||||
os.chdir(web_dir)
|
|
||||||
|
|
||||||
# Configuration du serveur avec gestion du favicon
|
|
||||||
class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|
||||||
def end_headers(self):
|
|
||||||
# Ajouter des headers pour éviter le cache du favicon
|
|
||||||
if self.path == '/favicon.ico':
|
|
||||||
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
|
|
||||||
self.send_header('Pragma', 'no-cache')
|
|
||||||
self.send_header('Expires', '0')
|
|
||||||
super().end_headers()
|
|
||||||
|
|
||||||
def do_GET(self):
|
|
||||||
try:
|
|
||||||
# Gérer le favicon.ico
|
|
||||||
if self.path == '/favicon.ico':
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header('Content-type', 'image/svg+xml')
|
|
||||||
self.end_headers()
|
|
||||||
favicon_svg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
||||||
<text y=".9em" font-size="90">📄</text>
|
|
||||||
</svg>'''
|
|
||||||
self.wfile.write(favicon_svg.encode())
|
|
||||||
return
|
|
||||||
super().do_GET()
|
|
||||||
except (BrokenPipeError, ConnectionResetError):
|
|
||||||
# Ignorer les erreurs de connexion fermée par le client
|
|
||||||
pass
|
|
||||||
|
|
||||||
handler = CustomHTTPRequestHandler
|
|
||||||
|
|
||||||
try:
|
|
||||||
with socketserver.TCPServer(("", port), handler) as httpd:
|
|
||||||
print(f"🌐 Interface web 4NK Notariat démarrée sur http://localhost:{port}")
|
|
||||||
print(f"📁 Répertoire: {web_dir}")
|
|
||||||
print("🔄 Appuyez sur Ctrl+C pour arrêter")
|
|
||||||
print()
|
|
||||||
|
|
||||||
httpd.serve_forever()
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("\n🛑 Arrêt du serveur web")
|
|
||||||
sys.exit(0)
|
|
||||||
except OSError as e:
|
|
||||||
if e.errno == 98: # Address already in use
|
|
||||||
print(f"❌ Erreur: Le port {port} est déjà utilisé")
|
|
||||||
print(f"💡 Essayez un autre port: python start_web.py {port + 1}")
|
|
||||||
else:
|
|
||||||
print(f"❌ Erreur: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# Port par défaut ou port spécifié en argument
|
|
||||||
port = 8080
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
try:
|
|
||||||
port = int(sys.argv[1])
|
|
||||||
except ValueError:
|
|
||||||
print("❌ Erreur: Le port doit être un nombre")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
start_web_server(port)
|
|
@ -6,7 +6,7 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from typing import Dict, Any, List
|
from typing import Dict, Any, List
|
||||||
from services.worker.utils.llm_client import WorkerLLMClient
|
from utils.llm_client import WorkerLLMClient
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ Tâches de classification des documents
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ Tâches d'extraction d'entités des documents
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any, List
|
from typing import Dict, Any, List
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ Tâches d'indexation des documents
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ def index_document(self, doc_id: str, text: str, entities: Dict[str, Any], doc_t
|
|||||||
|
|
||||||
# 1. Indexation dans AnythingLLM
|
# 1. Indexation dans AnythingLLM
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.anythingllm_client import AnythingLLMClient
|
from utils.anythingllm_client import AnythingLLMClient
|
||||||
anyllm_client = AnythingLLMClient()
|
anyllm_client = AnythingLLMClient()
|
||||||
anyllm_result = await anyllm_client.index_document_for_actes(
|
anyllm_result = await anyllm_client.index_document_for_actes(
|
||||||
doc_id, text, entities, doc_type
|
doc_id, text, entities, doc_type
|
||||||
@ -48,7 +48,7 @@ def index_document(self, doc_id: str, text: str, entities: Dict[str, Any], doc_t
|
|||||||
|
|
||||||
# 2. Indexation dans OpenSearch
|
# 2. Indexation dans OpenSearch
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.opensearch_client import OpenSearchClient
|
from utils.opensearch_client import OpenSearchClient
|
||||||
opensearch_client = OpenSearchClient()
|
opensearch_client = OpenSearchClient()
|
||||||
opensearch_result = await opensearch_client.index_document(doc_id, {
|
opensearch_result = await opensearch_client.index_document(doc_id, {
|
||||||
'text_content': text,
|
'text_content': text,
|
||||||
@ -64,7 +64,7 @@ def index_document(self, doc_id: str, text: str, entities: Dict[str, Any], doc_t
|
|||||||
|
|
||||||
# 3. Création du graphe Neo4j
|
# 3. Création du graphe Neo4j
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.neo4j_client import Neo4jClient
|
from utils.neo4j_client import Neo4jClient
|
||||||
neo4j_client = Neo4jClient()
|
neo4j_client = Neo4jClient()
|
||||||
|
|
||||||
# Ajout du document au graphe
|
# Ajout du document au graphe
|
||||||
|
@ -3,7 +3,7 @@ Tâches OCR pour le traitement des documents
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
from celery import current_task
|
from celery import current_task
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
from services.worker.pipelines import (
|
from pipelines import (
|
||||||
preprocess, ocr, classify, extract, index, checks, finalize
|
preprocess, ocr, classify, extract, index, checks, finalize
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ Tâches de vérification et contrôle qualité
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from services.worker.celery_app import app
|
from celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ def verify_document(self, doc_id: str, entities: Dict[str, Any], doc_type: str,
|
|||||||
# 1. Vérification des adresses via Cadastre
|
# 1. Vérification des adresses via Cadastre
|
||||||
if 'bien' in entities and 'adresse' in entities['bien']:
|
if 'bien' in entities and 'adresse' in entities['bien']:
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.external_apis import ExternalAPIManager
|
from utils.external_apis import ExternalAPIManager
|
||||||
api_manager = ExternalAPIManager()
|
api_manager = ExternalAPIManager()
|
||||||
address_result = await api_manager.verify_address(
|
address_result = await api_manager.verify_address(
|
||||||
entities['bien']['adresse'],
|
entities['bien']['adresse'],
|
||||||
@ -51,7 +51,7 @@ def verify_document(self, doc_id: str, entities: Dict[str, Any], doc_type: str,
|
|||||||
# 2. Vérification des risques géologiques
|
# 2. Vérification des risques géologiques
|
||||||
if 'bien' in entities and 'adresse' in entities['bien']:
|
if 'bien' in entities and 'adresse' in entities['bien']:
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.external_apis import ExternalAPIManager
|
from utils.external_apis import ExternalAPIManager
|
||||||
api_manager = ExternalAPIManager()
|
api_manager = ExternalAPIManager()
|
||||||
risks_result = await api_manager.check_geological_risks(
|
risks_result = await api_manager.check_geological_risks(
|
||||||
entities['bien']['adresse']
|
entities['bien']['adresse']
|
||||||
@ -64,7 +64,7 @@ def verify_document(self, doc_id: str, entities: Dict[str, Any], doc_type: str,
|
|||||||
# 3. Vérification des entreprises (si applicable)
|
# 3. Vérification des entreprises (si applicable)
|
||||||
if 'vendeur' in entities and 'nom' in entities['vendeur']:
|
if 'vendeur' in entities and 'nom' in entities['vendeur']:
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.external_apis import ExternalAPIManager
|
from utils.external_apis import ExternalAPIManager
|
||||||
api_manager = ExternalAPIManager()
|
api_manager = ExternalAPIManager()
|
||||||
company_result = await api_manager.verify_company(
|
company_result = await api_manager.verify_company(
|
||||||
entities['vendeur']['nom']
|
entities['vendeur']['nom']
|
||||||
@ -77,7 +77,7 @@ def verify_document(self, doc_id: str, entities: Dict[str, Any], doc_type: str,
|
|||||||
# 4. Vérification des personnes
|
# 4. Vérification des personnes
|
||||||
if 'vendeur' in entities or 'acheteur' in entities:
|
if 'vendeur' in entities or 'acheteur' in entities:
|
||||||
try:
|
try:
|
||||||
from services.worker.utils.external_apis import ExternalAPIManager
|
from utils.external_apis import ExternalAPIManager
|
||||||
api_manager = ExternalAPIManager()
|
api_manager = ExternalAPIManager()
|
||||||
|
|
||||||
# Vérification du vendeur
|
# Vérification du vendeur
|
||||||
|
98
start-dev.sh
98
start-dev.sh
@ -1,98 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Script de démarrage rapide pour l'environnement de développement 4NK_IA
|
|
||||||
# Usage: ./start-dev.sh
|
|
||||||
|
|
||||||
echo "=== Démarrage de l'environnement de développement 4NK_IA ==="
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Vérifier que nous sommes dans le bon répertoire
|
|
||||||
if [ ! -f "requirements-test.txt" ]; then
|
|
||||||
echo "❌ Erreur: Ce script doit être exécuté depuis le répertoire racine du projet 4NK_IA"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Activer l'environnement virtuel Python
|
|
||||||
echo "🐍 Activation de l'environnement virtuel Python..."
|
|
||||||
if [ -d "venv" ]; then
|
|
||||||
source venv/bin/activate
|
|
||||||
echo " ✅ Environnement virtuel activé"
|
|
||||||
else
|
|
||||||
echo " ❌ Environnement virtuel non trouvé. Création..."
|
|
||||||
python3 -m venv venv
|
|
||||||
source venv/bin/activate
|
|
||||||
echo " ✅ Environnement virtuel créé et activé"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier les dépendances Python
|
|
||||||
echo "📦 Vérification des dépendances Python..."
|
|
||||||
if python -c "import fastapi" 2>/dev/null; then
|
|
||||||
echo " ✅ FastAPI disponible"
|
|
||||||
else
|
|
||||||
echo " ⚠️ FastAPI non installé. Installation..."
|
|
||||||
pip install fastapi uvicorn pydantic
|
|
||||||
fi
|
|
||||||
|
|
||||||
if python -c "import pytest" 2>/dev/null; then
|
|
||||||
echo " ✅ pytest disponible"
|
|
||||||
else
|
|
||||||
echo " ⚠️ pytest non installé. Installation..."
|
|
||||||
pip install pytest
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier Docker
|
|
||||||
echo "🐳 Vérification de Docker..."
|
|
||||||
if command -v docker >/dev/null 2>&1; then
|
|
||||||
echo " ✅ Docker disponible"
|
|
||||||
if docker ps >/dev/null 2>&1; then
|
|
||||||
echo " ✅ Docker fonctionne"
|
|
||||||
else
|
|
||||||
echo " ⚠️ Docker installé mais non démarré"
|
|
||||||
echo " 💡 Démarrez Docker Desktop et activez l'intégration WSL2"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ❌ Docker non installé"
|
|
||||||
echo " 💡 Installez Docker Desktop et activez l'intégration WSL2"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier la configuration Git
|
|
||||||
echo "🔑 Vérification de la configuration Git..."
|
|
||||||
if git config --global user.name >/dev/null 2>&1; then
|
|
||||||
echo " ✅ Git configuré: $(git config --global user.name) <$(git config --global user.email)>"
|
|
||||||
else
|
|
||||||
echo " ❌ Git non configuré"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier SSH
|
|
||||||
echo "🔐 Vérification de la configuration SSH..."
|
|
||||||
if [ -f ~/.ssh/id_ed25519 ]; then
|
|
||||||
echo " ✅ Clé SSH trouvée"
|
|
||||||
if ssh -o ConnectTimeout=5 -o BatchMode=yes -T git@git.4nkweb.com 2>&1 | grep -q "successfully authenticated"; then
|
|
||||||
echo " ✅ Connexion SSH à git.4nkweb.com réussie"
|
|
||||||
else
|
|
||||||
echo " ⚠️ Connexion SSH à git.4nkweb.com échouée"
|
|
||||||
echo " 💡 Vérifiez que votre clé SSH est ajoutée à git.4nkweb.com"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ❌ Clé SSH non trouvée"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "=== Résumé de l'environnement ==="
|
|
||||||
echo "📁 Répertoire: $(pwd)"
|
|
||||||
echo "🐍 Python: $(python --version 2>/dev/null || echo 'Non disponible')"
|
|
||||||
echo "📦 pip: $(pip --version 2>/dev/null || echo 'Non disponible')"
|
|
||||||
echo "🔑 Git: $(git --version 2>/dev/null || echo 'Non disponible')"
|
|
||||||
echo "🐳 Docker: $(docker --version 2>/dev/null || echo 'Non disponible')"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "=== Commandes utiles ==="
|
|
||||||
echo "🚀 Démarrer l'API: uvicorn services.host_api.app:app --reload --host 0.0.0.0 --port 8000"
|
|
||||||
echo "🧪 Lancer les tests: pytest"
|
|
||||||
echo "🐳 Démarrer Docker: make up"
|
|
||||||
echo "📊 Voir les logs: make logs"
|
|
||||||
echo "🛑 Arrêter Docker: make down"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "✅ Environnement de développement prêt !"
|
|
||||||
echo "💡 Utilisez 'source venv/bin/activate' pour activer l'environnement virtuel"
|
|
111
start-stack.sh
111
start-stack.sh
@ -1,111 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Script de démarrage de la stack 4NK_IA_back
|
|
||||||
# Usage: ./start-stack.sh
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
echo "🚀 Démarrage de la stack 4NK_IA_back..."
|
|
||||||
|
|
||||||
# Vérifier que nous sommes dans le bon répertoire
|
|
||||||
if [ ! -f "requirements-test.txt" ]; then
|
|
||||||
echo "❌ Erreur: Ce script doit être exécuté depuis le répertoire racine du projet 4NK_IA_back"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérifier Docker
|
|
||||||
if ! command -v docker >/dev/null 2>&1; then
|
|
||||||
echo "❌ Docker n'est pas installé"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! docker ps >/dev/null 2>&1; then
|
|
||||||
echo "❌ Docker n'est pas démarré"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Aller dans le répertoire infra
|
|
||||||
cd infra
|
|
||||||
|
|
||||||
# Créer le fichier .env s'il n'existe pas
|
|
||||||
if [ ! -f .env ]; then
|
|
||||||
echo "📝 Création du fichier .env..."
|
|
||||||
cat > .env << 'EOF'
|
|
||||||
# Configuration de l'environnement 4NK_IA_back
|
|
||||||
# Fichier généré automatiquement pour le démarrage de la stack
|
|
||||||
|
|
||||||
# Configuration générale
|
|
||||||
TZ=Europe/Paris
|
|
||||||
PUID=1000
|
|
||||||
PGID=1000
|
|
||||||
|
|
||||||
# Configuration PostgreSQL
|
|
||||||
POSTGRES_USER=notariat
|
|
||||||
POSTGRES_PASSWORD=notariat_pwd
|
|
||||||
POSTGRES_DB=notariat
|
|
||||||
|
|
||||||
# Configuration MinIO
|
|
||||||
MINIO_ROOT_USER=minio
|
|
||||||
MINIO_ROOT_PASSWORD=minio_pwd
|
|
||||||
MINIO_BUCKET=ingest
|
|
||||||
MINIO_ENDPOINT=minio:9000
|
|
||||||
|
|
||||||
# Configuration Neo4j
|
|
||||||
NEO4J_AUTH=neo4j/neo4j_pwd
|
|
||||||
|
|
||||||
# Configuration OpenSearch
|
|
||||||
OPENSEARCH_PASSWORD=opensearch_pwd
|
|
||||||
|
|
||||||
# Configuration AnythingLLM
|
|
||||||
ANYLLM_BASE_URL=http://anythingsqlite:3001
|
|
||||||
ANYLLM_API_KEY=notariat_api_key_2025
|
|
||||||
ANYLLM_WORKSPACE_NORMES=workspace_normes
|
|
||||||
ANYLLM_WORKSPACE_TRAMES=workspace_trames
|
|
||||||
ANYLLM_WORKSPACE_ACTES=workspace_actes
|
|
||||||
|
|
||||||
# Configuration Ollama
|
|
||||||
OLLAMA_BASE_URL=http://ollama:11434
|
|
||||||
|
|
||||||
# Configuration des URLs externes (pour les tests)
|
|
||||||
EXTERNAL_ANYLLM_BASE_URL=http://localhost:3001
|
|
||||||
EXTERNAL_OLLAMA_BASE_URL=http://localhost:11434
|
|
||||||
EOF
|
|
||||||
echo "✅ Fichier .env créé"
|
|
||||||
else
|
|
||||||
echo "✅ Fichier .env existe déjà"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Démarrer les services
|
|
||||||
echo "🐳 Démarrage des services Docker..."
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
# Attendre que les services soient prêts
|
|
||||||
echo "⏳ Attente du démarrage des services..."
|
|
||||||
sleep 15
|
|
||||||
|
|
||||||
# Vérifier l'API
|
|
||||||
echo "🔍 Vérification de l'API..."
|
|
||||||
if curl -s http://localhost:8000/api/health > /dev/null; then
|
|
||||||
echo "✅ API accessible sur http://localhost:8000"
|
|
||||||
else
|
|
||||||
echo "⚠️ API non accessible, vérifiez les logs avec: docker compose logs host-api"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Afficher le statut
|
|
||||||
echo "📊 Statut des services:"
|
|
||||||
docker compose ps
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 Stack 4NK_IA_back démarrée !"
|
|
||||||
echo ""
|
|
||||||
echo "📋 Services disponibles:"
|
|
||||||
echo " • API Notariale: http://localhost:8000"
|
|
||||||
echo " • Documentation API: http://localhost:8000/docs"
|
|
||||||
echo " • MinIO Console: http://localhost:9001"
|
|
||||||
echo " • PostgreSQL: localhost:5432"
|
|
||||||
echo " • Redis: localhost:6379"
|
|
||||||
echo ""
|
|
||||||
echo "🔧 Commandes utiles:"
|
|
||||||
echo " • Voir les logs: docker compose logs -f"
|
|
||||||
echo " • Arrêter: docker compose down"
|
|
||||||
echo " • Redémarrer: docker compose restart"
|
|
@ -1,313 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 Démarrage du Système Notarial 4NK"
|
|
||||||
echo "======================================"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Couleurs pour les messages
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Fonction pour afficher les messages colorés
|
|
||||||
print_status() {
|
|
||||||
echo -e "${BLUE}[INFO]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_success() {
|
|
||||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_warning() {
|
|
||||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_error() {
|
|
||||||
echo -e "${RED}[ERROR]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Vérification des prérequis
|
|
||||||
check_prerequisites() {
|
|
||||||
print_status "Vérification des prérequis..."
|
|
||||||
|
|
||||||
# Python
|
|
||||||
if ! command -v python3 &> /dev/null; then
|
|
||||||
print_error "Python 3 n'est pas installé"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Docker
|
|
||||||
if ! command -v docker &> /dev/null; then
|
|
||||||
print_error "Docker n'est pas installé"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Docker Compose
|
|
||||||
if ! command -v docker-compose &> /dev/null; then
|
|
||||||
print_error "Docker Compose n'est pas installé"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Tesseract
|
|
||||||
if ! command -v tesseract &> /dev/null; then
|
|
||||||
print_warning "Tesseract OCR n'est pas installé"
|
|
||||||
print_status "Installation de Tesseract..."
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y tesseract-ocr tesseract-ocr-fra
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Prérequis vérifiés"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Configuration de l'environnement
|
|
||||||
setup_environment() {
|
|
||||||
print_status "Configuration de l'environnement..."
|
|
||||||
|
|
||||||
# Création de l'environnement virtuel si nécessaire
|
|
||||||
if [ ! -d "venv" ]; then
|
|
||||||
print_status "Création de l'environnement virtuel Python..."
|
|
||||||
python3 -m venv venv
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Activation de l'environnement virtuel
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# Installation des dépendances Python
|
|
||||||
print_status "Installation des dépendances Python..."
|
|
||||||
pip install --upgrade pip
|
|
||||||
pip install -r docker/host-api/requirements.txt
|
|
||||||
|
|
||||||
# Configuration des variables d'environnement
|
|
||||||
if [ ! -f "infra/.env" ]; then
|
|
||||||
print_status "Création du fichier de configuration..."
|
|
||||||
cp infra/.env.example infra/.env
|
|
||||||
print_warning "Veuillez éditer infra/.env avec vos paramètres"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Environnement configuré"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Démarrage des services Docker
|
|
||||||
start_docker_services() {
|
|
||||||
print_status "Démarrage des services Docker..."
|
|
||||||
|
|
||||||
cd infra
|
|
||||||
|
|
||||||
# Pull des images
|
|
||||||
print_status "Téléchargement des images Docker..."
|
|
||||||
docker-compose pull
|
|
||||||
|
|
||||||
# Démarrage des services de base
|
|
||||||
print_status "Démarrage des services de base..."
|
|
||||||
docker-compose up -d postgres redis minio ollama anythingsqlite
|
|
||||||
|
|
||||||
# Attente que les services soient prêts
|
|
||||||
print_status "Attente que les services soient prêts..."
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# Vérification des services
|
|
||||||
print_status "Vérification des services..."
|
|
||||||
|
|
||||||
# PostgreSQL
|
|
||||||
if docker-compose exec -T postgres pg_isready -U notariat &> /dev/null; then
|
|
||||||
print_success "PostgreSQL est prêt"
|
|
||||||
else
|
|
||||||
print_error "PostgreSQL n'est pas accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Redis
|
|
||||||
if docker-compose exec -T redis redis-cli ping &> /dev/null; then
|
|
||||||
print_success "Redis est prêt"
|
|
||||||
else
|
|
||||||
print_error "Redis n'est pas accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# MinIO
|
|
||||||
if curl -s http://localhost:9000/minio/health/live &> /dev/null; then
|
|
||||||
print_success "MinIO est prêt"
|
|
||||||
else
|
|
||||||
print_warning "MinIO n'est pas accessible (normal si pas encore démarré)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ollama
|
|
||||||
if curl -s http://localhost:11434/api/tags &> /dev/null; then
|
|
||||||
print_success "Ollama est prêt"
|
|
||||||
else
|
|
||||||
print_warning "Ollama n'est pas accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
|
|
||||||
# Configuration d'Ollama
|
|
||||||
setup_ollama() {
|
|
||||||
print_status "Configuration d'Ollama..."
|
|
||||||
|
|
||||||
# Attente qu'Ollama soit prêt
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Téléchargement des modèles
|
|
||||||
print_status "Téléchargement des modèles LLM..."
|
|
||||||
|
|
||||||
# Llama 3 8B
|
|
||||||
print_status "Téléchargement de Llama 3 8B..."
|
|
||||||
curl -s http://localhost:11434/api/pull -d '{"name":"llama3:8b"}' &
|
|
||||||
|
|
||||||
# Mistral 7B
|
|
||||||
print_status "Téléchargement de Mistral 7B..."
|
|
||||||
curl -s http://localhost:11434/api/pull -d '{"name":"mistral:7b"}' &
|
|
||||||
|
|
||||||
print_warning "Les modèles LLM sont en cours de téléchargement en arrière-plan"
|
|
||||||
print_warning "Cela peut prendre plusieurs minutes selon votre connexion"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Démarrage de l'API
|
|
||||||
start_api() {
|
|
||||||
print_status "Démarrage de l'API Notariale..."
|
|
||||||
|
|
||||||
cd services/host_api
|
|
||||||
|
|
||||||
# Démarrage en arrière-plan
|
|
||||||
nohup uvicorn app:app --host 0.0.0.0 --port 8000 --reload > ../../logs/api.log 2>&1 &
|
|
||||||
API_PID=$!
|
|
||||||
echo $API_PID > ../../logs/api.pid
|
|
||||||
|
|
||||||
# Attente que l'API soit prête
|
|
||||||
print_status "Attente que l'API soit prête..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Test de l'API
|
|
||||||
if curl -s http://localhost:8000/api/health &> /dev/null; then
|
|
||||||
print_success "API Notariale démarrée sur http://localhost:8000"
|
|
||||||
else
|
|
||||||
print_error "L'API n'est pas accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ../..
|
|
||||||
}
|
|
||||||
|
|
||||||
# Démarrage de l'interface web
|
|
||||||
start_web_interface() {
|
|
||||||
print_status "Démarrage de l'interface web..."
|
|
||||||
|
|
||||||
cd services/web_interface
|
|
||||||
|
|
||||||
# Démarrage en arrière-plan
|
|
||||||
nohup python start_web.py 8080 > ../../logs/web.log 2>&1 &
|
|
||||||
WEB_PID=$!
|
|
||||||
echo $WEB_PID > ../../logs/web.pid
|
|
||||||
|
|
||||||
# Attente que l'interface soit prête
|
|
||||||
sleep 3
|
|
||||||
|
|
||||||
if curl -s http://localhost:8080 &> /dev/null; then
|
|
||||||
print_success "Interface web démarrée sur http://localhost:8080"
|
|
||||||
else
|
|
||||||
print_error "L'interface web n'est pas accessible"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ../..
|
|
||||||
}
|
|
||||||
|
|
||||||
# Création des répertoires de logs
|
|
||||||
create_log_directories() {
|
|
||||||
print_status "Création des répertoires de logs..."
|
|
||||||
mkdir -p logs
|
|
||||||
print_success "Répertoires de logs créés"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Affichage du statut final
|
|
||||||
show_final_status() {
|
|
||||||
echo
|
|
||||||
echo "🎉 Système Notarial 4NK démarré avec succès!"
|
|
||||||
echo "============================================="
|
|
||||||
echo
|
|
||||||
echo "📊 Services disponibles:"
|
|
||||||
echo " • API Notariale: http://localhost:8000"
|
|
||||||
echo " • Interface Web: http://localhost:8080"
|
|
||||||
echo " • Documentation API: http://localhost:8000/docs"
|
|
||||||
echo " • MinIO Console: http://localhost:9001"
|
|
||||||
echo " • Ollama: http://localhost:11434"
|
|
||||||
echo
|
|
||||||
echo "📁 Fichiers de logs:"
|
|
||||||
echo " • API: logs/api.log"
|
|
||||||
echo " • Interface Web: logs/web.log"
|
|
||||||
echo
|
|
||||||
echo "🔧 Commandes utiles:"
|
|
||||||
echo " • Arrêter le système: ./stop_notary_system.sh"
|
|
||||||
echo " • Voir les logs: tail -f logs/api.log"
|
|
||||||
echo " • Redémarrer l'API: kill \$(cat logs/api.pid) && ./start_notary_system.sh"
|
|
||||||
echo
|
|
||||||
echo "📖 Documentation: docs/API-NOTARIALE.md"
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fonction principale
|
|
||||||
main() {
|
|
||||||
echo "Démarrage du système à $(date)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Vérification des prérequis
|
|
||||||
check_prerequisites
|
|
||||||
|
|
||||||
# Configuration de l'environnement
|
|
||||||
setup_environment
|
|
||||||
|
|
||||||
# Création des répertoires
|
|
||||||
create_log_directories
|
|
||||||
|
|
||||||
# Démarrage des services Docker
|
|
||||||
start_docker_services
|
|
||||||
|
|
||||||
# Configuration d'Ollama
|
|
||||||
setup_ollama
|
|
||||||
|
|
||||||
# Démarrage de l'API
|
|
||||||
start_api
|
|
||||||
|
|
||||||
# Démarrage de l'interface web
|
|
||||||
start_web_interface
|
|
||||||
|
|
||||||
# Affichage du statut final
|
|
||||||
show_final_status
|
|
||||||
}
|
|
||||||
|
|
||||||
# Gestion des signaux
|
|
||||||
cleanup() {
|
|
||||||
echo
|
|
||||||
print_warning "Arrêt du système..."
|
|
||||||
|
|
||||||
# Arrêt de l'API
|
|
||||||
if [ -f "logs/api.pid" ]; then
|
|
||||||
API_PID=$(cat logs/api.pid)
|
|
||||||
if kill -0 $API_PID 2>/dev/null; then
|
|
||||||
kill $API_PID
|
|
||||||
print_status "API arrêtée"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arrêt de l'interface web
|
|
||||||
if [ -f "logs/web.pid" ]; then
|
|
||||||
WEB_PID=$(cat logs/web.pid)
|
|
||||||
if kill -0 $WEB_PID 2>/dev/null; then
|
|
||||||
kill $WEB_PID
|
|
||||||
print_status "Interface web arrêtée"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arrêt des services Docker
|
|
||||||
cd infra
|
|
||||||
docker-compose down
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
print_success "Système arrêté"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Capture des signaux d'arrêt
|
|
||||||
trap cleanup SIGINT SIGTERM
|
|
||||||
|
|
||||||
# Exécution du script principal
|
|
||||||
main "$@"
|
|
@ -1,160 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🛑 Arrêt du Système Notarial 4NK"
|
|
||||||
echo "================================="
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Couleurs pour les messages
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
print_status() {
|
|
||||||
echo -e "${BLUE}[INFO]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_success() {
|
|
||||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_warning() {
|
|
||||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_error() {
|
|
||||||
echo -e "${RED}[ERROR]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Arrêt de l'API
|
|
||||||
stop_api() {
|
|
||||||
print_status "Arrêt de l'API Notariale..."
|
|
||||||
|
|
||||||
if [ -f "logs/api.pid" ]; then
|
|
||||||
API_PID=$(cat logs/api.pid)
|
|
||||||
if kill -0 $API_PID 2>/dev/null; then
|
|
||||||
kill $API_PID
|
|
||||||
print_success "API arrêtée (PID: $API_PID)"
|
|
||||||
else
|
|
||||||
print_warning "API déjà arrêtée"
|
|
||||||
fi
|
|
||||||
rm -f logs/api.pid
|
|
||||||
else
|
|
||||||
print_warning "Fichier PID de l'API non trouvé"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Arrêt de l'interface web
|
|
||||||
stop_web_interface() {
|
|
||||||
print_status "Arrêt de l'interface web..."
|
|
||||||
|
|
||||||
if [ -f "logs/web.pid" ]; then
|
|
||||||
WEB_PID=$(cat logs/web.pid)
|
|
||||||
if kill -0 $WEB_PID 2>/dev/null; then
|
|
||||||
kill $WEB_PID
|
|
||||||
print_success "Interface web arrêtée (PID: $WEB_PID)"
|
|
||||||
else
|
|
||||||
print_warning "Interface web déjà arrêtée"
|
|
||||||
fi
|
|
||||||
rm -f logs/web.pid
|
|
||||||
else
|
|
||||||
print_warning "Fichier PID de l'interface web non trouvé"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Arrêt des services Docker
|
|
||||||
stop_docker_services() {
|
|
||||||
print_status "Arrêt des services Docker..."
|
|
||||||
|
|
||||||
cd infra
|
|
||||||
|
|
||||||
# Arrêt des services
|
|
||||||
docker-compose down
|
|
||||||
|
|
||||||
print_success "Services Docker arrêtés"
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
|
|
||||||
# Nettoyage des processus orphelins
|
|
||||||
cleanup_orphaned_processes() {
|
|
||||||
print_status "Nettoyage des processus orphelins..."
|
|
||||||
|
|
||||||
# Recherche et arrêt des processus uvicorn
|
|
||||||
UVICORN_PIDS=$(pgrep -f "uvicorn.*app:app")
|
|
||||||
if [ ! -z "$UVICORN_PIDS" ]; then
|
|
||||||
echo $UVICORN_PIDS | xargs kill
|
|
||||||
print_success "Processus uvicorn orphelins arrêtés"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Recherche et arrêt des processus Python de l'interface web
|
|
||||||
WEB_PIDS=$(pgrep -f "start_web.py")
|
|
||||||
if [ ! -z "$WEB_PIDS" ]; then
|
|
||||||
echo $WEB_PIDS | xargs kill
|
|
||||||
print_success "Processus interface web orphelins arrêtés"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Affichage du statut final
|
|
||||||
show_final_status() {
|
|
||||||
echo
|
|
||||||
echo "✅ Système Notarial 4NK arrêté"
|
|
||||||
echo "==============================="
|
|
||||||
echo
|
|
||||||
echo "📊 Statut des services:"
|
|
||||||
|
|
||||||
# Vérification de l'API
|
|
||||||
if curl -s http://localhost:8000/api/health &> /dev/null; then
|
|
||||||
echo " • API: ${RED}Encore actif${NC}"
|
|
||||||
else
|
|
||||||
echo " • API: ${GREEN}Arrêté${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérification de l'interface web
|
|
||||||
if curl -s http://localhost:8080 &> /dev/null; then
|
|
||||||
echo " • Interface Web: ${RED}Encore actif${NC}"
|
|
||||||
else
|
|
||||||
echo " • Interface Web: ${GREEN}Arrêté${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vérification des services Docker
|
|
||||||
cd infra
|
|
||||||
if docker-compose ps | grep -q "Up"; then
|
|
||||||
echo " • Services Docker: ${RED}Encore actifs${NC}"
|
|
||||||
else
|
|
||||||
echo " • Services Docker: ${GREEN}Arrêtés${NC}"
|
|
||||||
fi
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "🔧 Pour redémarrer: ./start_notary_system.sh"
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fonction principale
|
|
||||||
main() {
|
|
||||||
echo "Arrêt du système à $(date)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Arrêt de l'API
|
|
||||||
stop_api
|
|
||||||
|
|
||||||
# Arrêt de l'interface web
|
|
||||||
stop_web_interface
|
|
||||||
|
|
||||||
# Arrêt des services Docker
|
|
||||||
stop_docker_services
|
|
||||||
|
|
||||||
# Nettoyage des processus orphelins
|
|
||||||
cleanup_orphaned_processes
|
|
||||||
|
|
||||||
# Attente pour que les processus se terminent
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Affichage du statut final
|
|
||||||
show_final_status
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exécution du script principal
|
|
||||||
main "$@"
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "=== Test du pipeline notarial simplifié ==="
|
|
||||||
|
|
||||||
# Test de santé de l'API
|
|
||||||
echo "1. Test de santé de l'API..."
|
|
||||||
curl -s http://localhost:8000/api/health | jq . || echo "API non accessible"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "2. Test de l'endpoint racine..."
|
|
||||||
curl -s http://localhost:8000/ | jq . || echo "Endpoint racine non accessible"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "3. Test de liste des documents..."
|
|
||||||
curl -s http://localhost:8000/api/documents | jq . || echo "Liste des documents non accessible"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Tests terminés ==="
|
|
@ -1,76 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Script de test de la configuration SSH pour 4NK_IA
|
|
||||||
# Usage: ./test-ssh-connection.sh
|
|
||||||
|
|
||||||
echo "=== Test de la configuration SSH ==="
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Vérifier la présence des clés SSH
|
|
||||||
echo "1. Vérification des clés SSH :"
|
|
||||||
if [ -f ~/.ssh/id_ed25519 ]; then
|
|
||||||
echo " ✅ Clé privée trouvée : ~/.ssh/id_ed25519"
|
|
||||||
else
|
|
||||||
echo " ❌ Clé privée manquante : ~/.ssh/id_ed25519"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f ~/.ssh/id_ed25519.pub ]; then
|
|
||||||
echo " ✅ Clé publique trouvée : ~/.ssh/id_ed25519.pub"
|
|
||||||
echo " 📋 Clé publique :"
|
|
||||||
cat ~/.ssh/id_ed25519.pub | sed 's/^/ /'
|
|
||||||
else
|
|
||||||
echo " ❌ Clé publique manquante : ~/.ssh/id_ed25519.pub"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Vérifier la configuration SSH
|
|
||||||
echo "2. Vérification de la configuration SSH :"
|
|
||||||
if [ -f ~/.ssh/config ]; then
|
|
||||||
echo " ✅ Fichier de configuration SSH trouvé"
|
|
||||||
echo " 📋 Configuration :"
|
|
||||||
cat ~/.ssh/config | sed 's/^/ /'
|
|
||||||
else
|
|
||||||
echo " ❌ Fichier de configuration SSH manquant"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Vérifier la configuration Git
|
|
||||||
echo "3. Vérification de la configuration Git :"
|
|
||||||
echo " 📋 Configuration Git :"
|
|
||||||
git config --global --list | grep -E "(user\.|url\.|init\.)" | sed 's/^/ /'
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Tester les connexions SSH
|
|
||||||
echo "4. Test des connexions SSH :"
|
|
||||||
|
|
||||||
echo " 🔍 Test de connexion à git.4nkweb.com :"
|
|
||||||
if ssh -o ConnectTimeout=10 -o BatchMode=yes -T git@git.4nkweb.com 2>&1 | grep -q "successfully authenticated"; then
|
|
||||||
echo " ✅ Connexion SSH réussie à git.4nkweb.com"
|
|
||||||
elif ssh -o ConnectTimeout=10 -o BatchMode=yes -T git@git.4nkweb.com 2>&1 | grep -q "Permission denied"; then
|
|
||||||
echo " ⚠️ Clé SSH non autorisée sur git.4nkweb.com"
|
|
||||||
echo " 💡 Ajoutez votre clé publique dans les paramètres SSH de votre compte"
|
|
||||||
else
|
|
||||||
echo " ❌ Impossible de se connecter à git.4nkweb.com"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " 🔍 GitHub non configuré (inutile pour ce projet)"
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Instructions pour ajouter les clés
|
|
||||||
echo "5. Instructions pour ajouter votre clé SSH :"
|
|
||||||
echo " 📋 Votre clé publique SSH :"
|
|
||||||
cat ~/.ssh/id_ed25519.pub
|
|
||||||
echo
|
|
||||||
echo " 🔗 git.4nkweb.com :"
|
|
||||||
echo " 1. Connectez-vous à git.4nkweb.com"
|
|
||||||
echo " 2. Allez dans Settings > SSH Keys"
|
|
||||||
echo " 3. Ajoutez la clé ci-dessus"
|
|
||||||
echo
|
|
||||||
echo " 🔗 GitHub : Non nécessaire pour ce projet"
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "=== Fin du test ==="
|
|
Loading…
x
Reference in New Issue
Block a user