Update
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// AnalyticsDashboardRequest represents the request for analytics data
|
||||
type AnalyticsDashboardRequest struct {
|
||||
StartDate string `form:"start_date" json:"start_date"`
|
||||
EndDate string `form:"end_date" json:"end_date"`
|
||||
DepartmentID *uuid.UUID `form:"department_id" json:"department_id,omitempty"`
|
||||
UserID *uuid.UUID `form:"user_id" json:"user_id,omitempty"`
|
||||
}
|
||||
|
||||
// AnalyticsDashboardResponse represents the complete analytics dashboard
|
||||
type AnalyticsDashboardResponse struct {
|
||||
Summary LetterSummaryStats `json:"summary"`
|
||||
PriorityDistribution []PriorityDistribution `json:"priority_distribution"`
|
||||
DepartmentStats []DepartmentStats `json:"department_stats"`
|
||||
MonthlyTrend []MonthlyTrend `json:"monthly_trend"`
|
||||
DepartmentsStats []SimpleDepartmentStats `json:"departments_stats,omitempty"`
|
||||
InstitutionStats []InstitutionStats `json:"institution_stats"`
|
||||
DailyActivity []DailyActivity `json:"daily_activity"`
|
||||
StatusDistribution []StatusDistribution `json:"status_distribution,omitempty"`
|
||||
TopSenders []TopUserStats `json:"top_senders,omitempty"`
|
||||
TopRecipients []TopUserStats `json:"top_recipients,omitempty"`
|
||||
ApprovalMetrics *ApprovalMetrics `json:"approval_metrics,omitempty"`
|
||||
ResponseTimeStats *ResponseTimeStats `json:"response_time_stats,omitempty"`
|
||||
}
|
||||
|
||||
// LetterSummaryStats represents overall summary statistics
|
||||
type LetterSummaryStats struct {
|
||||
TotalIncoming int64 `json:"total_incoming"`
|
||||
TotalOutgoing int64 `json:"total_outgoing"`
|
||||
WeekOverWeekGrowth float64 `json:"week_over_week_growth"`
|
||||
MonthOverMonthGrowth float64 `json:"month_over_month_growth"`
|
||||
TotalPending int64 `json:"total_pending,omitempty"`
|
||||
TotalApproved int64 `json:"total_approved,omitempty"`
|
||||
TotalRejected int64 `json:"total_rejected,omitempty"`
|
||||
TotalArchived int64 `json:"total_archived,omitempty"`
|
||||
AvgProcessingTime float64 `json:"avg_processing_time_hours,omitempty"`
|
||||
CompletionRate float64 `json:"completion_rate,omitempty"`
|
||||
}
|
||||
|
||||
// StatusDistribution represents letter distribution by status
|
||||
type StatusDistribution struct {
|
||||
Status string `json:"status"`
|
||||
Count int64 `json:"count"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
Type string `json:"type"` // incoming or outgoing
|
||||
}
|
||||
|
||||
// PriorityDistribution represents letter distribution by priority
|
||||
type PriorityDistribution struct {
|
||||
PriorityID string `json:"priority_id"`
|
||||
PriorityName string `json:"priority_name"`
|
||||
Level int `json:"level"`
|
||||
Count int64 `json:"count"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
AvgResponseTime float64 `json:"avg_response_time_hours"`
|
||||
}
|
||||
|
||||
// DepartmentStats represents statistics per department
|
||||
type DepartmentStats struct {
|
||||
DepartmentID uuid.UUID `json:"department_id"`
|
||||
DepartmentName string `json:"department_name"`
|
||||
DepartmentCode string `json:"department_code"`
|
||||
IncomingCount int64 `json:"incoming_count"`
|
||||
OutgoingCount int64 `json:"outgoing_count"`
|
||||
PendingCount int64 `json:"pending_count"`
|
||||
AvgResponseTime float64 `json:"avg_response_time_hours"`
|
||||
CompletionRate float64 `json:"completion_rate"`
|
||||
}
|
||||
|
||||
// MonthlyTrend represents monthly trend data
|
||||
type MonthlyTrend struct {
|
||||
Month string `json:"month"`
|
||||
Year int `json:"year"`
|
||||
IncomingCount int64 `json:"incoming_count"`
|
||||
OutgoingCount int64 `json:"outgoing_count"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
GrowthRate float64 `json:"growth_rate"`
|
||||
}
|
||||
|
||||
// TopUserStats represents top users by letter activity
|
||||
type TopUserStats struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
UserEmail string `json:"user_email"`
|
||||
Department string `json:"department"`
|
||||
LetterCount int64 `json:"letter_count"`
|
||||
AvgResponseTime float64 `json:"avg_response_time_hours"`
|
||||
}
|
||||
|
||||
// InstitutionStats represents statistics per institution
|
||||
type InstitutionStats struct {
|
||||
InstitutionID uuid.UUID `json:"institution_id"`
|
||||
InstitutionName string `json:"institution_name"`
|
||||
InstitutionType string `json:"institution_type"`
|
||||
IncomingCount int64 `json:"incoming_count"`
|
||||
OutgoingCount int64 `json:"outgoing_count"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
LastActivity time.Time `json:"last_activity"`
|
||||
}
|
||||
|
||||
// ApprovalMetrics represents approval-related metrics
|
||||
type ApprovalMetrics struct {
|
||||
TotalSubmitted int64 `json:"total_submitted"`
|
||||
TotalApproved int64 `json:"total_approved"`
|
||||
TotalRejected int64 `json:"total_rejected"`
|
||||
TotalPending int64 `json:"total_pending"`
|
||||
ApprovalRate float64 `json:"approval_rate"`
|
||||
RejectionRate float64 `json:"rejection_rate"`
|
||||
AvgApprovalTime float64 `json:"avg_approval_time_hours"`
|
||||
AvgApprovalSteps float64 `json:"avg_approval_steps"`
|
||||
BottleneckSteps []BottleneckStep `json:"bottleneck_steps"`
|
||||
}
|
||||
|
||||
// BottleneckStep represents approval steps that cause delays
|
||||
type BottleneckStep struct {
|
||||
StepOrder int `json:"step_order"`
|
||||
ApproverName string `json:"approver_name"`
|
||||
AvgProcessTime float64 `json:"avg_process_time_hours"`
|
||||
PendingCount int64 `json:"pending_count"`
|
||||
}
|
||||
|
||||
// ResponseTimeStats represents response time statistics
|
||||
type ResponseTimeStats struct {
|
||||
MinResponseTime float64 `json:"min_response_time_hours"`
|
||||
MaxResponseTime float64 `json:"max_response_time_hours"`
|
||||
AvgResponseTime float64 `json:"avg_response_time_hours"`
|
||||
MedianResponseTime float64 `json:"median_response_time_hours"`
|
||||
P95ResponseTime float64 `json:"p95_response_time_hours"`
|
||||
P99ResponseTime float64 `json:"p99_response_time_hours"`
|
||||
}
|
||||
|
||||
// SimpleDepartmentStats represents simplified department statistics
|
||||
type SimpleDepartmentStats struct {
|
||||
DepartmentID uuid.UUID `json:"department_id"`
|
||||
Department string `json:"department"`
|
||||
LetterCount int64 `json:"letter_count"`
|
||||
}
|
||||
|
||||
// DailyActivity represents daily activity data
|
||||
type DailyActivity struct {
|
||||
Date string `json:"date"`
|
||||
DayOfWeek string `json:"day_of_week"`
|
||||
IncomingCount int64 `json:"incoming_count"`
|
||||
OutgoingCount int64 `json:"outgoing_count"`
|
||||
ApprovedCount int64 `json:"approved_count,omitempty"`
|
||||
RejectedCount int64 `json:"rejected_count,omitempty"`
|
||||
HourlyDistribution []HourlyActivity `json:"hourly_distribution,omitempty"`
|
||||
}
|
||||
|
||||
// HourlyActivity represents hourly activity within a day
|
||||
type HourlyActivity struct {
|
||||
Hour int `json:"hour"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// LetterVolumeByTypeResponse represents letter volume grouped by type
|
||||
type LetterVolumeByTypeResponse struct {
|
||||
Incoming IncomingLetterVolume `json:"incoming"`
|
||||
Outgoing OutgoingLetterVolume `json:"outgoing"`
|
||||
}
|
||||
|
||||
// IncomingLetterVolume represents incoming letter statistics
|
||||
type IncomingLetterVolume struct {
|
||||
Today int64 `json:"today"`
|
||||
ThisWeek int64 `json:"this_week"`
|
||||
ThisMonth int64 `json:"this_month"`
|
||||
ThisYear int64 `json:"this_year"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// OutgoingLetterVolume represents outgoing letter statistics
|
||||
type OutgoingLetterVolume struct {
|
||||
Today int64 `json:"today"`
|
||||
ThisWeek int64 `json:"this_week"`
|
||||
ThisMonth int64 `json:"this_month"`
|
||||
ThisYear int64 `json:"this_year"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
@@ -57,13 +57,15 @@ type OutgoingLetterAttachmentResponse struct {
|
||||
}
|
||||
|
||||
type OutgoingLetterApprovalResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
StepOrder int `json:"step_order"`
|
||||
ApproverID *uuid.UUID `json:"approver_id,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Remarks *string `json:"remarks,omitempty"`
|
||||
ActedAt *time.Time `json:"acted_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
StepOrder int `json:"step_order"`
|
||||
ParallelGroup int `json:"parallel_group"`
|
||||
IsRequired bool `json:"is_required"`
|
||||
ApproverID *uuid.UUID `json:"approver_id,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Remarks *string `json:"remarks,omitempty"`
|
||||
ActedAt *time.Time `json:"acted_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type OutgoingLetterResponse struct {
|
||||
@@ -97,14 +99,18 @@ type UpdateOutgoingLetterRequest struct {
|
||||
}
|
||||
|
||||
type ListOutgoingLettersRequest struct {
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
Query *string `json:"query,omitempty"`
|
||||
CreatedBy *uuid.UUID `json:"created_by,omitempty"`
|
||||
ReceiverInstitutionID *uuid.UUID `json:"receiver_institution_id,omitempty"`
|
||||
FromDate *time.Time `json:"from_date,omitempty"`
|
||||
ToDate *time.Time `json:"to_date,omitempty"`
|
||||
Page int `form:"page" json:"page"`
|
||||
Limit int `form:"limit" json:"limit"`
|
||||
Status string `form:"status" json:"status,omitempty"`
|
||||
Query string `form:"q" json:"query,omitempty"`
|
||||
CreatedBy *uuid.UUID `form:"created_by" json:"created_by,omitempty"`
|
||||
DepartmentID *uuid.UUID `form:"department_id" json:"department_id,omitempty"`
|
||||
ReceiverInstitutionID *uuid.UUID `form:"receiver_institution_id" json:"receiver_institution_id,omitempty"`
|
||||
FromDate string `form:"from_date" json:"from_date,omitempty"`
|
||||
ToDate string `form:"to_date" json:"to_date,omitempty"`
|
||||
PriorityID *uuid.UUID `form:"priority_id" json:"priority_id,omitempty"`
|
||||
SortBy string `form:"sort_by" json:"sort_by,omitempty"`
|
||||
SortOrder string `form:"sort_order" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
type ListOutgoingLettersResponse struct {
|
||||
@@ -242,32 +248,45 @@ type OutgoingLetterApprovalDiscussionsResponse struct {
|
||||
|
||||
// EnhancedOutgoingLetterApprovalResponse includes approval details with related data
|
||||
type EnhancedOutgoingLetterApprovalResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
StepID uuid.UUID `json:"step_id"`
|
||||
ApproverID *uuid.UUID `json:"approver_id,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Remarks *string `json:"remarks,omitempty"`
|
||||
ActedAt *time.Time `json:"acted_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Step *ApprovalFlowStepResponse `json:"step,omitempty"`
|
||||
Approver *UserResponse `json:"approver,omitempty"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
StepID uuid.UUID `json:"step_id"`
|
||||
StepOrder int `json:"step_order"`
|
||||
ParallelGroup int `json:"parallel_group"`
|
||||
IsRequired bool `json:"is_required"`
|
||||
ApproverID *uuid.UUID `json:"approver_id,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Remarks *string `json:"remarks,omitempty"`
|
||||
ActedAt *time.Time `json:"acted_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Step *ApprovalFlowStepResponse `json:"step,omitempty"`
|
||||
Approver *UserResponse `json:"approver,omitempty"`
|
||||
}
|
||||
|
||||
// GetLetterApprovalsResponse represents the list of approvals for a letter
|
||||
type GetLetterApprovalsResponse struct {
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
LetterNumber string `json:"letter_number"`
|
||||
LetterStatus string `json:"letter_status"`
|
||||
TotalSteps int `json:"total_steps"`
|
||||
CurrentStep int `json:"current_step"`
|
||||
Approvals []EnhancedOutgoingLetterApprovalResponse `json:"approvals"`
|
||||
}
|
||||
|
||||
// OutgoingLetterDiscussionResponse represents a discussion on an outgoing letter
|
||||
type OutgoingLetterDiscussionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Message string `json:"message"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
EditedAt *time.Time `json:"edited_at,omitempty"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
MentionedUsers []UserResponse `json:"mentioned_users,omitempty"`
|
||||
Attachments []OutgoingLetterDiscussionAttachmentResponse `json:"attachments,omitempty"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Message string `json:"message"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
EditedAt *time.Time `json:"edited_at,omitempty"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
MentionedUsers []UserResponse `json:"mentioned_users,omitempty"`
|
||||
Attachments []OutgoingLetterDiscussionAttachmentResponse `json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
// OutgoingLetterDiscussionAttachmentResponse represents an attachment in a discussion
|
||||
@@ -280,3 +299,39 @@ type OutgoingLetterDiscussionAttachmentResponse struct {
|
||||
UploadedBy *uuid.UUID `json:"uploaded_by,omitempty"`
|
||||
UploadedAt time.Time `json:"uploaded_at"`
|
||||
}
|
||||
|
||||
// TimelineEvent represents a single event in the approval timeline
|
||||
type TimelineEvent struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"` // "approval", "discussion", "submission", "rejection"
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Actor *UserResponse `json:"actor,omitempty"`
|
||||
Action string `json:"action"`
|
||||
Description string `json:"description"`
|
||||
Status string `json:"status,omitempty"`
|
||||
StepOrder int `json:"step_order,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// ApprovalTimelineResponse represents the complete timeline for a letter
|
||||
type ApprovalTimelineResponse struct {
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
LetterNumber string `json:"letter_number"`
|
||||
Subject string `json:"subject"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Timeline []TimelineEvent `json:"timeline"`
|
||||
Summary TimelineSummary `json:"summary"`
|
||||
}
|
||||
|
||||
// TimelineSummary provides overview statistics for the timeline
|
||||
type TimelineSummary struct {
|
||||
TotalSteps int `json:"total_steps"`
|
||||
CompletedSteps int `json:"completed_steps"`
|
||||
PendingSteps int `json:"pending_steps"`
|
||||
CurrentStep int `json:"current_step"`
|
||||
TotalDuration string `json:"total_duration"`
|
||||
AverageStepTime string `json:"average_step_time"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user