key findings
This commit is contained in:
@@ -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)
|
||||
18
backend/core/migrations/0017_document_key_findings.py
Normal file
18
backend/core/migrations/0017_document_key_findings.py
Normal file
@@ -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),
|
||||
),
|
||||
]
|
||||
@@ -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}"
|
||||
|
||||
@@ -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}/"
|
||||
|
||||
@@ -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
|
||||
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)
|
||||
Reference in New Issue
Block a user