This commit is contained in:
Aditya Siregar
2025-09-01 12:06:14 +07:00
parent 2bdce63852
commit aa662a321f
25 changed files with 2923 additions and 189 deletions
+185
View File
@@ -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"`
}
+92 -37
View File
@@ -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"`
}