diff --git a/backend/accounts/tasks.py b/backend/accounts/tasks.py
index 15ed444..0c1475e 100644
--- a/backend/accounts/tasks.py
+++ b/backend/accounts/tasks.py
@@ -1,9 +1,9 @@
from celery import shared_task
from backend.core.models import Organization, Document, Risk, Control, DocumentRiskControl
-from backend.core.utils import get_top_risk, get_controls_for_risk
+from backend.core.utils import get_top_risk, get_controls_for_risk, generate_key_findings
from django.shortcuts import get_object_or_404, render
from .utils import send_payment_email
-
+from backend.core.tables import get_risk_table
@shared_task
def create_document_for_organization(confirmation_email):
@@ -53,5 +53,10 @@ def create_document_for_organization(confirmation_email):
document.add_segment('body', controls_content)
-
+ risks_by_weight = get_risk_table(document)[:3]
+ key_findings = generate_key_findings(document, risks_by_weight)
+ if key_findings:
+ document.key_findings = key_findings
+ document.save()
+
send_payment_email(confirmation_email)
\ No newline at end of file
diff --git a/backend/core/migrations/0017_document_key_findings.py b/backend/core/migrations/0017_document_key_findings.py
new file mode 100644
index 0000000..adfb209
--- /dev/null
+++ b/backend/core/migrations/0017_document_key_findings.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.1.3 on 2025-07-03 12:43
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('core', '0016_paymentcode'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='document',
+ name='key_findings',
+ field=models.TextField(blank=True, help_text='Key findings', null=True),
+ ),
+ ]
diff --git a/backend/core/models.py b/backend/core/models.py
index 09b1288..aa21de9 100644
--- a/backend/core/models.py
+++ b/backend/core/models.py
@@ -105,6 +105,7 @@ class Document(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name='documents')
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
+ key_findings = models.TextField(blank=True, null=True, help_text="Key findings")
def __str__(self):
return f"Document for {self.organization.name}"
diff --git a/backend/core/utils.py b/backend/core/utils.py
index 50e4fbe..445eb6b 100644
--- a/backend/core/utils.py
+++ b/backend/core/utils.py
@@ -211,6 +211,63 @@ def get_controls_for_risk(risk, organization):
break
return selected_controls if len(selected_controls) == 10 else []
+def generate_key_findings(document, top_10_risks):
+
+ client = OpenAI(api_key=settings.OPENAI_API_KEY)
+
+
+ def extract_organization_details(organization):
+ excluded_fields = {"email"}
+ risk_data = {}
+
+ for field in organization._meta.get_fields():
+ if field.name not in excluded_fields and hasattr(organization, field.name):
+ value = getattr(organization, field.name)
+ if value:
+ help_text = getattr(field, 'help_text', '').strip()
+ key = help_text if help_text else field.name
+ risk_data[key] = value
+ return risk_data
+
+ organization_details = extract_organization_details(document.organization)
+
+ prompt = f"""
+ You are an AI assistant tasked with generating a "Key Findings" section for a cybersecurity assessment report. Your output must be structured precisely, extracting and presenting the top 3 risks.
+
+ From the following list of risks, select the 3 most critical for the organization and generate the as specified.
+
+ List of risks:
+ {top_10_risks}
+ Organization details:
+ {organization_details}
+
+ Introduction: The description field must begin with the following exact text:
+ "The assessment revealed several areas where { document.organization.name } faces heightened cybersecurity risks. These risks pose significant threats to operational continuity, sensitive data, and regulatory compliance. The top risks identified are:"
+
+ Risk Presentation:
+ Identify the top 3 risks from the list above.
+ For each of these top 3 risks, present it as a bulleted item within the description field, following this format:
+ "- [Risk Name]: [Concise, professionally phrased description of the risk's significance in context of the organization, likelihood, or impact.]"
+
+ Description Derivation:
+ The [Risk Name] part should be the actual name of the risk from the input data (e.g., {{ item.risk.name }}).
+ The [Concise, professionally phrased description] part must be synthesized from the provided risk_description field (e.g., {{ item.risk_description }}) associated with that risk. Aim to create a polished, impactful summary that clearly explains the risk's context, severity, or contributing factors.
+
+ Return it as plain text in the following format:
+ Example Output Format:
+ Introduction
+ - Risk 1: Brief description of Risk 1
+ - Risk 2: Brief description of Risk 2
+ - Risk 3: Brief description of Risk 3
+ """
+
+ response = client.chat.completions.create(
+ model="gpt-4o-mini",
+ messages=[{"role": "system", "content": prompt}]
+ )
+ key_findings = response.choices[0].message.content.strip()
+ return key_findings
+
def generate_pdf(document):
document_link = f"{site_domain}/document/{document.id}/"
diff --git a/backend/settings.py b/backend/settings.py
index 883ed55..747bdb3 100644
--- a/backend/settings.py
+++ b/backend/settings.py
@@ -37,9 +37,7 @@ DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())
-SITE_DOMAIN = "https://risklet.com"
-#SITE_DOMAIN = "http://risklet.kompanijabroj4.com"
-#SITE_DOMAIN = "http://127.0.0.1:8000"
+SITE_DOMAIN = config('SITE_DOMAIN', default='localhost:8000')
# Application definition
@@ -169,9 +167,9 @@ CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'
-SECURE_SSL_REDIRECT = True
-SESSION_COOKIE_SECURE = True
-CSRF_COOKIE_SECURE = True
-SECURE_HSTS_SECONDS = 31536000
-SECURE_HSTS_INCLUDE_SUBDOMAINS = True
-SECURE_HSTS_PRELOAD = True
\ No newline at end of file
+SECURE_SSL_REDIRECT = config('SECURE_SSL_REDIRECT', default=False, cast=bool)
+SESSION_COOKIE_SECURE = config('SESSION_COOKIE_SECURE', default=False, cast=bool)
+CSRF_COOKIE_SECURE = config('CSRF_COOKIE_SECURE', default=False, cast=bool)
+SECURE_HSTS_SECONDS = config('SECURE_HSTS_SECONDS', default=0, cast=int)
+SECURE_HSTS_INCLUDE_SUBDOMAINS = config('SECURE_HSTS_INCLUDE_SUBDOMAINS', default=False, cast=bool)
+SECURE_HSTS_PRELOAD = config('SECURE_HSTS_PRELOAD', default=False, cast=bool)
\ No newline at end of file
diff --git a/document_template.yml b/document_template.yml
index 7ac8f94..42d3a81 100644
--- a/document_template.yml
+++ b/document_template.yml
@@ -17,12 +17,7 @@
content:
- title: "Key Findings"
description: |
- The assessment revealed several areas where {{ document.organization.name }} faces heightened cybersecurity risks. These risks pose significant threats to operational continuity, sensitive data, and regulatory compliance. The top risks identified are: - Phishing Attacks: High likelihood due to reliance on email communication and remote workforce operations.
- - Phishing Attacks: Assessed with a high likelihood, primarily attributed to the organization's reliance on email communication and the prevalence of remote workforce operations.
- - Ransomware Incidents: Evaluated as having an elevated impact, capable of threatening critical data assets and operational systems, potentially causing significant disruption.
- - Vendor Risks: Indicating increased exposure resulting from reliance on a substantial number ({{ document.organization.third_party_vendor_access }}) of third-party vendors without the presence of robust monitoring mechanisms.
- - Unpatched Software Vulnerabilities: (Identified as a contributing factor to risks like Ransomware Infection and addressed by recommended controls).
-
+ {{ document.key_findings }}
- segment_type: "recommendations"
content:
- title: "Recommendations"