autocomit
This commit is contained in:
@@ -0,0 +1,586 @@
|
|||||||
|
# Story 10: Service Level Agreement (SLA) Management
|
||||||
|
|
||||||
|
## Story Overview
|
||||||
|
|
||||||
|
**As a** service delivery manager
|
||||||
|
**I want** to define and track Service Level Agreements for applications
|
||||||
|
**So that** I can document expected service levels, maintenance windows, and responsibilities
|
||||||
|
|
||||||
|
**Story Type**: Feature (Service Management)
|
||||||
|
**Priority**: Medium
|
||||||
|
**Estimated Effort**: 6-8 days
|
||||||
|
**Dependencies**: Story 2 (Applications), Story 3 (Contacts)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Business Value
|
||||||
|
|
||||||
|
SLAs define the expected service levels, maintenance windows, and responsibilities for applications. This enables:
|
||||||
|
- Clear service level expectations
|
||||||
|
- Maintenance window planning
|
||||||
|
- Critical period identification
|
||||||
|
- Responsibility mapping
|
||||||
|
- Service delivery tracking
|
||||||
|
- Foundation for incident management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### In Scope
|
||||||
|
✅ SLA CRUD operations
|
||||||
|
✅ SLA-Application association (one-to-one)
|
||||||
|
✅ Core SLA metrics (availability, response time, reaction time)
|
||||||
|
✅ Maintenance window management
|
||||||
|
✅ Critical period tracking
|
||||||
|
✅ SLA-Contact associations (responsible parties)
|
||||||
|
✅ Diagram storage (draw.io JSON format)
|
||||||
|
✅ Dependencies documentation
|
||||||
|
|
||||||
|
### Out of Scope
|
||||||
|
❌ Automated SLA monitoring/compliance
|
||||||
|
❌ Incident management integration
|
||||||
|
❌ Automated alerts for SLA breaches
|
||||||
|
❌ Real-time availability tracking
|
||||||
|
❌ Historical compliance reporting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- SLA entity
|
||||||
|
CREATE TABLE sla (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
application_id UUID UNIQUE REFERENCES application(id) ON DELETE CASCADE,
|
||||||
|
availability_percentage DECIMAL(5,2) NOT NULL, -- e.g., 99.90
|
||||||
|
min_avg_response_time_seconds INTEGER NOT NULL,
|
||||||
|
reaction_time VARCHAR(255) NOT NULL, -- Free text, e.g., "Within 4 hours for P1 incidents"
|
||||||
|
diagram_json JSONB, -- draw.io diagram in JSON format
|
||||||
|
dependencies_description TEXT,
|
||||||
|
responsibility_scope TEXT,
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
updated_at TIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT check_availability CHECK (availability_percentage >= 0 AND availability_percentage <= 100),
|
||||||
|
CONSTRAINT check_response_time CHECK (min_avg_response_time_seconds > 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Maintenance Windows
|
||||||
|
CREATE TABLE maintenance_window (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
sla_id UUID NOT NULL REFERENCES sla(id) ON DELETE CASCADE,
|
||||||
|
day_of_week VARCHAR(10) NOT NULL, -- MONDAY, TUESDAY, etc.
|
||||||
|
start_time TIME NOT NULL, -- e.g., 02:00
|
||||||
|
end_time TIME NOT NULL, -- e.g., 06:00
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT check_time_order CHECK (end_time > start_time),
|
||||||
|
CONSTRAINT check_day_of_week CHECK (day_of_week IN ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'))
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Critical Periods
|
||||||
|
CREATE TABLE critical_period (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
sla_id UUID NOT NULL REFERENCES sla(id) ON DELETE CASCADE,
|
||||||
|
start_datetime TIMESTAMP NOT NULL,
|
||||||
|
end_datetime TIMESTAMP NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT check_period_order CHECK (end_datetime > start_datetime)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Computed column for duration in minutes
|
||||||
|
ALTER TABLE critical_period ADD COLUMN duration_minutes INTEGER GENERATED ALWAYS AS
|
||||||
|
(EXTRACT(EPOCH FROM (end_datetime - start_datetime)) / 60) STORED;
|
||||||
|
|
||||||
|
-- SLA-Contact junction (many-to-many)
|
||||||
|
CREATE TABLE sla_contact (
|
||||||
|
sla_id UUID NOT NULL REFERENCES sla(id) ON DELETE CASCADE,
|
||||||
|
contact_id UUID NOT NULL REFERENCES contact(id) ON DELETE CASCADE,
|
||||||
|
PRIMARY KEY (sla_id, contact_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_sla_application ON sla(application_id);
|
||||||
|
CREATE INDEX idx_maint_window_sla ON maintenance_window(sla_id);
|
||||||
|
CREATE INDEX idx_maint_window_day ON maintenance_window(day_of_week);
|
||||||
|
CREATE INDEX idx_critical_period_sla ON critical_period(sla_id);
|
||||||
|
CREATE INDEX idx_critical_period_dates ON critical_period(start_datetime, end_datetime);
|
||||||
|
CREATE INDEX idx_sla_contact_sla ON sla_contact(sla_id);
|
||||||
|
CREATE INDEX idx_sla_contact_contact ON sla_contact(contact_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Business Logic
|
||||||
|
|
||||||
|
### SLA-Application Relationship
|
||||||
|
- Each application can have at most ONE SLA (one-to-one)
|
||||||
|
- SLA is optional (not all applications require formal SLAs)
|
||||||
|
- When creating SLA, validate application doesn't already have one
|
||||||
|
- When deleting SLA, application is not affected (cascade delete from SLA side)
|
||||||
|
|
||||||
|
### Maintenance Windows
|
||||||
|
- Represent recurring weekly maintenance periods
|
||||||
|
- Each window defines: day of week, start time, end time
|
||||||
|
- Multiple windows can be defined per SLA (e.g., nightly 2-4 AM every day)
|
||||||
|
- Validate end time > start time (no cross-midnight windows in MVP)
|
||||||
|
- Display in local time (time zone handling future enhancement)
|
||||||
|
|
||||||
|
### Critical Periods
|
||||||
|
- Represent specific date/time ranges requiring higher service levels
|
||||||
|
- Examples: Black Friday, tax season, year-end closing
|
||||||
|
- Duration in minutes is computed automatically
|
||||||
|
- Can overlap (multiple critical periods active simultaneously)
|
||||||
|
- Historical critical periods are kept for audit
|
||||||
|
|
||||||
|
### Contacts
|
||||||
|
- Multiple contacts can be responsible for an SLA
|
||||||
|
- Typical roles: Service Delivery Manager, Technical Lead, Escalation Point
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Endpoints
|
||||||
|
|
||||||
|
### SLA Management
|
||||||
|
- `GET /api/slas` - List all SLAs (paginated)
|
||||||
|
- `GET /api/slas/{id}` - Get SLA details with all related data
|
||||||
|
- `GET /api/applications/{appId}/sla` - Get SLA for specific application
|
||||||
|
- `POST /api/slas` - Create new SLA
|
||||||
|
- `PUT /api/slas/{id}` - Update SLA
|
||||||
|
- `DELETE /api/slas/{id}` - Delete SLA
|
||||||
|
- `GET /api/slas/{id}/contacts` - Get responsible contacts
|
||||||
|
- `POST /api/slas/{id}/contacts/{contactId}` - Add contact to SLA
|
||||||
|
- `DELETE /api/slas/{id}/contacts/{contactId}` - Remove contact from SLA
|
||||||
|
|
||||||
|
### Maintenance Windows
|
||||||
|
- `GET /api/slas/{slaId}/maintenance-windows` - List windows for SLA
|
||||||
|
- `POST /api/slas/{slaId}/maintenance-windows` - Add maintenance window
|
||||||
|
- `PUT /api/maintenance-windows/{id}` - Update maintenance window
|
||||||
|
- `DELETE /api/maintenance-windows/{id}` - Delete maintenance window
|
||||||
|
|
||||||
|
### Critical Periods
|
||||||
|
- `GET /api/slas/{slaId}/critical-periods` - List critical periods for SLA
|
||||||
|
- `GET /api/critical-periods/active` - Get currently active critical periods
|
||||||
|
- `GET /api/critical-periods/upcoming?days={30}` - Get upcoming critical periods
|
||||||
|
- `POST /api/slas/{slaId}/critical-periods` - Add critical period
|
||||||
|
- `PUT /api/critical-periods/{id}` - Update critical period
|
||||||
|
- `DELETE /api/critical-periods/{id}` - Delete critical period
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DTOs
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export enum DayOfWeek {
|
||||||
|
MONDAY = 'MONDAY',
|
||||||
|
TUESDAY = 'TUESDAY',
|
||||||
|
WEDNESDAY = 'WEDNESDAY',
|
||||||
|
THURSDAY = 'THURSDAY',
|
||||||
|
FRIDAY = 'FRIDAY',
|
||||||
|
SATURDAY = 'SATURDAY',
|
||||||
|
SUNDAY = 'SUNDAY'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SLA {
|
||||||
|
id: string;
|
||||||
|
application: { id: string; name: string };
|
||||||
|
availabilityPercentage: number; // 99.9
|
||||||
|
minAvgResponseTimeSeconds: number; // 2
|
||||||
|
reactionTime: string; // "Within 4 hours for P1 incidents"
|
||||||
|
diagramJson?: object; // draw.io diagram as JSON
|
||||||
|
dependenciesDescription?: string;
|
||||||
|
responsibilityScope?: string;
|
||||||
|
maintenanceWindows: MaintenanceWindow[];
|
||||||
|
criticalPeriods: CriticalPeriod[];
|
||||||
|
responsibleContacts: ContactSummary[];
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MaintenanceWindow {
|
||||||
|
id: string;
|
||||||
|
slaId: string;
|
||||||
|
dayOfWeek: DayOfWeek;
|
||||||
|
startTime: string; // "02:00"
|
||||||
|
endTime: string; // "06:00"
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CriticalPeriod {
|
||||||
|
id: string;
|
||||||
|
slaId: string;
|
||||||
|
startDatetime: Date;
|
||||||
|
endDatetime: Date;
|
||||||
|
durationMinutes: number; // Computed
|
||||||
|
description?: string;
|
||||||
|
isActive: boolean; // Computed: current time between start and end
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateSLARequest {
|
||||||
|
applicationId: string;
|
||||||
|
availabilityPercentage: number;
|
||||||
|
minAvgResponseTimeSeconds: number;
|
||||||
|
reactionTime: string;
|
||||||
|
diagramJson?: object;
|
||||||
|
dependenciesDescription?: string;
|
||||||
|
responsibilityScope?: string;
|
||||||
|
maintenanceWindows?: CreateMaintenanceWindowRequest[];
|
||||||
|
criticalPeriods?: CreateCriticalPeriodRequest[];
|
||||||
|
contactIds?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateSLARequest {
|
||||||
|
availabilityPercentage?: number;
|
||||||
|
minAvgResponseTimeSeconds?: number;
|
||||||
|
reactionTime?: string;
|
||||||
|
diagramJson?: object;
|
||||||
|
dependenciesDescription?: string;
|
||||||
|
responsibilityScope?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateMaintenanceWindowRequest {
|
||||||
|
dayOfWeek: DayOfWeek;
|
||||||
|
startTime: string; // "HH:MM"
|
||||||
|
endTime: string; // "HH:MM"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateCriticalPeriodRequest {
|
||||||
|
startDatetime: Date;
|
||||||
|
endDatetime: Date;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Frontend Components
|
||||||
|
|
||||||
|
### SLADetailComponent (Application Detail Tab)
|
||||||
|
- Displayed as tab in Application Detail view
|
||||||
|
- If no SLA exists: "Create SLA" button
|
||||||
|
- If SLA exists: Full SLA details display
|
||||||
|
- Sections:
|
||||||
|
1. **Core Metrics**
|
||||||
|
- Availability: 99.9% (with visual gauge)
|
||||||
|
- Response Time: 2 seconds
|
||||||
|
- Reaction Time: "Within 4 hours for P1 incidents"
|
||||||
|
2. **Maintenance Windows**
|
||||||
|
- Weekly calendar view showing all maintenance windows
|
||||||
|
- List view: Day, Time Range
|
||||||
|
- Add/Edit/Delete maintenance window
|
||||||
|
3. **Critical Periods**
|
||||||
|
- Timeline view of critical periods
|
||||||
|
- Highlight currently active periods
|
||||||
|
- List: Start, End, Duration, Description
|
||||||
|
- Add/Edit/Delete critical period
|
||||||
|
4. **Architecture Diagram**
|
||||||
|
- Render draw.io diagram (if present)
|
||||||
|
- Edit button (opens diagram editor)
|
||||||
|
5. **Dependencies & Scope**
|
||||||
|
- Dependencies description (formatted text)
|
||||||
|
- Responsibility scope (formatted text)
|
||||||
|
6. **Responsible Contacts**
|
||||||
|
- List of contacts with roles
|
||||||
|
- Add/Remove contacts
|
||||||
|
- "Edit SLA" and "Delete SLA" buttons
|
||||||
|
|
||||||
|
### SLAFormComponent
|
||||||
|
- Reactive form with sections:
|
||||||
|
|
||||||
|
**Core Metrics:**
|
||||||
|
- Application (dropdown, disabled in edit mode)
|
||||||
|
- Availability Percentage (number input, 0-100, 2 decimals)
|
||||||
|
- Min Avg Response Time (number input, seconds)
|
||||||
|
- Reaction Time (text input or textarea)
|
||||||
|
|
||||||
|
**Maintenance Windows:**
|
||||||
|
- Repeatable section (add/remove)
|
||||||
|
- Day of Week (dropdown)
|
||||||
|
- Start Time (time picker)
|
||||||
|
- End Time (time picker)
|
||||||
|
- Visual: Weekly calendar preview
|
||||||
|
|
||||||
|
**Critical Periods:**
|
||||||
|
- Repeatable section (add/remove)
|
||||||
|
- Start DateTime (datetime picker)
|
||||||
|
- End DateTime (datetime picker)
|
||||||
|
- Description (text input)
|
||||||
|
- Duration auto-computed and displayed
|
||||||
|
|
||||||
|
**Documentation:**
|
||||||
|
- Diagram (upload draw.io JSON or use embedded editor)
|
||||||
|
- Dependencies Description (rich text editor)
|
||||||
|
- Responsibility Scope (rich text editor)
|
||||||
|
|
||||||
|
**Responsible Contacts:**
|
||||||
|
- Multi-select dropdown
|
||||||
|
|
||||||
|
- Validation:
|
||||||
|
- Availability: 0-100, required
|
||||||
|
- Response time: > 0, required
|
||||||
|
- Reaction time: required
|
||||||
|
- Maintenance window: end time > start time
|
||||||
|
- Critical period: end datetime > start datetime
|
||||||
|
- Application: must not already have SLA
|
||||||
|
|
||||||
|
- Support create and edit modes
|
||||||
|
|
||||||
|
### MaintenanceWindowCalendarComponent
|
||||||
|
- Visual representation of maintenance windows
|
||||||
|
- Weekly calendar grid (7 days × 24 hours)
|
||||||
|
- Highlight maintenance windows
|
||||||
|
- Click to add/edit window
|
||||||
|
- Different colors for different window types (if needed)
|
||||||
|
|
||||||
|
### CriticalPeriodTimelineComponent
|
||||||
|
- Timeline visualization of critical periods
|
||||||
|
- Show past, current, and future periods
|
||||||
|
- Highlight active periods (green background)
|
||||||
|
- Click period to edit/view details
|
||||||
|
- Add new period button
|
||||||
|
|
||||||
|
### SLAListComponent (Admin View)
|
||||||
|
- Table of all SLAs in system
|
||||||
|
- Columns: Application, Availability, Response Time, Maintenance Windows Count, Critical Periods Active, Actions
|
||||||
|
- Filter by application
|
||||||
|
- Sort by availability, response time
|
||||||
|
- Quick view of SLA summary
|
||||||
|
- Navigate to application detail
|
||||||
|
|
||||||
|
### DiagramEditorComponent (Optional Integration)
|
||||||
|
- Embed draw.io editor for diagram creation
|
||||||
|
- Save diagram as JSON
|
||||||
|
- Load existing diagram for editing
|
||||||
|
- Full-screen editing mode
|
||||||
|
- Alternative: Upload draw.io file, store JSON
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] SLA can be created for an application
|
||||||
|
- [ ] SLA creation fails if application already has SLA
|
||||||
|
- [ ] SLA validates availability percentage (0-100)
|
||||||
|
- [ ] SLA validates response time (> 0)
|
||||||
|
- [ ] SLA can be updated
|
||||||
|
- [ ] SLA can be deleted (cascade to windows and periods)
|
||||||
|
- [ ] Maintenance windows can be added to SLA
|
||||||
|
- [ ] Maintenance window validates end time > start time
|
||||||
|
- [ ] Multiple maintenance windows can exist per SLA
|
||||||
|
- [ ] Critical periods can be added to SLA
|
||||||
|
- [ ] Critical period validates end datetime > start datetime
|
||||||
|
- [ ] Critical period duration is computed correctly
|
||||||
|
- [ ] Multiple critical periods can exist per SLA
|
||||||
|
- [ ] Contacts can be added to SLA
|
||||||
|
- [ ] Contacts can be removed from SLA
|
||||||
|
- [ ] SLA details include all related entities
|
||||||
|
- [ ] Active critical periods query works correctly
|
||||||
|
- [ ] All endpoints authenticated
|
||||||
|
- [ ] Tests pass (>80% coverage)
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] User can view SLA in application detail
|
||||||
|
- [ ] If no SLA, "Create SLA" button is shown
|
||||||
|
- [ ] User can create new SLA
|
||||||
|
- [ ] Form validates all required fields
|
||||||
|
- [ ] Form validates ranges (0-100 for availability)
|
||||||
|
- [ ] Form validates time/datetime logic
|
||||||
|
- [ ] User can add multiple maintenance windows
|
||||||
|
- [ ] User can remove maintenance windows
|
||||||
|
- [ ] Weekly calendar preview shows maintenance windows
|
||||||
|
- [ ] User can add multiple critical periods
|
||||||
|
- [ ] User can remove critical periods
|
||||||
|
- [ ] Critical period duration is auto-calculated
|
||||||
|
- [ ] Currently active critical periods are highlighted
|
||||||
|
- [ ] User can upload/edit diagram
|
||||||
|
- [ ] Diagram is rendered correctly
|
||||||
|
- [ ] User can add/remove responsible contacts
|
||||||
|
- [ ] User can edit existing SLA
|
||||||
|
- [ ] User can delete SLA (with confirmation)
|
||||||
|
- [ ] All sections render correctly
|
||||||
|
- [ ] Success/error notifications displayed
|
||||||
|
- [ ] Tests pass (>70% coverage)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Scenarios
|
||||||
|
|
||||||
|
### Scenario 1: Create SLA with Basic Metrics
|
||||||
|
1. Navigate to Application Detail → SLA tab
|
||||||
|
2. Click "Create SLA"
|
||||||
|
3. Fill in core metrics:
|
||||||
|
- Availability: 99.9%
|
||||||
|
- Response Time: 2 seconds
|
||||||
|
- Reaction Time: "P1: 1 hour, P2: 4 hours, P3: 1 business day"
|
||||||
|
4. Skip windows/periods for now
|
||||||
|
5. Click "Save"
|
||||||
|
6. Verify success notification
|
||||||
|
7. Verify SLA details displayed
|
||||||
|
8. Verify availability gauge shows 99.9%
|
||||||
|
|
||||||
|
### Scenario 2: Add Maintenance Windows
|
||||||
|
1. Navigate to existing SLA
|
||||||
|
2. Click "Edit"
|
||||||
|
3. Add maintenance window:
|
||||||
|
- Day: Monday
|
||||||
|
- Start: 02:00
|
||||||
|
- End: 04:00
|
||||||
|
4. Add another window:
|
||||||
|
- Day: Wednesday
|
||||||
|
- Start: 02:00
|
||||||
|
- End: 04:00
|
||||||
|
5. Save
|
||||||
|
6. Verify weekly calendar shows both windows
|
||||||
|
7. Verify windows listed in detail view
|
||||||
|
|
||||||
|
### Scenario 3: Add Critical Period
|
||||||
|
1. Navigate to existing SLA
|
||||||
|
2. Click "Edit"
|
||||||
|
3. Add critical period:
|
||||||
|
- Start: 2026-11-25 00:00 (Black Friday)
|
||||||
|
- End: 2026-11-27 23:59
|
||||||
|
- Description: "Black Friday weekend sales event"
|
||||||
|
4. Verify duration computed: 4,319 minutes
|
||||||
|
5. Save
|
||||||
|
6. Verify critical period listed
|
||||||
|
7. Navigate to dashboard
|
||||||
|
8. If period is active, verify highlighted
|
||||||
|
|
||||||
|
### Scenario 4: Validation - Availability Range
|
||||||
|
1. Create/Edit SLA
|
||||||
|
2. Set availability: 101%
|
||||||
|
3. Attempt to save
|
||||||
|
4. Verify error: "Availability must be between 0 and 100"
|
||||||
|
5. Set availability: -5%
|
||||||
|
6. Verify same error
|
||||||
|
7. Set availability: 99.5%
|
||||||
|
8. Verify validation passes
|
||||||
|
|
||||||
|
### Scenario 5: Validation - Time Order
|
||||||
|
1. Edit SLA
|
||||||
|
2. Add maintenance window:
|
||||||
|
- Day: Tuesday
|
||||||
|
- Start: 06:00
|
||||||
|
- End: 02:00 (before start)
|
||||||
|
3. Attempt to save
|
||||||
|
4. Verify error: "End time must be after start time"
|
||||||
|
|
||||||
|
### Scenario 6: Prevent Duplicate SLA
|
||||||
|
1. Application already has SLA
|
||||||
|
2. Attempt to create another SLA for same application
|
||||||
|
3. Verify error: "Application already has an SLA"
|
||||||
|
4. Edit existing SLA instead
|
||||||
|
|
||||||
|
### Scenario 7: Add Diagram
|
||||||
|
1. Navigate to SLA detail
|
||||||
|
2. Click "Edit"
|
||||||
|
3. Upload draw.io diagram JSON
|
||||||
|
4. Save
|
||||||
|
5. Verify diagram renders in detail view
|
||||||
|
6. Click "Edit Diagram"
|
||||||
|
7. Modify in embedded editor
|
||||||
|
8. Save changes
|
||||||
|
9. Verify updated diagram displayed
|
||||||
|
|
||||||
|
### Scenario 8: Manage Responsible Contacts
|
||||||
|
1. Navigate to SLA detail
|
||||||
|
2. Click "Add Contact"
|
||||||
|
3. Select "John Doe (Service Delivery Manager)"
|
||||||
|
4. Click "Add"
|
||||||
|
5. Verify contact appears in list
|
||||||
|
6. Add another contact: "Jane Smith (Technical Lead)"
|
||||||
|
7. Verify both contacts listed
|
||||||
|
8. Remove "John Doe"
|
||||||
|
9. Verify only "Jane Smith" remains
|
||||||
|
|
||||||
|
### Scenario 9: View Active Critical Periods
|
||||||
|
1. Create critical period starting yesterday, ending tomorrow
|
||||||
|
2. Navigate to dashboard or SLA list
|
||||||
|
3. Verify period marked as "Active" (green highlight)
|
||||||
|
4. View critical period detail
|
||||||
|
5. Verify "Currently Active" badge displayed
|
||||||
|
|
||||||
|
### Scenario 10: Weekly Maintenance Calendar View
|
||||||
|
1. Navigate to SLA detail
|
||||||
|
2. View maintenance windows section
|
||||||
|
3. Verify weekly calendar displayed
|
||||||
|
4. Verify all windows highlighted on calendar
|
||||||
|
5. Hover over window
|
||||||
|
6. Verify tooltip shows time range
|
||||||
|
7. Click on calendar day/time
|
||||||
|
8. Verify opens "Add Maintenance Window" with day pre-selected
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Integration Points
|
||||||
|
|
||||||
|
### Application Detail Enhancement
|
||||||
|
Add "SLA" tab showing:
|
||||||
|
- Full SLA details if exists
|
||||||
|
- Create SLA button if not exists
|
||||||
|
- Quick metrics summary in overview tab
|
||||||
|
|
||||||
|
### Dashboard Enhancement (Optional)
|
||||||
|
Add widgets:
|
||||||
|
- Applications with/without SLAs count
|
||||||
|
- Active critical periods count
|
||||||
|
- Upcoming critical periods (next 7 days)
|
||||||
|
- Maintenance windows today
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
- [ ] Index on application_id for fast SLA lookup
|
||||||
|
- [ ] Index on critical period dates for active/upcoming queries
|
||||||
|
- [ ] Store diagram JSON in JSONB for efficient querying (PostgreSQL)
|
||||||
|
- [ ] Paginate SLA list if count grows large
|
||||||
|
- [ ] Optimize loading of related entities (maintenance windows, critical periods, contacts)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diagram Integration Options
|
||||||
|
|
||||||
|
### Option 1: Upload draw.io JSON
|
||||||
|
- User creates diagram in draw.io desktop app
|
||||||
|
- Exports as JSON
|
||||||
|
- Uploads JSON file in SLA form
|
||||||
|
- Backend stores JSON in JSONB column
|
||||||
|
- Frontend renders using draw.io viewer library
|
||||||
|
|
||||||
|
### Option 2: Embedded draw.io Editor
|
||||||
|
- Integrate draw.io embed library
|
||||||
|
- User edits diagram directly in application
|
||||||
|
- Save diagram as JSON to backend
|
||||||
|
- Requires: `<iframe>` or draw.io integration library
|
||||||
|
|
||||||
|
### Option 3: External Link Only (Simplest MVP)
|
||||||
|
- Store only URL to diagram (in SharePoint, Confluence, etc.)
|
||||||
|
- Display link, open in new tab
|
||||||
|
- No rendering in LDPv2
|
||||||
|
|
||||||
|
**Recommendation for MVP**: Option 3 (external link), upgrade to Option 1 or 2 in Phase 2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Enhancements (Phase 3)
|
||||||
|
|
||||||
|
- [ ] Automated SLA compliance monitoring
|
||||||
|
- [ ] Real-time availability tracking
|
||||||
|
- [ ] Incident management integration
|
||||||
|
- [ ] Automated alerts during critical periods
|
||||||
|
- [ ] SLA breach notifications
|
||||||
|
- [ ] Historical compliance reports
|
||||||
|
- [ ] SLA comparison across applications
|
||||||
|
- [ ] Automated maintenance window scheduling
|
||||||
|
- [ ] Time zone support for global teams
|
||||||
|
- [ ] Integration with monitoring tools (Datadog, New Relic)
|
||||||
|
- [ ] SLA templates for quick creation
|
||||||
|
- [ ] Approval workflow for SLA changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Story Status**: Ready for Development
|
||||||
|
**Estimated Completion**: 6-8 days
|
||||||
@@ -0,0 +1,456 @@
|
|||||||
|
# Story 9: Data Usage Agreements Management
|
||||||
|
|
||||||
|
## Story Overview
|
||||||
|
|
||||||
|
**As a** compliance officer
|
||||||
|
**I want** to track data usage agreements for external dependencies
|
||||||
|
**So that** I can ensure legal compliance and proper authorization for data usage
|
||||||
|
|
||||||
|
**Story Type**: Feature (Compliance & Governance)
|
||||||
|
**Priority**: High
|
||||||
|
**Estimated Effort**: 4-6 days
|
||||||
|
**Dependencies**: Story 8 (External Dependencies), Story 3 (Contacts)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Business Value
|
||||||
|
|
||||||
|
Data Usage Agreements formalize the authorization to use external data sources and services. This enables:
|
||||||
|
- Legal compliance tracking
|
||||||
|
- Data governance documentation
|
||||||
|
- Authorization management per dependency
|
||||||
|
- Contact responsibility tracking
|
||||||
|
- Data lineage documentation
|
||||||
|
- Agreement lifecycle management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### In Scope
|
||||||
|
✅ Data Usage Agreement CRUD operations
|
||||||
|
✅ Agreement-Dependency associations (many-to-many)
|
||||||
|
✅ Agreement-Contact associations (who authorized)
|
||||||
|
✅ Validity period tracking
|
||||||
|
✅ Data nature and lineage documentation
|
||||||
|
✅ Agreement expiration tracking
|
||||||
|
✅ Search and filtering capabilities
|
||||||
|
|
||||||
|
### Out of Scope
|
||||||
|
❌ Automated agreement renewal workflows
|
||||||
|
❌ Digital signature integration
|
||||||
|
❌ Document management system integration
|
||||||
|
❌ Automated compliance reporting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Data Usage Agreements
|
||||||
|
CREATE TABLE data_usage_agreement (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
data_nature TEXT NOT NULL,
|
||||||
|
data_lineage_url VARCHAR(500),
|
||||||
|
documentation_url VARCHAR(500),
|
||||||
|
validity_start_date DATE NOT NULL,
|
||||||
|
validity_end_date DATE,
|
||||||
|
created_at TIMESTAMP NOT NULL,
|
||||||
|
updated_at TIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT check_dua_validity_dates CHECK (validity_end_date IS NULL OR validity_end_date >= validity_start_date)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Junction table: Data Usage Agreement to External Dependency (many-to-many)
|
||||||
|
CREATE TABLE agreement_dependency (
|
||||||
|
agreement_id UUID NOT NULL REFERENCES data_usage_agreement(id) ON DELETE CASCADE,
|
||||||
|
dependency_id UUID NOT NULL REFERENCES external_dependency(id) ON DELETE CASCADE,
|
||||||
|
PRIMARY KEY (agreement_id, dependency_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Junction table: Data Usage Agreement to Contact (many-to-many)
|
||||||
|
-- These are the contacts who authorized the agreement
|
||||||
|
CREATE TABLE agreement_contact (
|
||||||
|
agreement_id UUID NOT NULL REFERENCES data_usage_agreement(id) ON DELETE CASCADE,
|
||||||
|
contact_id UUID NOT NULL REFERENCES contact(id) ON DELETE CASCADE,
|
||||||
|
authorization_role VARCHAR(100), -- e.g., "Data Owner", "Legal Approver"
|
||||||
|
PRIMARY KEY (agreement_id, contact_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_dua_validity_end ON data_usage_agreement(validity_end_date);
|
||||||
|
CREATE INDEX idx_dua_start ON data_usage_agreement(validity_start_date);
|
||||||
|
CREATE INDEX idx_agreement_dep ON agreement_dependency(dependency_id);
|
||||||
|
CREATE INDEX idx_agreement_contact ON agreement_contact(contact_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Business Logic
|
||||||
|
|
||||||
|
### Validity Period Management
|
||||||
|
- **Validity Start Date**: When the agreement becomes effective (required)
|
||||||
|
- **Validity End Date**: When the agreement expires (optional for indefinite agreements)
|
||||||
|
- **Active Status**: An agreement is "active" if:
|
||||||
|
- Current date >= validity_start_date
|
||||||
|
- Current date <= validity_end_date (or no end date)
|
||||||
|
|
||||||
|
### Expiration Tracking
|
||||||
|
- Agreements expiring within 90 days should trigger alerts
|
||||||
|
- Expired agreements should be flagged but not blocked
|
||||||
|
- Dependencies can reference multiple agreements (e.g., different data types)
|
||||||
|
|
||||||
|
### Authorization Documentation
|
||||||
|
- Each agreement must document the nature of data being used
|
||||||
|
- Optional link to data lineage documentation (external system)
|
||||||
|
- Optional link to formal agreement document
|
||||||
|
- Track contacts who authorized the agreement and their roles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Endpoints
|
||||||
|
|
||||||
|
### Data Usage Agreements
|
||||||
|
- `GET /api/data-usage-agreements` - List all agreements (paginated, filtered)
|
||||||
|
- `GET /api/data-usage-agreements/{id}` - Get agreement details
|
||||||
|
- `POST /api/data-usage-agreements` - Create new agreement
|
||||||
|
- `PUT /api/data-usage-agreements/{id}` - Update agreement
|
||||||
|
- `DELETE /api/data-usage-agreements/{id}` - Delete agreement
|
||||||
|
- `GET /api/data-usage-agreements/expiring?days={90}` - Get agreements expiring soon
|
||||||
|
- `GET /api/data-usage-agreements/expired` - Get expired agreements
|
||||||
|
- `GET /api/data-usage-agreements/{id}/dependencies` - Get dependencies covered
|
||||||
|
- `POST /api/data-usage-agreements/{id}/dependencies/{dependencyId}` - Link dependency
|
||||||
|
- `DELETE /api/data-usage-agreements/{id}/dependencies/{dependencyId}` - Unlink dependency
|
||||||
|
- `GET /api/data-usage-agreements/{id}/contacts` - Get authorizing contacts
|
||||||
|
- `POST /api/data-usage-agreements/{id}/contacts` - Add authorizing contact
|
||||||
|
- `DELETE /api/data-usage-agreements/{id}/contacts/{contactId}` - Remove contact
|
||||||
|
|
||||||
|
### Dependencies Enhancement
|
||||||
|
- `GET /api/dependencies/{id}/agreements` - Get agreements for dependency
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DTOs
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export interface DataUsageAgreement {
|
||||||
|
id: string;
|
||||||
|
dataNature: string; // Description of data type/usage
|
||||||
|
dataLineageUrl?: string; // Link to data lineage documentation
|
||||||
|
documentationUrl?: string; // Link to formal agreement document
|
||||||
|
validityStartDate: Date;
|
||||||
|
validityEndDate?: Date;
|
||||||
|
isActive: boolean; // Computed
|
||||||
|
daysUntilExpiration?: number; // Computed if expiring
|
||||||
|
dependencies: DependencySummary[]; // List of covered dependencies
|
||||||
|
authorizingContacts: AgreementContact[]; // Who authorized
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DependencySummary {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
dependencyType: string;
|
||||||
|
application: { id: string; name: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgreementContact {
|
||||||
|
contact: ContactSummary;
|
||||||
|
authorizationRole: string; // e.g., "Data Owner", "Legal Approver"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateDataUsageAgreementRequest {
|
||||||
|
dataNature: string;
|
||||||
|
dataLineageUrl?: string;
|
||||||
|
documentationUrl?: string;
|
||||||
|
validityStartDate: Date;
|
||||||
|
validityEndDate?: Date;
|
||||||
|
dependencyIds?: string[]; // Initial dependencies to link
|
||||||
|
contacts?: Array<{
|
||||||
|
contactId: string;
|
||||||
|
authorizationRole: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateDataUsageAgreementRequest {
|
||||||
|
dataNature?: string;
|
||||||
|
dataLineageUrl?: string;
|
||||||
|
documentationUrl?: string;
|
||||||
|
validityStartDate?: Date;
|
||||||
|
validityEndDate?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LinkDependencyRequest {
|
||||||
|
dependencyId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AddAuthorizingContactRequest {
|
||||||
|
contactId: string;
|
||||||
|
authorizationRole: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Frontend Components
|
||||||
|
|
||||||
|
### DataUsageAgreementListComponent
|
||||||
|
- Table view of all data usage agreements
|
||||||
|
- Columns: Data Nature, Validity Period, Status, Dependencies Count, Authorizers, Actions
|
||||||
|
- Status indicators:
|
||||||
|
- **Active**: Green badge
|
||||||
|
- **Expiring Soon**: Yellow badge (< 90 days)
|
||||||
|
- **Expired**: Red badge
|
||||||
|
- **Future**: Gray badge (start date in future)
|
||||||
|
- Filters:
|
||||||
|
- Status (all, active, expiring, expired)
|
||||||
|
- By dependency (dropdown)
|
||||||
|
- By contact (dropdown)
|
||||||
|
- Date range
|
||||||
|
- Sort by expiration date, start date, data nature
|
||||||
|
- "Create Agreement" button
|
||||||
|
- Actions: View, Edit, Delete
|
||||||
|
|
||||||
|
### DataUsageAgreementFormComponent
|
||||||
|
- Reactive form with fields:
|
||||||
|
- **Data Nature** (required, textarea) - Description of what data is used for
|
||||||
|
- **Data Lineage URL** (optional, URL input) - Link to data lineage documentation
|
||||||
|
- **Documentation URL** (optional, URL input) - Link to formal agreement PDF/document
|
||||||
|
- **Validity Start Date** (required, date picker)
|
||||||
|
- **Validity End Date** (optional, date picker)
|
||||||
|
- **Dependencies** (multi-select, searchable dropdown)
|
||||||
|
- **Authorizing Contacts** (repeatable section):
|
||||||
|
- Contact (dropdown)
|
||||||
|
- Authorization Role (text input) - e.g., "Data Owner", "Legal Approver"
|
||||||
|
- Add/Remove buttons
|
||||||
|
- Validation:
|
||||||
|
- Data nature required (min 10 characters)
|
||||||
|
- Valid URLs
|
||||||
|
- End date >= start date
|
||||||
|
- At least one dependency
|
||||||
|
- At least one authorizing contact
|
||||||
|
- Warning if end date is in past or < 90 days from now
|
||||||
|
- Support create and edit modes
|
||||||
|
|
||||||
|
### DataUsageAgreementDetailComponent
|
||||||
|
- Display full agreement details
|
||||||
|
- Status badge (active/expiring/expired)
|
||||||
|
- Data nature (formatted text)
|
||||||
|
- Links (data lineage, documentation) - clickable
|
||||||
|
- Validity period with visual indicator
|
||||||
|
- Computed fields:
|
||||||
|
- "Expires in X days" if expiring
|
||||||
|
- "Expired X days ago" if expired
|
||||||
|
- Section: **Covered Dependencies**
|
||||||
|
- List of dependencies with application names
|
||||||
|
- "Add Dependency" button
|
||||||
|
- Remove dependency action
|
||||||
|
- Section: **Authorizing Contacts**
|
||||||
|
- Table: Contact Name, Role, Email
|
||||||
|
- "Add Contact" button
|
||||||
|
- Remove contact action
|
||||||
|
- "Edit" and "Delete" buttons
|
||||||
|
|
||||||
|
### DependencyDetailComponent Enhancement
|
||||||
|
- Add section: **Data Usage Agreements**
|
||||||
|
- List all agreements covering this dependency
|
||||||
|
- Click to navigate to agreement detail
|
||||||
|
- "Link to Agreement" button (search and select existing agreement)
|
||||||
|
|
||||||
|
### ExpiringAgreementsWidget (Dashboard)
|
||||||
|
- Widget showing agreements expiring within 90 days
|
||||||
|
- Count badge
|
||||||
|
- List showing: Data nature, days until expiration, dependency count
|
||||||
|
- Click to navigate to agreement detail
|
||||||
|
- Warning icon for expired agreements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Data usage agreement can be created
|
||||||
|
- [ ] Agreement validates required fields
|
||||||
|
- [ ] Agreement validates date logic (end >= start)
|
||||||
|
- [ ] Agreement can be updated
|
||||||
|
- [ ] Agreement can be deleted
|
||||||
|
- [ ] Agreements can be listed with pagination
|
||||||
|
- [ ] Agreements can be filtered by status (active/expiring/expired)
|
||||||
|
- [ ] Dependencies can be linked to agreement
|
||||||
|
- [ ] Dependencies can be unlinked from agreement
|
||||||
|
- [ ] One dependency can have multiple agreements
|
||||||
|
- [ ] One agreement can cover multiple dependencies
|
||||||
|
- [ ] Contacts can be added as authorizers
|
||||||
|
- [ ] Contacts can be removed from agreement
|
||||||
|
- [ ] Authorization role is required when adding contact
|
||||||
|
- [ ] Active status is computed correctly
|
||||||
|
- [ ] Expiring agreements query works correctly
|
||||||
|
- [ ] Agreement details include all dependencies and contacts
|
||||||
|
- [ ] All endpoints authenticated
|
||||||
|
- [ ] Tests pass (>80% coverage)
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] User can view list of all agreements
|
||||||
|
- [ ] Agreements show status badge (active/expiring/expired)
|
||||||
|
- [ ] User can filter agreements by status
|
||||||
|
- [ ] User can create new agreement
|
||||||
|
- [ ] Form validates all required fields
|
||||||
|
- [ ] Form validates URLs
|
||||||
|
- [ ] Form validates date logic
|
||||||
|
- [ ] Form requires at least one dependency
|
||||||
|
- [ ] Form requires at least one authorizing contact
|
||||||
|
- [ ] User can add/remove authorizing contacts dynamically
|
||||||
|
- [ ] User can view agreement details
|
||||||
|
- [ ] User can edit existing agreement
|
||||||
|
- [ ] User can delete agreement (with confirmation)
|
||||||
|
- [ ] User can link dependencies to agreement
|
||||||
|
- [ ] User can unlink dependencies from agreement
|
||||||
|
- [ ] User can add/remove authorizing contacts from detail view
|
||||||
|
- [ ] Expiring agreements are highlighted
|
||||||
|
- [ ] Documentation and lineage links are clickable
|
||||||
|
- [ ] Dependency detail shows linked agreements
|
||||||
|
- [ ] Success/error notifications displayed
|
||||||
|
- [ ] Tests pass (>70% coverage)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Scenarios
|
||||||
|
|
||||||
|
### Scenario 1: Create Data Usage Agreement
|
||||||
|
1. Navigate to Data Usage Agreements list
|
||||||
|
2. Click "Create Agreement"
|
||||||
|
3. Fill in form:
|
||||||
|
- Data Nature: "Customer contact information for email marketing campaigns"
|
||||||
|
- Data Lineage URL: "https://datalineage.company.com/customer-emails"
|
||||||
|
- Documentation URL: "https://docs.company.com/agreements/GDPR-2026-001.pdf"
|
||||||
|
- Validity Start: 2026-01-01
|
||||||
|
- Validity End: 2027-12-31
|
||||||
|
- Dependencies: Select "Marketing Database" and "Email Service API"
|
||||||
|
- Authorizing Contacts:
|
||||||
|
- Contact: "John Doe (Data Protection Officer)", Role: "Data Owner"
|
||||||
|
- Contact: "Jane Smith (Legal)", Role: "Legal Approver"
|
||||||
|
4. Click "Save"
|
||||||
|
5. Verify success notification
|
||||||
|
6. Verify agreement appears in list with "Active" status
|
||||||
|
|
||||||
|
### Scenario 2: Expiring Agreement Warning
|
||||||
|
1. Create agreement with end date 60 days from today
|
||||||
|
2. Verify warning: "This agreement expires in 60 days"
|
||||||
|
3. Save agreement
|
||||||
|
4. Verify "Expiring Soon" badge (yellow)
|
||||||
|
5. Navigate to dashboard
|
||||||
|
6. Verify agreement appears in "Expiring Agreements" widget
|
||||||
|
|
||||||
|
### Scenario 3: Link Dependency to Agreement
|
||||||
|
1. Navigate to Dependency Detail
|
||||||
|
2. View "Data Usage Agreements" section
|
||||||
|
3. Click "Link to Agreement"
|
||||||
|
4. Search and select existing agreement
|
||||||
|
5. Click "Link"
|
||||||
|
6. Verify success notification
|
||||||
|
7. Verify agreement appears in dependency's agreements list
|
||||||
|
8. Navigate to agreement detail
|
||||||
|
9. Verify dependency appears in covered dependencies list
|
||||||
|
|
||||||
|
### Scenario 4: Add Authorizing Contact
|
||||||
|
1. Navigate to Agreement Detail
|
||||||
|
2. In "Authorizing Contacts" section, click "Add Contact"
|
||||||
|
3. Select contact: "Bob Johnson (Compliance Manager)"
|
||||||
|
4. Enter role: "Compliance Reviewer"
|
||||||
|
5. Click "Add"
|
||||||
|
6. Verify contact appears in list with role
|
||||||
|
7. Verify contact's email is displayed
|
||||||
|
|
||||||
|
### Scenario 5: Multiple Agreements per Dependency
|
||||||
|
1. Create Dependency: "Customer Database"
|
||||||
|
2. Create Agreement 1: "Marketing Data Usage"
|
||||||
|
3. Link "Customer Database" to Agreement 1
|
||||||
|
4. Create Agreement 2: "Analytics Data Usage"
|
||||||
|
5. Link "Customer Database" to Agreement 2
|
||||||
|
6. Navigate to "Customer Database" detail
|
||||||
|
7. Verify both agreements listed
|
||||||
|
8. Verify each agreement shows different data nature
|
||||||
|
|
||||||
|
### Scenario 6: Date Validation
|
||||||
|
1. Create agreement form
|
||||||
|
2. Set start date: 2027-01-01
|
||||||
|
3. Set end date: 2026-01-01
|
||||||
|
4. Attempt to save
|
||||||
|
5. Verify error: "End date must be after start date"
|
||||||
|
|
||||||
|
### Scenario 7: Filter Agreements
|
||||||
|
1. Create agreements with various statuses
|
||||||
|
2. Filter by "Expiring Soon"
|
||||||
|
3. Verify only expiring agreements shown
|
||||||
|
4. Filter by specific dependency
|
||||||
|
5. Verify only agreements covering that dependency shown
|
||||||
|
|
||||||
|
### Scenario 8: View Expired Agreement
|
||||||
|
1. Navigate to agreement with past end date
|
||||||
|
2. Verify "Expired" badge (red)
|
||||||
|
3. Verify message: "This agreement expired X days ago"
|
||||||
|
4. Verify dependencies still visible
|
||||||
|
5. Verify no functionality blocked (informational only)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Integration Points
|
||||||
|
|
||||||
|
### Dependency Detail Enhancement
|
||||||
|
Add section showing:
|
||||||
|
- List of data usage agreements covering this dependency
|
||||||
|
- Agreement status and expiration info
|
||||||
|
- Quick link to agreement detail
|
||||||
|
- "Link to Agreement" action
|
||||||
|
|
||||||
|
### Dashboard Enhancement
|
||||||
|
Add "Expiring Agreements" widget:
|
||||||
|
- Count of agreements expiring within 90 days
|
||||||
|
- List of top 5 expiring soonest
|
||||||
|
- Link to full list
|
||||||
|
|
||||||
|
### Application Detail Enhancement (Indirect)
|
||||||
|
Show summary of agreements via dependencies:
|
||||||
|
- Count of dependencies with valid agreements
|
||||||
|
- Count of dependencies without agreements
|
||||||
|
- Warnings for expired agreements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
- [ ] Index on validity_end_date for expiring/expired queries
|
||||||
|
- [ ] Index on junction tables for fast agreement-dependency lookups
|
||||||
|
- [ ] Pagination for agreement lists
|
||||||
|
- [ ] Optimize N+1 queries when loading dependencies and contacts
|
||||||
|
- [ ] Consider caching expiring agreements count
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Compliance & Security Considerations
|
||||||
|
|
||||||
|
- [ ] Audit log for all agreement changes
|
||||||
|
- [ ] Restrict deletion of agreements (admin only or soft delete)
|
||||||
|
- [ ] Email notifications for expiring agreements (90 days, 30 days, 7 days)
|
||||||
|
- [ ] Export capability for compliance reporting
|
||||||
|
- [ ] Document retention policy (keep expired agreements for audit)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Enhancements (Phase 3)
|
||||||
|
|
||||||
|
- [ ] Automated renewal workflow
|
||||||
|
- [ ] Digital signature integration
|
||||||
|
- [ ] Document version management
|
||||||
|
- [ ] Automated compliance reporting
|
||||||
|
- [ ] Integration with DMS (Document Management System)
|
||||||
|
- [ ] Email alerts for expiring agreements
|
||||||
|
- [ ] Bulk agreement creation
|
||||||
|
- [ ] Agreement templates
|
||||||
|
- [ ] Approval workflow before activation
|
||||||
|
- [ ] Impact analysis (what happens if agreement expires)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Story Status**: Ready for Development
|
||||||
|
**Estimated Completion**: 4-6 days
|
||||||
Reference in New Issue
Block a user