Merge branch 'dev' into copilot/add-webhook-system-ai-events

Resolved merge conflicts in:
- src/documents/ai_deletion_manager.py: Kept webhook integration alongside dev changes
- src/documents/ai_scanner.py: Kept webhook integration and applied_fields tracking
- src/documents/models.py: Integrated AISuggestionFeedback model with webhook imports

All conflicts resolved maintaining both webhook functionality and new AI suggestions features from dev branch.

Co-authored-by: dawnsystem <42047891+dawnsystem@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-11-14 15:26:54 +00:00
parent ebc906b713
commit 5ae18e03b5
24 changed files with 5421 additions and 299 deletions

View file

@ -0,0 +1,26 @@
# Generated migration for adding AI-related custom permissions
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("documents", "1072_workflowtrigger_filter_custom_field_query_and_more"),
]
operations = [
migrations.AlterModelOptions(
name="document",
options={
"ordering": ("-created",),
"permissions": [
("can_view_ai_suggestions", "Can view AI suggestions"),
("can_apply_ai_suggestions", "Can apply AI suggestions"),
("can_approve_deletions", "Can approve AI-recommended deletions"),
("can_configure_ai", "Can configure AI settings"),
],
"verbose_name": "document",
"verbose_name_plural": "documents",
},
),
]

View file

@ -0,0 +1,148 @@
# Generated manually for DeletionRequest model
# Based on model definition in documents/models.py
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
"""
Add DeletionRequest model for AI-initiated deletion requests.
This model tracks deletion requests that require user approval,
implementing the safety requirement from agents.md to ensure
no documents are deleted without explicit user consent.
"""
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("documents", "1075_add_performance_indexes"),
]
operations = [
migrations.CreateModel(
name="DeletionRequest",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
models.DateTimeField(auto_now_add=True),
),
(
"updated_at",
models.DateTimeField(auto_now=True),
),
(
"requested_by_ai",
models.BooleanField(default=True),
),
(
"ai_reason",
models.TextField(
help_text="Detailed explanation from AI about why deletion is recommended"
),
),
(
"status",
models.CharField(
choices=[
("pending", "Pending"),
("approved", "Approved"),
("rejected", "Rejected"),
("cancelled", "Cancelled"),
("completed", "Completed"),
],
default="pending",
max_length=20,
),
),
(
"impact_summary",
models.JSONField(
default=dict,
help_text="Summary of what will be affected by this deletion",
),
),
(
"reviewed_at",
models.DateTimeField(blank=True, null=True),
),
(
"review_comment",
models.TextField(
blank=True,
help_text="User's comment when reviewing",
),
),
(
"completed_at",
models.DateTimeField(blank=True, null=True),
),
(
"completion_details",
models.JSONField(
default=dict,
help_text="Details about the deletion execution",
),
),
(
"documents",
models.ManyToManyField(
help_text="Documents that would be deleted if approved",
related_name="deletion_requests",
to="documents.document",
),
),
(
"reviewed_by",
models.ForeignKey(
blank=True,
help_text="User who reviewed and approved/rejected",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="reviewed_deletion_requests",
to=settings.AUTH_USER_MODEL,
),
),
(
"user",
models.ForeignKey(
help_text="User who must approve this deletion",
on_delete=django.db.models.deletion.CASCADE,
related_name="deletion_requests",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"verbose_name": "deletion request",
"verbose_name_plural": "deletion requests",
"ordering": ["-created_at"],
},
),
# Add composite index for status + user (common query pattern)
migrations.AddIndex(
model_name="deletionrequest",
index=models.Index(
fields=["status", "user"],
name="del_req_status_user_idx",
),
),
# Add index for created_at (for chronological queries)
migrations.AddIndex(
model_name="deletionrequest",
index=models.Index(
fields=["created_at"],
name="del_req_created_idx",
),
),
]

View file

@ -0,0 +1,55 @@
# Generated manually for DeletionRequest performance optimization
from django.db import migrations, models
class Migration(migrations.Migration):
"""
Add performance indexes for DeletionRequest model.
These indexes optimize common query patterns:
- Filtering by user + status + created_at (most common listing query)
- Filtering by reviewed_at (for finding reviewed requests)
- Filtering by completed_at (for finding completed requests)
Expected performance improvement:
- List queries: <100ms
- Filter queries: <50ms
Addresses Issue: [AI Scanner] Índices de Performance para DeletionRequest
Epic: Migraciones de Base de Datos
"""
dependencies = [
("documents", "1075_add_performance_indexes"),
]
operations = [
# Composite index for user + status + created_at (most common query pattern)
# This supports queries like: DeletionRequest.objects.filter(user=user, status='pending').order_by('-created_at')
migrations.AddIndex(
model_name="deletionrequest",
index=models.Index(
fields=["user", "status", "created_at"],
name="delreq_user_status_created_idx",
),
),
# Index for reviewed_at (for filtering reviewed requests)
# Supports queries like: DeletionRequest.objects.filter(reviewed_at__isnull=False)
migrations.AddIndex(
model_name="deletionrequest",
index=models.Index(
fields=["reviewed_at"],
name="delreq_reviewed_at_idx",
),
),
# Index for completed_at (for filtering completed requests)
# Supports queries like: DeletionRequest.objects.filter(completed_at__isnull=False)
migrations.AddIndex(
model_name="deletionrequest",
index=models.Index(
fields=["completed_at"],
name="delreq_completed_at_idx",
),
),
]

View file

@ -0,0 +1,164 @@
# Generated manually for AI Suggestions API
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.core.validators
class Migration(migrations.Migration):
"""
Add AISuggestionFeedback model for tracking user feedback on AI suggestions.
This model enables:
- Tracking of applied vs rejected AI suggestions
- Accuracy statistics and improvement of AI models
- User feedback analysis
"""
dependencies = [
("documents", "1075_add_performance_indexes"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="AISuggestionFeedback",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"suggestion_type",
models.CharField(
choices=[
("tag", "Tag"),
("correspondent", "Correspondent"),
("document_type", "Document Type"),
("storage_path", "Storage Path"),
("custom_field", "Custom Field"),
("workflow", "Workflow"),
("title", "Title"),
],
max_length=50,
verbose_name="suggestion type",
),
),
(
"suggested_value_id",
models.IntegerField(
blank=True,
help_text="ID of the suggested object (tag, correspondent, etc.)",
null=True,
verbose_name="suggested value ID",
),
),
(
"suggested_value_text",
models.TextField(
blank=True,
help_text="Text representation of the suggested value",
verbose_name="suggested value text",
),
),
(
"confidence",
models.FloatField(
help_text="AI confidence score (0.0 to 1.0)",
validators=[
django.core.validators.MinValueValidator(0.0),
django.core.validators.MaxValueValidator(1.0),
],
verbose_name="confidence",
),
),
(
"status",
models.CharField(
choices=[
("applied", "Applied"),
("rejected", "Rejected"),
],
max_length=20,
verbose_name="status",
),
),
(
"created_at",
models.DateTimeField(
auto_now_add=True,
verbose_name="created at",
),
),
(
"applied_at",
models.DateTimeField(
auto_now=True,
verbose_name="applied/rejected at",
),
),
(
"metadata",
models.JSONField(
blank=True,
default=dict,
help_text="Additional metadata about the suggestion",
verbose_name="metadata",
),
),
(
"document",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="ai_suggestion_feedbacks",
to="documents.document",
verbose_name="document",
),
),
(
"user",
models.ForeignKey(
blank=True,
help_text="User who applied or rejected the suggestion",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="ai_suggestion_feedbacks",
to=settings.AUTH_USER_MODEL,
verbose_name="user",
),
),
],
options={
"verbose_name": "AI suggestion feedback",
"verbose_name_plural": "AI suggestion feedbacks",
"ordering": ["-created_at"],
},
),
migrations.AddIndex(
model_name="aisuggestionfeedback",
index=models.Index(
fields=["document", "suggestion_type"],
name="documents_a_documen_idx",
),
),
migrations.AddIndex(
model_name="aisuggestionfeedback",
index=models.Index(
fields=["status", "created_at"],
name="documents_a_status_idx",
),
),
migrations.AddIndex(
model_name="aisuggestionfeedback",
index=models.Index(
fields=["suggestion_type", "status"],
name="documents_a_suggest_idx",
),
),
]