From 59741e323ecdcf841c93d1161c35a14f96e620ff Mon Sep 17 00:00:00 2001 From: Daniel Langio Date: Thu, 12 Feb 2026 11:56:21 +0300 Subject: [PATCH 1/5] chore(AnalyseurToiture): update category classification and comment --- .../birdia/genai/model/AnalyseurToiture.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java b/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java index 574c75f..2f3b1ae 100644 --- a/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java +++ b/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java @@ -145,16 +145,16 @@ private String getCategory(Toit toit) { var categoryFromConsumer = toit.category(); if (categoryFromConsumer == null || categoryFromConsumer.isEmpty()) { var globalRate = toit.noteDegradationGlobale(); - if (globalRate < 8) { + if (globalRate < 4) { return "A"; } - if (globalRate >= 8 && globalRate < 20) { + if (globalRate >= 4 && globalRate < 11) { return "B"; } - if (globalRate >= 20 && globalRate < 30) { + if (globalRate >= 11 && globalRate < 21) { return "C"; } - if (globalRate >= 30 && globalRate < 40) { + if (globalRate >= 21 && globalRate < 41) { return "D"; } return "E"; @@ -165,11 +165,11 @@ private String getCategory(Toit toit) { private String getEtatToiture(Toit toit) { var category = getCategory(toit); return switch (category) { - case "A" -> "Excellent état général"; - case "B" -> "Bon état avec légères réparations à prévoir"; - case "C" -> "État moyen, entretien recommandé rapidement"; - case "D" -> "Mauvais état, réparations importantes nécessaires"; - case "E" -> "Très mauvais état, rénovation complète recommandée"; + case "A" -> "Bon état, RAS"; + case "B" -> "Entretien à prévoir"; + case "C" -> "Entretien nécessaire"; + case "D" -> "Réparation nécessaire"; + case "E" -> "Intervention urgente"; default -> throw new IllegalStateException("Unexpected value: " + category); }; } From c8060b8442b03262c6cddd1c62b59b11efdc01fe Mon Sep 17 00:00:00 2001 From: "poja[bot]" Date: Tue, 17 Feb 2026 11:53:32 +0000 Subject: [PATCH 2/5] poja: deployment ID: acad6020-9738-4934-a781-8e466df066a0 --- .github/workflows/cd-compute.yml | 13 +++++++------ .github/workflows/ci.yml | 4 +++- build.gradle | 17 +++++++++-------- .../genai/handler/MailboxEventHandler.java | 1 - 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/.github/workflows/cd-compute.yml b/.github/workflows/cd-compute.yml index b1f4423..231da61 100644 --- a/.github/workflows/cd-compute.yml +++ b/.github/workflows/cd-compute.yml @@ -28,6 +28,7 @@ jobs: env: AWS_REGION: eu-west-3 + steps: - uses: actions/checkout@v4.1.6 @@ -46,7 +47,7 @@ jobs: fi response=$(curl --fail -X POST "https://api.prod.poja.io/gh-repos/${{ github.repository }}/github-workflow-state" \ - -H "Authorization: AppBearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg app_env_deployment_id "$app_env_deployment_id_value" \ @@ -79,10 +80,10 @@ jobs: run: | chmod +x ./gradlew chmod +x .shell/publish_gen_to_maven_local.sh - response=$(curl --fail -X GET "https://api.prod.poja.io/gh-repos/${{ github.repository }}/upload-build-uri?environment_type=$(echo "${{ github.ref_name }}" | tr '[:lower:]' '[:upper:]')" -H "Authorization: AppBearer ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/json") + response=$(curl -X GET "https://api.prod.poja.io/gh-repos/${{ github.repository }}/upload-build-uri?environment_type=$(echo "${{ github.ref_name }}" | tr '[:lower:]' '[:upper:]')" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/json") echo "upload_build_file_uri=$(echo $response | jq -r '.uri')" >> $GITHUB_ENV echo "to_upload_filename=$(echo $response | jq -r '.filename')" >> $GITHUB_ENV - curl --fail -X GET -o template.yml "$(echo $response | jq -r '.build_template_file_uri')" + curl -X GET -o template.yml "$(echo $response | jq -r '.build_template_file_uri')" - name: Build project run: sam build @@ -92,7 +93,7 @@ jobs: shopt -s globstar zip -r9 ${{ env.to_upload_filename }} .aws-sam shopt -u globstar - curl --fail -X PUT -H "Content-Type: application/zip" -H "x-amz-tagging: temporary=true" -T ${{ env.to_upload_filename }} "${{ env.upload_build_file_uri }}" + curl -X PUT -H "Content-Type: application/zip" -H "x-amz-tagging: temporary=true" -T ${{ env.to_upload_filename }} "${{ env.upload_build_file_uri }}" - name: Get current time uses: gerred/actions/current-time@master @@ -124,7 +125,7 @@ jobs: input_conf_id="null" fi response=$(curl --fail -X PUT "https://api.prod.poja.io/gh-repos/${{ github.repository }}/env-deploys?environment_type=$(echo "${{ github.ref_name }}" | tr '[:lower:]' '[:upper:]')" \ - -H "Authorization: AppBearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg env_depl_conf_id "$input_conf_id" \ @@ -174,7 +175,7 @@ jobs: fi response=$(curl --fail -X POST "https://api.prod.poja.io/gh-repos/${{ github.repository }}/github-workflow-state" \ - -H "Authorization: AppBearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg app_env_deployment_id "$app_env_deployment_id_value" \ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da930db..07ae15e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,7 @@ jobs: env: AWS_REGION: eu-west-3 + steps: - uses: actions/checkout@v4.1.6 @@ -30,7 +31,8 @@ jobs: distribution: 'corretto' - run: chmod +x gradlew - run: chmod +x .shell/publish_gen_to_maven_local.sh - - run: ./gradlew test + - run: | + ./gradlew test diff --git a/build.gradle b/build.gradle index 629b892..86e4b4f 100644 --- a/build.gradle +++ b/build.gradle @@ -108,9 +108,10 @@ jacocoTestReport { } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-web:3.2.2' + testImplementation 'org.testcontainers:testcontainers:2.0.2' - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.3' implementation 'com.amazonaws.serverless:aws-serverless-java-container-springboot3:2.1.0' implementation 'software.amazon.awssdk:aws-query-protocol:2.20.26' @@ -132,16 +133,16 @@ dependencies { implementation 'org.reflections:reflections:0.10.2' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - testCompileOnly 'org.projectlombok:lombok' - testAnnotationProcessor 'org.projectlombok:lombok' + compileOnly 'org.projectlombok:lombok:1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' + testCompileOnly 'org.projectlombok:lombok:1.18.30' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.30' implementation 'org.openapitools:jackson-databind-nullable:0.2.6' implementation 'io.swagger:swagger-annotations:1.6.12' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.testcontainers:junit-jupiter:1.19.1' + testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.2' + testImplementation 'org.testcontainers:testcontainers-junit-jupiter:2.0.2' testImplementation 'org.junit-pioneer:junit-pioneer:2.2.0' implementation 'dev.langchain4j:langchain4j-open-ai:1.1.0' diff --git a/src/main/java/fr/birdia/genai/handler/MailboxEventHandler.java b/src/main/java/fr/birdia/genai/handler/MailboxEventHandler.java index 72b5f9f..774839d 100644 --- a/src/main/java/fr/birdia/genai/handler/MailboxEventHandler.java +++ b/src/main/java/fr/birdia/genai/handler/MailboxEventHandler.java @@ -42,7 +42,6 @@ public String handleRequest(SQSEvent event, Context context) { log.info("SQS messages: {}", messages); var applicationContext = applicationContext(); - var eventConsumer = applicationContext.getBean(EventConsumer.class); var messageConverter = applicationContext.getBean(ConsumableEventTyper.class); From bb5ea56883faf1268de2d0461efa256634730bf6 Mon Sep 17 00:00:00 2001 From: Daniel Langio Date: Thu, 19 Feb 2026 13:46:55 +0300 Subject: [PATCH 3/5] chore(AnalyseurToiture): update llm prompt to 6 frebruary 2026 version --- .../rest/controller/RoofController.java | 10 +- .../birdia/genai/model/AnalyseurToiture.java | 91 ++++++++++++++----- src/main/java/fr/birdia/genai/model/Toit.java | 5 +- 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/main/java/fr/birdia/genai/endpoint/rest/controller/RoofController.java b/src/main/java/fr/birdia/genai/endpoint/rest/controller/RoofController.java index 92a933b..bb96381 100644 --- a/src/main/java/fr/birdia/genai/endpoint/rest/controller/RoofController.java +++ b/src/main/java/fr/birdia/genai/endpoint/rest/controller/RoofController.java @@ -34,7 +34,10 @@ public String hazavao( @RequestParam(required = false) Boolean fissureCassure, @RequestParam(required = false) Boolean risqueFeu, @RequestParam(required = false) Double noteDegradationGlobale, - @RequestParam(required = false) String categorie) { + @RequestParam(required = false) String categorie, + @RequestParam(required = false) String revetement2, + @RequestParam(required = false) Double hauteurBatiment, + @RequestParam(required = false) String commentaireCouvreur) { return analyseurToiture.apply( new Toit( @@ -55,6 +58,9 @@ public String hazavao( fissureCassure, risqueFeu, noteDegradationGlobale, - categorie)); + categorie, + revetement2, + hauteurBatiment, + commentaireCouvreur)); } } diff --git a/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java b/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java index 2f3b1ae..6c43e5c 100644 --- a/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java +++ b/src/main/java/fr/birdia/genai/model/AnalyseurToiture.java @@ -30,16 +30,33 @@ public String apply(Toit toit) { private String getAIReport(Toit toit) { var prompt = """ Tu es un artisan couvreur expérimenté, spécialiste des toitures depuis plus de 15 ans. + + Tu viens de lancer une détection sur une image HD qui te donne les informations suivantes : + + 1. Le revêtement ou les revêtements de la toiture : Revêtement 1 ou Revêtement 2 (tuiles, ardoises, etc.). + 2. Hauteur du bâtiment en mètres. + 3. Pente globale en degrés (°). + 4. Niveau d’usure : minime, partielle, avancée, extrême. + 5. Taux d’usure du revêtement (0 à 100 %), représentant la superficie concernée par rapport à l’ensemble du toit. + 6. Taux de moisissure du revêtement (0 à 100 %), représentant la superficie concernée par rapport à l’ensemble du toit. + 7. Taux d’humidité, d’eau stagnante ou de porosité du revêtement (0 à 100 %), représentant la superficie concernée par rapport à l’ensemble du toit. + 8. Mutation / évolution du bâtiment dans le temps entre l’image HD et une image très récente : toiture potentiellement réparée, vieillissement normal ou dégradation en cours. + 9. Présence d’obstacles (cheminée, Velux, panneaux solaires, etc.) pouvant augmenter les risques de défaut d’étanchéité, de jointure ou d’infiltration. + 10. Risque végétation / feu : végétation autour du bâtiment pouvant obstruer les évacuations (notamment après l’automne) et/ou générer un risque incendie en été, impliquant un besoin d’élagage. + 11. Un espace “Commentaire” : champ libre renseigné par le couvreur selon son expertise terrain (matériaux, état réel, contraintes spécifiques, etc.). + + ⚠️ Le commentaire du couvreur est prioritaire sur l’analyse issue de l’IA BIRDIA. Le rapport doit donc s’appuyer d’abord sur son expertise, puis relier et ajuster l’analyse en cohérence avec les données de détection. + Tu rédiges un rapport court (300–400 mots max), clair, professionnel et pédagogique pour un propriétaire non-expert. Ton objectif est double : 1. Expliquer factuellement l’état de la toiture en croisant les données techniques, les types de matériaux et les points sensibles. - 2. Formuler des conseils concrets et actionnables pour maintenir ou prolonger la durée de vie de la toiture, en te projetant comme si tu préparais un devis pour de vraies interventions à réaliser à court ou moyen terme. + 2. Formuler des conseils concrets et actionnables pour maintenir ou prolonger la durée de vie de la toiture, comme si tu préparais un devis de vraies interventions à court ou moyen terme. 🛑 Interdictions : - • Ne fais aucun disclaimer juridique. - • Ne dépasse jamais 400 mots. - • Ne parle jamais d’argent. - • Ne répète pas les données brutes : interprète-les. + • Ne fais aucun disclaimer juridique sauf si le couvreur te le demande dans le commentaire + • Ne dépasse jamais 400 mots. + • Ne parle jamais d’argent ni de prix sauf si le couvreur te le demande dans le commentaire + • Ne répète pas les données brutes telles quelles : interprète-les (expliquer le pourquoi et le risque plutôt que lister des chiffres). ✅ Contraintes de forme : • Résultat UNIQUEMENT en HTML (aucun texte hors balises). @@ -47,6 +64,10 @@ private String getAIReport(Toit toit) { • Utilise la police suivante en priorité : Kumbh Sans • Respecte strictement la structure suivante, de telle sorte que les blocs INSTRUCTION soient remplacés par l’instruction donnée: + 👉 Le commentaire du couvreur est prioritaire : en cas de contradiction entre la détection + automatique et son commentaire, tu suis le commentaire et tu t’en sers pour + interpréter/nuancer les données de BIRDIA +