HH/apps/feedback/admin.py
ismail 7369d08012
All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
feat: unified reference numbers + feedback modules QA audit
Reference numbers (unified scheme PREFIX-YYYYMM-HOSP-NNNN, e.g. CMP-202606-HHN-0001):
- new ReferenceSequence model + generate_reference() helper (apps/core)
- Complaint/Inquiry/Observation/Appreciation/Suggestion emit unified refs via save()
- prefix-based auto-routing in public track API (CMP/INQ/OBS trackable; APR/SGT internal-only)
- removed legacy CMP-/INQ- generators in ui_views, integrations, px_sources
- migrations: core.0003_referencesequence, appreciation.0006, feedback.0008, observations.0012
- unit tests (format, sanitization, monthly reset, 40-thread concurrency)

QA audit:
- isolated E2E hospital sandbox mirroring HH-N + 10 role users (create_e2e_isolated_env)
- feedback-modules-audit.spec.ts + audit helper (headed, run-to-completion)
- reports/feedback-modules-qa-report.md

Also bundles accumulated in-progress work across complaints, observations,
organizations, templates, and other modules.
2026-06-14 14:29:23 +03:00

211 lines
6.5 KiB
Python

"""
Feedback admin configuration
"""
from django.contrib import admin
from .models import (
Feedback,
FeedbackAttachment,
FeedbackResponse,
CommentImport,
PatientComment,
CommentActionPlan,
)
@admin.register(Feedback)
class FeedbackAdmin(admin.ModelAdmin):
"""Admin interface for Feedback model"""
list_display = [
"id",
"feedback_type",
"title",
"get_contact_name",
"hospital",
"status",
"sentiment",
"rating",
"is_featured",
"created_at",
]
list_filter = [
"feedback_type",
"status",
"sentiment",
"category",
"priority",
"is_featured",
"is_deleted",
"created_at",
]
search_fields = [
"title",
"message",
"patient__first_name",
"patient__last_name",
"patient__mrn",
"contact_name",
"contact_email",
]
readonly_fields = [
"id",
"created_at",
"updated_at",
"assigned_at",
"reviewed_at",
"acknowledged_at",
"closed_at",
"deleted_at",
]
fieldsets = (
(
"Basic Information",
{"fields": ("id", "feedback_type", "title", "message", "category", "subcategory", "rating", "priority")},
),
("Patient/Contact", {"fields": ("patient", "is_anonymous", "contact_name", "contact_email", "contact_phone")}),
(
"Organization",
{
"fields": (
"hospital",
"department",
"legacy_location",
"legacy_main_section",
"legacy_subsection",
"section",
"staff",
"encounter_id",
)
},
),
(
"Status & Workflow",
{
"fields": (
"status",
"assigned_to",
"assigned_at",
"reviewed_by",
"reviewed_at",
"acknowledged_by",
"acknowledged_at",
"closed_by",
"closed_at",
)
},
),
("Sentiment Analysis", {"fields": ("sentiment", "sentiment_score")}),
(
"Flags",
{"fields": ("is_featured", "is_public", "requires_follow_up", "is_deleted", "deleted_at", "deleted_by")},
),
("Metadata", {"fields": ("source", "metadata", "created_at", "updated_at"), "classes": ("collapse",)}),
)
date_hierarchy = "created_at"
ordering = ["-created_at"]
@admin.register(FeedbackAttachment)
class FeedbackAttachmentAdmin(admin.ModelAdmin):
"""Admin interface for FeedbackAttachment model"""
list_display = ["id", "feedback", "filename", "file_type", "file_size", "uploaded_by", "created_at"]
list_filter = ["file_type", "created_at"]
search_fields = ["filename", "feedback__title"]
readonly_fields = ["id", "created_at", "updated_at"]
date_hierarchy = "created_at"
ordering = ["-created_at"]
@admin.register(CommentImport)
class CommentImportAdmin(admin.ModelAdmin):
list_display = ["hospital", "year", "month", "status", "total_rows", "imported_count", "imported_by", "created_at"]
list_filter = ["status", "year", "month", "hospital"]
date_hierarchy = "created_at"
raw_id_fields = ["hospital", "imported_by"]
@admin.register(PatientComment)
class PatientCommentAdmin(admin.ModelAdmin):
list_display = [
"serial_number",
"hospital",
"source_category",
"classification",
"sub_category",
"sentiment",
"is_classified",
"year",
"month",
]
list_filter = [
"hospital",
"source_category",
"classification",
"sub_category",
"sentiment",
"is_classified",
"year",
"month",
]
search_fields = ["comment_text", "comment_text_en", "negative_keywords", "positive_keywords"]
date_hierarchy = "created_at"
raw_id_fields = ["hospital", "comment_import"]
fieldsets = (
(None, {"fields": ("hospital", "comment_import", "serial_number", "source_category", "year", "month")}),
("Comment Text", {"fields": ("comment_text", "comment_text_en")}),
("Classification (Step 1)", {"fields": ("classification", "sub_category", "is_classified", "sentiment")}),
(
"Sentiment Keywords",
{"fields": ("negative_keywords", "positive_keywords", "gratitude_keywords", "suggestions")},
),
("Doctor Reference", {"fields": ("mentioned_doctor_name", "mentioned_doctor_name_en", "frequency")}),
("Metadata", {"fields": ("metadata",), "classes": ("collapse",)}),
)
@admin.register(CommentActionPlan)
class CommentActionPlanAdmin(admin.ModelAdmin):
list_display = [
"department_label",
"problem_number",
"status",
"frequency",
"timeframe",
"year",
"month",
]
list_filter = ["status", "hospital", "department", "year", "month"]
search_fields = ["recommendation", "comment_text", "department_label", "responsible_department"]
date_hierarchy = "created_at"
raw_id_fields = ["hospital", "department", "comment"]
fieldsets = (
(None, {"fields": ("hospital", "department", "department_label", "problem_number", "year", "month")}),
("Source Comment", {"fields": ("comment", "comment_text", "comment_text_en", "frequency")}),
("Action Plan", {"fields": ("recommendation", "recommendation_en", "responsible_department")}),
("Tracking (Step 5)", {"fields": ("status", "timeframe", "evidences")}),
)
@admin.register(FeedbackResponse)
class FeedbackResponseAdmin(admin.ModelAdmin):
"""Admin interface for FeedbackResponse model"""
list_display = ["id", "feedback", "response_type", "created_by", "is_internal", "created_at"]
list_filter = ["response_type", "is_internal", "created_at"]
search_fields = ["message", "feedback__title"]
readonly_fields = ["id", "created_at", "updated_at"]
fieldsets = (
(
"Response Information",
{"fields": ("id", "feedback", "response_type", "message", "created_by", "is_internal")},
),
("Status Change", {"fields": ("old_status", "new_status")}),
("Metadata", {"fields": ("metadata", "created_at", "updated_at"), "classes": ("collapse",)}),
)
date_hierarchy = "created_at"
ordering = ["-created_at"]