288 lines
8.4 KiB
Markdown
288 lines
8.4 KiB
Markdown
# Clinical Document Signing Implementation Plan
|
|
|
|
## Overview
|
|
This document outlines the implementation of clinical document signing functionality across all therapy modules that use `ClinicallySignableMixin`.
|
|
|
|
## Completed Implementation
|
|
|
|
### ✅ ABA Module
|
|
- **Models**: ABAConsult, ABASession
|
|
- **Views**: Added `ABASessionSignView` for signing sessions
|
|
- **URLs**: Added `/sessions/<uuid:pk>/sign/` route
|
|
- **Templates**:
|
|
- `session_detail.html`: Sign button for unsigned sessions
|
|
- `session_list.html`: Unsigned sessions notification banner + signature status column
|
|
- **Features**:
|
|
- Role-based access (provider or admin only)
|
|
- Confirmation dialog before signing
|
|
- Audit trail (signed_by, signed_at)
|
|
- Visual indicators (badges, alerts)
|
|
|
|
## Pending Implementation
|
|
|
|
### 1. OT (Occupational Therapy) Module
|
|
|
|
#### Models to Implement
|
|
- **OTConsult** - Consultation forms
|
|
- **OTSession** - Session notes
|
|
- **OTProgressReport** - Progress reports
|
|
|
|
#### Required Changes
|
|
|
|
**Views** (`ot/views.py`):
|
|
```python
|
|
# Add sign views for each model
|
|
class OTConsultSignView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
allowed_roles = [User.Role.ADMIN, User.Role.OT]
|
|
# Similar implementation to ABASessionSignView
|
|
|
|
class OTSessionSignView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
allowed_roles = [User.Role.ADMIN, User.Role.OT]
|
|
|
|
class OTProgressReportSignView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
allowed_roles = [User.Role.ADMIN, User.Role.OT]
|
|
```
|
|
|
|
**URLs** (`ot/urls.py`):
|
|
```python
|
|
# Add sign routes
|
|
path('consults/<uuid:pk>/sign/', views.OTConsultSignView.as_view(), name='consult_sign'),
|
|
path('sessions/<uuid:pk>/sign/', views.OTSessionSignView.as_view(), name='session_sign'),
|
|
path('progress-reports/<uuid:pk>/sign/', views.OTProgressReportSignView.as_view(), name='progress_report_sign'),
|
|
```
|
|
|
|
**Templates**:
|
|
- `ot/templates/ot/consult_detail.html` - Add signature status card with sign button
|
|
- `ot/templates/ot/consult_list.html` - Add unsigned notifications + signature column
|
|
- `ot/templates/ot/session_detail.html` - Add signature status card with sign button
|
|
- `ot/templates/ot/session_list.html` - Add unsigned notifications + signature column
|
|
- `ot/templates/ot/progress_report_detail.html` - Add signature status card with sign button
|
|
- `ot/templates/ot/progress_report_list.html` - Add unsigned notifications + signature column
|
|
|
|
**List Views** - Update `get_context_data()`:
|
|
```python
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
user = self.request.user
|
|
|
|
# Get unsigned documents for current user
|
|
unsigned_query = ModelName.objects.filter(
|
|
tenant=user.tenant,
|
|
signed_by__isnull=True
|
|
)
|
|
|
|
if user.role == User.Role.OT:
|
|
unsigned_query = unsigned_query.filter(provider=user)
|
|
|
|
context['unsigned_count'] = unsigned_query.count()
|
|
context['unsigned_items'] = unsigned_query.select_related('patient', 'provider').order_by('-date_field')[:10]
|
|
|
|
return context
|
|
```
|
|
|
|
### 2. SLP (Speech-Language Pathology) Module
|
|
|
|
#### Models to Implement
|
|
- **SLPConsult** - Consultation forms
|
|
- **SLPAssessment** - Assessment reports
|
|
- **SLPIntervention** - Intervention notes
|
|
- **SLPProgressReport** - Progress reports
|
|
|
|
#### Required Changes
|
|
Same pattern as OT module:
|
|
- Add 4 sign views (one per model)
|
|
- Add 4 URL routes
|
|
- Update 8 templates (4 detail + 4 list)
|
|
- Update 4 list views with unsigned counts
|
|
|
|
**Views** (`slp/views.py`):
|
|
```python
|
|
class SLPConsultSignView(...)
|
|
class SLPAssessmentSignView(...)
|
|
class SLPInterventionSignView(...)
|
|
class SLPProgressReportSignView(...)
|
|
```
|
|
|
|
**URLs** (`slp/urls.py`):
|
|
```python
|
|
path('consults/<uuid:pk>/sign/', ...),
|
|
path('assessments/<uuid:pk>/sign/', ...),
|
|
path('interventions/<uuid:pk>/sign/', ...),
|
|
path('progress-reports/<uuid:pk>/sign/', ...),
|
|
```
|
|
|
|
### 3. Medical Module
|
|
|
|
#### Models to Implement
|
|
- **MedicalConsultation** - Medical consultations
|
|
- **MedicalFollowUp** - Follow-up visits
|
|
|
|
#### Required Changes
|
|
Same pattern:
|
|
- Add 2 sign views
|
|
- Add 2 URL routes
|
|
- Update 4 templates (2 detail + 2 list)
|
|
- Update 2 list views
|
|
|
|
**Views** (`medical/views.py`):
|
|
```python
|
|
class MedicalConsultationSignView(...)
|
|
class MedicalFollowUpSignView(...)
|
|
```
|
|
|
|
**URLs** (`medical/urls.py`):
|
|
```python
|
|
path('consultations/<uuid:pk>/sign/', ...),
|
|
path('follow-ups/<uuid:pk>/sign/', ...),
|
|
```
|
|
|
|
### 4. Nursing Module
|
|
|
|
#### Models to Implement
|
|
- **NursingEncounter** - Nursing encounters
|
|
|
|
#### Required Changes
|
|
- Add 1 sign view
|
|
- Add 1 URL route
|
|
- Update 2 templates (1 detail + 1 list)
|
|
- Update 1 list view
|
|
|
|
**Views** (`nursing/views.py`):
|
|
```python
|
|
class NursingEncounterSignView(...)
|
|
```
|
|
|
|
**URLs** (`nursing/urls.py`):
|
|
```python
|
|
path('encounters/<uuid:pk>/sign/', ...),
|
|
```
|
|
|
|
## Implementation Checklist
|
|
|
|
### Per Model Implementation Steps:
|
|
- [ ] Create sign view class in views.py
|
|
- [ ] Add URL route in urls.py
|
|
- [ ] Update detail template with signature status card
|
|
- [ ] Update list template with unsigned notification banner
|
|
- [ ] Add signature status column to list table
|
|
- [ ] Update list view to include unsigned counts
|
|
- [ ] Test signing functionality
|
|
- [ ] Test role-based access control
|
|
- [ ] Verify audit trail (signed_by, signed_at)
|
|
|
|
### OT Module
|
|
- [ ] OTConsult signing (3 steps above)
|
|
- [ ] OTSession signing (3 steps above)
|
|
- [ ] OTProgressReport signing (3 steps above)
|
|
|
|
### SLP Module
|
|
- [ ] SLPConsult signing
|
|
- [ ] SLPAssessment signing
|
|
- [ ] SLPIntervention signing
|
|
- [ ] SLPProgressReport signing
|
|
|
|
### Medical Module
|
|
- [ ] MedicalConsultation signing
|
|
- [ ] MedicalFollowUp signing
|
|
|
|
### Nursing Module
|
|
- [ ] NursingEncounter signing
|
|
|
|
## Code Reusability
|
|
|
|
### Generic Sign View Template
|
|
Consider creating a generic mixin or base class to reduce code duplication:
|
|
|
|
```python
|
|
# core/mixins.py
|
|
class ClinicalDocumentSignMixin:
|
|
"""Mixin for signing clinical documents."""
|
|
|
|
def post(self, request, pk):
|
|
model = self.model
|
|
document = get_object_or_404(
|
|
model,
|
|
pk=pk,
|
|
tenant=request.user.tenant
|
|
)
|
|
|
|
# Check if already signed
|
|
if document.signed_by:
|
|
messages.warning(request, "This document has already been signed.")
|
|
return HttpResponseRedirect(self.get_success_url(pk))
|
|
|
|
# Check if user is the provider or admin
|
|
if document.provider != request.user and request.user.role != User.Role.ADMIN:
|
|
messages.error(request, "Only the provider or an administrator can sign this document.")
|
|
return HttpResponseRedirect(self.get_success_url(pk))
|
|
|
|
# Sign the document
|
|
document.signed_by = request.user
|
|
document.signed_at = timezone.now()
|
|
document.save()
|
|
|
|
messages.success(request, f"{model._meta.verbose_name} signed successfully!")
|
|
return HttpResponseRedirect(self.get_success_url(pk))
|
|
|
|
def get_success_url(self, pk):
|
|
raise NotImplementedError("Subclasses must implement get_success_url()")
|
|
```
|
|
|
|
### Template Includes
|
|
Create reusable template snippets:
|
|
|
|
**`templates/includes/signature_status_card.html`**:
|
|
```django
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="fas fa-signature me-2"></i>{% trans "Signature Status" %}</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if document.signed_by %}
|
|
<!-- Signed content -->
|
|
{% else %}
|
|
<!-- Unsigned content with sign button -->
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
**`templates/includes/unsigned_notification.html`**:
|
|
```django
|
|
{% if unsigned_count > 0 %}
|
|
<div class="alert alert-warning alert-dismissible fade show mb-3" role="alert">
|
|
<!-- Notification content -->
|
|
</div>
|
|
{% endif %}
|
|
```
|
|
|
|
## Testing Requirements
|
|
|
|
For each implementation:
|
|
1. Test signing as provider
|
|
2. Test signing as admin
|
|
3. Test access denial for other users
|
|
4. Test re-signing prevention
|
|
5. Test unsigned notifications display
|
|
6. Test signature status indicators
|
|
7. Verify audit trail records
|
|
|
|
## Priority Order
|
|
|
|
1. **High Priority**: OT and SLP modules (most frequently used)
|
|
2. **Medium Priority**: Medical module
|
|
3. **Low Priority**: Nursing module
|
|
|
|
## Estimated Effort
|
|
|
|
- Per model: ~30-45 minutes
|
|
- Total: ~6-8 hours for all modules
|
|
|
|
## Notes
|
|
|
|
- All implementations should follow the ABA module pattern
|
|
- Maintain consistency in UI/UX across all modules
|
|
- Ensure proper role-based access control
|
|
- Include proper error handling and user feedback
|
|
- Add appropriate translations for all user-facing text
|