File size: 11,008 Bytes
63b7afd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
import os
import json
import streamlit as st
# Configuration du mot de passe admin (à définir dans les secrets de l'application)
ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "default_admin_password")
def load_referentials_from_json():
"""
Charge les référentiels depuis les fichiers JSON dans le dossier referentiels/
"""
# Structure améliorée des référentiels (pour compatibilité)
referentials = {
"BRCGS": {
"Education_and_Experience": {
"requirements": [
"The auditor shall have a degree in a food-related, bioscience, or science and engineering discipline.",
"The auditor shall have a minimum of 5 years post-qualification experience related to the food industry.",
"This experience shall include roles such as quality assurance, food safety, technical management, or risk management functions within manufacturing, retailing, or inspection/enforcement."
]
},
"Qualifications": {
"Lead_Auditor": [
"The auditor shall have completed a recognized lead auditor qualification, including training on quality management systems with a minimum of 40 hours.",
"Examples of recognized courses include IRCA registered courses, ASQ Certified Quality Auditor, or BRCGS Lead Auditor courses."
],
"HACCP": [
"The auditor shall have completed a HACCP training course of at least 2 days (16 hours) based on Codex Alimentarius principles."
],
"Global_Standard_Food_Safety": [
"Auditors shall have successfully completed a Global Standard Food Safety (Issue 9) training course with corresponding examinations."
]
},
"Auditor_Training": {
"Training_Program": [
"Certification bodies must develop tailored training programs for each auditor depending on their background.",
"Training shall include product safety, HACCP, prerequisite programs, and relevant laws and regulations.",
"Assessment of knowledge and skills for each category is required before certification."
],
"Exceptions": [
"Certification bodies may employ auditors who do not fully meet the specified criteria, provided there is documented justification approved by BRCGS."
]
}
},
"FSSC_22000": {
"Initial_Training_and_Experience": {
"Work_Experience": [
"The auditor shall have at least 2 years full-time experience in the food or associated industry.",
"Consultancy experience may be recognized for up to 6 months, provided it is equivalent to work experience."
],
"Education": [
"A degree in a food-related or bioscience discipline, or completion of a higher education course in a related field."
],
"Training": [
"Successful completion of a Lead Auditor Course for FSMS or QMS (minimum 40 hours).",
"Completed HACCP training of at least 16 hours."
]
},
"Audits": {
"Audit_Requirements": [
"Auditors must have completed at least 10 audit days consisting of 5 third-party certification audits covering FSMS, HACCP, and PRP requirements.",
"At least 2 audits must be performed under supervision of an FSSC 22000 qualified auditor."
],
"Special_Categories": {
"Packaging": [
"Auditors specializing in packaging must have a primary qualification in packaging technology.",
"Training must cover topics like packaging legislation, standards, and safety control."
]
}
}
},
"IFS": {
"General_Requirements": {
"Education": [
"A food-related or bioscience degree (minimum Bachelor's degree or equivalent) or a successfully completed food-related professional higher education."
],
"Work_Experience": [
"A minimum of 3 years full-time professional experience in the food industry, including quality assurance, food safety, R&D, or food safety inspection/enforcement.",
"Consultancy experience may be recognized for up to 1 year, provided it is documented."
]
},
"Qualifications": {
"Lead_Auditor": [
"Completed a recognized Lead Auditor course (e.g., IFS, IRCA) with a duration of at least 40 hours.",
"Completed a Food Hygiene and HACCP course with a duration of at least 2 days/16 hours."
],
"Audit_Experience": [
"Performed a minimum of 7 food safety audits (GFSI recognized food safety certification audits and/or second party audits) in the past 5 years.",
"For candidates with no audit experience, participation in 7 audits is required, including 2 shadowing audits and 5 supervised audits."
]
},
"Advanced_Requirements": {
"Product_Scope": [
"One year of professional experience in the food industry in relation to food processing activities for each applied product scope.",
"At least 5 audits per scope, including GFSI recognized or second party audits."
],
"Technology_Scope": [
"One year of professional experience in the food industry for each applied technology scope.",
"At least 5 audits per scope, including GFSI recognized or second party audits."
],
"Language": [
"Proof of fluency in audit language via CEFR B2 certificate, 2 years work experience, or 10 audits conducted in that language."
]
}
}
}
referentials_dir = "referentiels"
if os.path.exists(referentials_dir):
for filename in os.listdir(referentials_dir):
if filename.endswith(".json") and filename != "template.json":
filepath = os.path.join(referentials_dir, filename)
try:
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
referential_name = data.get("metadata", {}).get("name", filename.replace(".json", ""))
referentials[referential_name] = data
except Exception as e:
print(f"Erreur lors du chargement de {filename}: {str(e)}")
return referentials
# Charger les référentiels
REFERENTIALS = load_referentials_from_json()
def create_referential_with_ai(exigences_text, groq_client):
"""
Utilise l'IA pour créer un référentiel à partir de texte brut
"""
prompt = f"""
Structure ces exigences de référentiel en JSON formaté avec pondérations et références :
TEXTES À STRUCTURER:
{exigences_text}
FORMAT DEMANDÉ:
{{
"metadata": {{
"name": "Nom à déterminer",
"version": "1.0",
"description": "Description du référentiel",
"last_updated": "2025-07-28",
"source": "Source des exigences"
}},
"categories": {{
"Category_Name": {{
"weight": 0.3,
"description": "Description de la catégorie",
"subcategories": {{
"Subcategory_Name": {{
"weight": 0.5,
"requirements": [
{{
"id": "REF-001",
"text": "Texte de l'exigence",
"critical": true,
"minimum_acceptable": "Critère minimum acceptable",
"references": ["Section du standard"]
}}
]
}}
}}
}}
}}
}}
CONSIGNES:
- Identifie les catégories principales et sous-catégories logiques
- Attribue des pondérations pertinentes (total = 1.0)
- Numérote les exigences de manière logique
- Propose un nom de référentiel pertinent
- Maintiens le sens exact des exigences
- Ajoute des références aux sections du standard si identifiables
"""
try:
response = groq_client.chat.completions.create(
messages=[
{"role": "system", "content": "Vous êtes un expert en structuration de référentiels de conformité."},
{"role": "user", "content": prompt}
],
model="llama-3.1-8b-instant",
max_tokens=4000,
temperature=0.1
)
# Extraire le JSON de la réponse
content = response.choices[0].message.content
# Trouver le JSON dans la réponse (entre ```json et ```)
import re
json_match = re.search(r'```json\s*(\{.*?\})\s*```', content, re.DOTALL)
if json_match:
return json.loads(json_match.group(1))
else:
# Essayer de parser directement si c'est du JSON pur
return json.loads(content)
except Exception as e:
st.error(f"Erreur lors de la génération du référentiel : {str(e)}")
return None
def save_referential_to_json(referential_data, filename):
"""
Sauvegarde un référentiel au format JSON
"""
try:
filepath = f"referentiels/{filename}.json"
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(referential_data, f, ensure_ascii=False, indent=2)
return True
except Exception as e:
st.error(f"Erreur lors de la sauvegarde : {str(e)}")
return False
def is_admin_authenticated(password):
"""
Vérifie si le mot de passe admin est correct
"""
return password == ADMIN_PASSWORD
# Template pour nouveaux référentiels
TEMPLATE_NOUVEAU_REFERENTIEL = {
"NOM_DU_REFERENTIEL": {
"General_Requirements": {
"requirements": [
"Exigence 1",
"Exigence 2"
]
},
"Qualifications": {
"required_certifications": [
"Certification 1",
"Certification 2"
]
},
"Audit_Experience": {
"minimum_experience": "Description de l'expérience requise"
}
}
}
|