add dukcapil
This commit is contained in:
@@ -1,186 +0,0 @@
|
||||
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"`
|
||||
TotalThisWeek float64 `json:"total_this_week"`
|
||||
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"`
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type DepartmentInfo struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code,omitempty"`
|
||||
}
|
||||
|
||||
type DispositionRouteResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
FromDepartmentID uuid.UUID `json:"from_department_id"`
|
||||
ToDepartmentID uuid.UUID `json:"to_department_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
AllowedActions map[string]interface{} `json:"allowed_actions,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// Department information
|
||||
FromDepartment DepartmentInfo `json:"from_department"`
|
||||
ToDepartment DepartmentInfo `json:"to_department"`
|
||||
}
|
||||
|
||||
type CreateDispositionRouteRequest struct {
|
||||
FromDepartmentID uuid.UUID `json:"from_department_id" binding:"required"`
|
||||
ToDepartmentIDs []uuid.UUID `json:"to_department_ids" binding:"required,min=1"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
AllowedActions *map[string]interface{} `json:"allowed_actions,omitempty"`
|
||||
}
|
||||
|
||||
// BulkCreateDispositionRouteResponse response for bulk create/update operation
|
||||
type BulkCreateDispositionRouteResponse struct {
|
||||
Created int `json:"created"`
|
||||
Updated int `json:"updated"`
|
||||
Routes []DispositionRouteResponse `json:"routes"`
|
||||
}
|
||||
|
||||
type UpdateDispositionRouteRequest struct {
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
AllowedActions *map[string]interface{} `json:"allowed_actions,omitempty"`
|
||||
}
|
||||
|
||||
type ListDispositionRoutesResponse struct {
|
||||
Routes []DispositionRouteResponse `json:"routes"`
|
||||
}
|
||||
|
||||
// DepartmentMapping represents department ID and name mapping
|
||||
type DepartmentMapping struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// DispositionRouteGroupedItem represents a single grouped route item with clean department structure
|
||||
type DispositionRouteGroupedItem struct {
|
||||
FromDepartment DepartmentMapping `json:"from_department"`
|
||||
ToDepartments []DepartmentMapping `json:"to_departments"`
|
||||
}
|
||||
|
||||
// ListDispositionRoutesGroupedResponse returns all routes grouped by from_department_id
|
||||
type ListDispositionRoutesGroupedResponse struct {
|
||||
Dispositions []DispositionRouteGroupedItem `json:"dispositions"`
|
||||
}
|
||||
|
||||
// ListDispositionRoutesDetailedResponse returns all routes with department details
|
||||
type ListDispositionRoutesDetailedResponse struct {
|
||||
Routes []DispositionRouteResponse `json:"routes"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package contract
|
||||
|
||||
// FaceMatchRequest is the inbound payload from clients of this service to
|
||||
// trigger a Dukcapil 1:N face recognition lookup.
|
||||
//
|
||||
// Image must already be a base64 (no data:image prefix) representation of a
|
||||
// jpg/png file. Threshold is forwarded to Dukcapil (1..20). IP is optional;
|
||||
// when empty the configured default IP will be used.
|
||||
type FaceMatchRequest struct {
|
||||
TransactionID string `json:"transaction_id" validate:"required,max=20"`
|
||||
TransactionSource string `json:"transaction_source" validate:"required,max=50"`
|
||||
Threshold string `json:"threshold" validate:"required"`
|
||||
Image string `json:"image" validate:"required"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
}
|
||||
|
||||
// DukcapilFaceRequest is the exact JSON body sent to the Dukcapil
|
||||
// face-recognition endpoint (CALL_FN). user_id and password are RSA encrypted
|
||||
// with the provided public key and base64 encoded.
|
||||
type DukcapilFaceRequest struct {
|
||||
TransactionID string `json:"transactionId"`
|
||||
TransactionSource string `json:"transactionSource"`
|
||||
Threshold string `json:"threshold"`
|
||||
Image string `json:"image"`
|
||||
UserID string `json:"user_id"`
|
||||
Password string `json:"password"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
// DukcapilFaceResponse is the standard Dukcapil response envelope (success +
|
||||
// most error variants share this shape). Some error variants use a different
|
||||
// shape – clients should also inspect ErrorCode.
|
||||
type DukcapilFaceResponse struct {
|
||||
TID string `json:"tid"`
|
||||
EncounterID interface{} `json:"encounter_id"`
|
||||
Error string `json:"error"`
|
||||
ErrorCode string `json:"errorCode"`
|
||||
FingerData interface{} `json:"finger_data"`
|
||||
IrisData interface{} `json:"iris_data"`
|
||||
FaceData interface{} `json:"face_data"`
|
||||
RequestType string `json:"request_type"`
|
||||
MaxResults int `json:"maxResults"`
|
||||
FaceThreshold string `json:"faceThreshold"`
|
||||
FingerThreshold int `json:"fingerThreshold"`
|
||||
IrisThreshold int `json:"irisThreshold"`
|
||||
Response string `json:"response"`
|
||||
}
|
||||
|
||||
// FaceMatchResponse is what we return to our API consumers.
|
||||
type FaceMatchResponse struct {
|
||||
TID string `json:"tid"`
|
||||
ErrorCode string `json:"error_code"`
|
||||
Error string `json:"error"`
|
||||
RequestType string `json:"request_type"`
|
||||
Threshold string `json:"threshold"`
|
||||
MaxResults int `json:"max_results"`
|
||||
Matches []FaceMatchResult `json:"matches"`
|
||||
Raw *DukcapilFaceResponse `json:"raw,omitempty"`
|
||||
}
|
||||
|
||||
// FaceMatchResult represents a single (NIK -> score) entry from the Dukcapil
|
||||
// `response.face.FACE_T5` map.
|
||||
type FaceMatchResult struct {
|
||||
NIK string `json:"nik"`
|
||||
Score float64 `json:"score"`
|
||||
}
|
||||
@@ -1,291 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type SearchIncomingLettersRequest struct {
|
||||
Query string `json:"query" form:"query"`
|
||||
LetterNumber string `json:"letter_number" form:"letter_number"`
|
||||
Subject string `json:"subject" form:"subject"`
|
||||
Status string `json:"status" form:"status"`
|
||||
PriorityID *uuid.UUID `json:"priority_id" form:"priority_id"`
|
||||
InstitutionID *uuid.UUID `json:"institution_id" form:"institution_id"`
|
||||
CreatedBy *uuid.UUID `json:"created_by" form:"created_by"`
|
||||
DateFrom *time.Time `json:"date_from" form:"date_from"`
|
||||
DateTo *time.Time `json:"date_to" form:"date_to"`
|
||||
Page int `json:"page" form:"page"`
|
||||
Limit int `json:"limit" form:"limit"`
|
||||
SortBy string `json:"sort_by" form:"sort_by"`
|
||||
SortOrder string `json:"sort_order" form:"sort_order"`
|
||||
}
|
||||
|
||||
type SearchIncomingLettersResponse struct {
|
||||
Letters []IncomingLetterResponse `json:"letters"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
type CreateIncomingLetterAttachment struct {
|
||||
FileURL string `json:"file_url"`
|
||||
FileName string `json:"file_name"`
|
||||
FileType string `json:"file_type"`
|
||||
}
|
||||
|
||||
type CreateIncomingLetterRequest struct {
|
||||
LetterNumber string `json:"-"` // Generated by service layer
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject string `json:"subject"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PriorityID *uuid.UUID `json:"priority_id,omitempty"`
|
||||
SenderInstitutionID *uuid.UUID `json:"sender_institution_id,omitempty"`
|
||||
SenderName *string `json:"sender_name,omitempty"`
|
||||
Addressee *string `json:"addressee,omitempty"`
|
||||
ReceivedDate time.Time `json:"received_date"`
|
||||
DueDate *time.Time `json:"due_date,omitempty"`
|
||||
Type string `json:"type"` // UTAMA or TEMBUSAN
|
||||
Attachments []CreateIncomingLetterAttachment `json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
type IncomingLetterAttachmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
FileURL string `json:"file_url"`
|
||||
FileName string `json:"file_name"`
|
||||
FileType string `json:"file_type"`
|
||||
UploadedAt time.Time `json:"uploaded_at"`
|
||||
}
|
||||
|
||||
type IncomingLetterResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterNumber string `json:"letter_number"`
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject string `json:"subject"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Priority *PriorityResponse `json:"priority,omitempty"`
|
||||
SenderInstitution *InstitutionResponse `json:"sender_institution,omitempty"`
|
||||
SenderName *string `json:"sender_name,omitempty"`
|
||||
Addressee *string `json:"addressee,omitempty"`
|
||||
ReceivedDate time.Time `json:"received_date"`
|
||||
DueDate *time.Time `json:"due_date,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Attachments []IncomingLetterAttachmentResponse `json:"attachments"`
|
||||
IsRead bool `json:"is_read"`
|
||||
Dispositions []EnhancedDispositionResponse `json:"dispositions"`
|
||||
}
|
||||
|
||||
type UpdateIncomingLetterRequest struct {
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject *string `json:"subject,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PriorityID *uuid.UUID `json:"priority_id,omitempty"`
|
||||
SenderInstitutionID *uuid.UUID `json:"sender_institution_id,omitempty"`
|
||||
SenderName *string `json:"sender_name,omitempty"`
|
||||
Addressee *string `json:"addressee,omitempty"`
|
||||
ReceivedDate *time.Time `json:"received_date,omitempty"`
|
||||
DueDate *time.Time `json:"due_date,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type ListIncomingLettersRequest struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
Query *string `json:"query,omitempty"`
|
||||
DepartmentID *uuid.UUID
|
||||
IsRead *bool `json:"is_read,omitempty"`
|
||||
PriorityIDs []uuid.UUID `json:"priority_ids,omitempty"`
|
||||
IsDispositioned *bool `json:"is_dispositioned,omitempty"`
|
||||
IsArchived *bool `json:"is_archived,omitempty"`
|
||||
}
|
||||
|
||||
type ListIncomingLettersResponse struct {
|
||||
Letters []IncomingLetterResponse `json:"letters"`
|
||||
Pagination PaginationResponse `json:"pagination"`
|
||||
TotalUnread int `json:"total_unread"`
|
||||
}
|
||||
|
||||
type LetterUnreadCountResponse struct {
|
||||
IncomingLetter struct {
|
||||
Unread int `json:"unread"`
|
||||
} `json:"incoming_letter"`
|
||||
OutgoingLetter struct {
|
||||
Unread int `json:"unread"`
|
||||
} `json:"outgoing_letter"`
|
||||
}
|
||||
|
||||
type MarkLetterReadResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type CreateDispositionActionSelection struct {
|
||||
ActionID uuid.UUID `json:"action_id"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
}
|
||||
|
||||
type CreateLetterDispositionRequest struct {
|
||||
FromDepartment uuid.UUID `json:"from_department"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
ToDepartmentIDs []uuid.UUID `json:"to_department_ids"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
SelectedActions []CreateDispositionActionSelection `json:"selected_actions,omitempty"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
}
|
||||
|
||||
type DispositionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
ReadAt *time.Time `json:"read_at,omitempty"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ListDispositionsResponse struct {
|
||||
Dispositions []DispositionResponse `json:"dispositions"`
|
||||
}
|
||||
|
||||
type EnhancedDispositionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
ReadAt *time.Time `json:"read_at,omitempty"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Department DepartmentResponse `json:"department"`
|
||||
Departments []DispositionDepartmentResponse `json:"departments"`
|
||||
Actions []DispositionActionSelectionResponse `json:"actions"`
|
||||
DispositionNotes []DispositionNoteResponse `json:"disposition_notes"`
|
||||
}
|
||||
|
||||
type DispositionDepartmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
DepartmentID uuid.UUID `json:"department_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Department *DepartmentResponse `json:"department,omitempty"`
|
||||
}
|
||||
|
||||
type DispositionActionSelectionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
ActionID uuid.UUID `json:"action_id"`
|
||||
Action *DispositionActionResponse `json:"action,omitempty"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type DispositionNoteResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
UserID *uuid.UUID `json:"user_id,omitempty"`
|
||||
Note string `json:"note"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
type ListEnhancedDispositionsResponse struct {
|
||||
Dispositions []EnhancedDispositionResponse `json:"dispositions"`
|
||||
Discussions []LetterDiscussionResponse `json:"discussions"`
|
||||
}
|
||||
|
||||
type GetDepartmentDispositionStatusRequest struct {
|
||||
LetterIncomingID uuid.UUID `json:"letter_incoming_id"`
|
||||
DepartmentID uuid.UUID `json:"department_id"`
|
||||
}
|
||||
|
||||
type DepartmentDispositionStatusResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
Letter *IncomingLetterResponse `json:"letter,omitempty"`
|
||||
FromDepartmentID *uuid.UUID `json:"from_department_id,omitempty"`
|
||||
FromDepartment *DepartmentResponse `json:"from_department,omitempty"`
|
||||
ToDepartmentID uuid.UUID `json:"to_department_id"`
|
||||
ToDepartment *DepartmentResponse `json:"to_department,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
ReadAt *time.Time `json:"read_at,omitempty"`
|
||||
CompletedAt *time.Time `json:"completed_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ListDepartmentDispositionStatusResponse struct {
|
||||
Dispositions []DepartmentDispositionStatusResponse `json:"dispositions"`
|
||||
Pagination PaginationResponse `json:"pagination"`
|
||||
}
|
||||
|
||||
type UpdateDispositionStatusRequest struct {
|
||||
LetterIncomingID uuid.UUID `json:"letter_incoming_id"`
|
||||
Status string `json:"status"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
}
|
||||
|
||||
type CreateLetterDiscussionRequest struct {
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
Message string `json:"message"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateLetterDiscussionRequest struct {
|
||||
Message string `json:"message"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
}
|
||||
|
||||
type LetterDiscussionResponse 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"`
|
||||
|
||||
// Preloaded user profile who created the discussion
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
|
||||
// Preloaded user profiles for mentions
|
||||
MentionedUsers []UserResponse `json:"mentioned_users,omitempty"`
|
||||
}
|
||||
|
||||
type GetLetterCTARequest struct {
|
||||
LetterIncomingID uuid.UUID `json:"letter_incoming_id"`
|
||||
}
|
||||
|
||||
type LetterCTAAction struct {
|
||||
Type string `json:"type"` // "create_disposition", "update_status", "view"
|
||||
Label string `json:"label"` // Human-readable label for the action
|
||||
Path string `json:"path"` // API endpoint path
|
||||
Method string `json:"method"` // HTTP method: GET, POST, PUT, etc.
|
||||
Description string `json:"description"` // Description of what this action does
|
||||
}
|
||||
|
||||
type LetterCTAResponse struct {
|
||||
LetterIncomingID uuid.UUID `json:"letter_incoming_id"`
|
||||
Actions []LetterCTAAction `json:"actions"`
|
||||
DispositionID *uuid.UUID `json:"disposition_id,omitempty"`
|
||||
CurrentStatus *string `json:"current_status,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type BulkArchiveLettersRequest struct {
|
||||
LetterIDs []uuid.UUID `json:"letter_ids" binding:"required,min=1"`
|
||||
}
|
||||
|
||||
type BulkArchiveLettersResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
ArchivedCount int `json:"archived_count"`
|
||||
}
|
||||
@@ -1,385 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type SearchOutgoingLettersRequest struct {
|
||||
Query string `json:"query" form:"query"`
|
||||
LetterNumber string `json:"letter_number" form:"letter_number"`
|
||||
Subject string `json:"subject" form:"subject"`
|
||||
Status string `json:"status" form:"status"`
|
||||
PriorityID *uuid.UUID `json:"priority_id" form:"priority_id"`
|
||||
InstitutionID *uuid.UUID `json:"institution_id" form:"institution_id"`
|
||||
CreatedBy *uuid.UUID `json:"created_by" form:"created_by"`
|
||||
DateFrom *time.Time `json:"date_from" form:"date_from"`
|
||||
DateTo *time.Time `json:"date_to" form:"date_to"`
|
||||
Page int `json:"page" form:"page"`
|
||||
Limit int `json:"limit" form:"limit"`
|
||||
SortBy string `json:"sort_by" form:"sort_by"`
|
||||
SortOrder string `json:"sort_order" form:"sort_order"`
|
||||
}
|
||||
|
||||
type SearchOutgoingLettersResponse struct {
|
||||
Letters []OutgoingLetterResponse `json:"letters"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
type CreateOutgoingLetterRecipient struct {
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
UserID *uuid.UUID `json:"user_id,omitempty"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
Status string `json:"status"`
|
||||
Flag *string `json:"flag,omitempty"`
|
||||
IsArchived bool `json:"is_archived"`
|
||||
}
|
||||
|
||||
type CreateOutgoingLetterAttachment struct {
|
||||
FileURL string `json:"file_url" validate:"required"`
|
||||
FileName string `json:"file_name" validate:"required"`
|
||||
FileType string `json:"file_type" validate:"required"`
|
||||
}
|
||||
|
||||
type CreateOutgoingLetterRequest struct {
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject string `json:"subject" validate:"required"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PriorityID *uuid.UUID `json:"priority_id,omitempty"`
|
||||
ReceiverInstitutionID *uuid.UUID `json:"receiver_institution_id,omitempty"`
|
||||
ReceiverName *string `json:"receiver_name,omitempty"`
|
||||
IssueDate time.Time `json:"issue_date" validate:"required"`
|
||||
Attachments []CreateOutgoingLetterAttachment `json:"attachments,omitempty"`
|
||||
UserID uuid.UUID
|
||||
ApprovalFlowID *uuid.UUID `json:"approval_flow_id,omitempty"`
|
||||
}
|
||||
|
||||
type OutgoingLetterRecipientResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterID uuid.UUID `json:"letter_id"`
|
||||
UserID *uuid.UUID `json:"user_id,omitempty"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
Status string `json:"status"`
|
||||
ReadAt *time.Time `json:"read_at,omitempty"`
|
||||
Flag *string `json:"flag,omitempty"`
|
||||
IsArchived bool `json:"is_archived"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
Department *DepartmentResponse `json:"department,omitempty"`
|
||||
}
|
||||
|
||||
type OutgoingLetterAttachmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
FileURL string `json:"file_url"`
|
||||
FileName string `json:"file_name"`
|
||||
FileType string `json:"file_type"`
|
||||
UploadedAt time.Time `json:"uploaded_at"`
|
||||
}
|
||||
|
||||
type OutgoingLetterApprovalResponse struct {
|
||||
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 {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LetterNumber string `json:"letter_number"`
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject string `json:"subject"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PriorityID *uuid.UUID `json:"priority_id,omitempty"`
|
||||
Priority *PriorityResponse `json:"priority,omitempty"`
|
||||
ReceiverInstitutionID *uuid.UUID `json:"receiver_institution_id,omitempty"`
|
||||
ReceiverInstitution *InstitutionResponse `json:"receiver_institution,omitempty"`
|
||||
ReceiverName *string `json:"receiver_name,omitempty"`
|
||||
IssueDate time.Time `json:"issue_date"`
|
||||
Status string `json:"status"`
|
||||
ApprovalFlowID *uuid.UUID `json:"approval_flow_id,omitempty"`
|
||||
RevisionNumber int `json:"revision_number"`
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedName string `json:"created_name"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
IsRead bool `json:"is_read"`
|
||||
Recipients []OutgoingLetterRecipientResponse `json:"recipients,omitempty"`
|
||||
Attachments []OutgoingLetterAttachmentResponse `json:"attachments,omitempty"`
|
||||
FinalAttachments []OutgoingLetterAttachmentResponse `json:"final_attachments,omitempty"`
|
||||
Approvals []OutgoingLetterApprovalResponse `json:"approvals,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateOutgoingLetterRequest struct {
|
||||
ReferenceNumber *string `json:"reference_number,omitempty"`
|
||||
Subject *string `json:"subject,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PriorityID *uuid.UUID `json:"priority_id,omitempty"`
|
||||
ReceiverInstitutionID *uuid.UUID `json:"receiver_institution_id,omitempty"`
|
||||
ReceiverName *string `json:"receiver_name,omitempty"`
|
||||
IssueDate *time.Time `json:"issue_date,omitempty"`
|
||||
}
|
||||
|
||||
type ListOutgoingLettersRequest struct {
|
||||
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"`
|
||||
PriorityIDs []uuid.UUID `json:"priority_ids,omitempty"`
|
||||
SortBy string `form:"sort_by" json:"sort_by,omitempty"`
|
||||
SortOrder string `form:"sort_order" json:"sort_order,omitempty"`
|
||||
IsArchived *bool `form:"is_archived" json:"is_archived,omitempty"`
|
||||
IsRead *bool `form:"is_read,omitempty"`
|
||||
}
|
||||
|
||||
type ListOutgoingLettersResponse struct {
|
||||
Items []*OutgoingLetterResponse `json:"items"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
type ApproveLetterRequest struct {
|
||||
Remarks *string `json:"remarks,omitempty"`
|
||||
}
|
||||
|
||||
type RejectLetterRequest struct {
|
||||
Reason string `json:"reason" validate:"required"`
|
||||
}
|
||||
|
||||
type ReviseLetterRequest struct {
|
||||
FileURL string `json:"file_url" validate:"required"`
|
||||
FileName string `json:"file_name" validate:"required"`
|
||||
FileType string `json:"file_type" validate:"required"`
|
||||
}
|
||||
|
||||
type AddRecipientsRequest struct {
|
||||
Recipients []CreateOutgoingLetterRecipient `json:"recipients" validate:"required,dive"`
|
||||
}
|
||||
|
||||
type UpdateRecipientRequest struct {
|
||||
UserID *uuid.UUID `json:"user_id,omitempty"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
Flag *string `json:"flag,omitempty"`
|
||||
IsArchived *bool `json:"is_archived,omitempty"`
|
||||
}
|
||||
|
||||
type AddAttachmentsRequest struct {
|
||||
Attachments []CreateOutgoingLetterAttachment `json:"attachments" validate:"required,dive"`
|
||||
}
|
||||
|
||||
type CreateDiscussionAttachment struct {
|
||||
FileURL string `json:"file_url" validate:"required"`
|
||||
FileName string `json:"file_name" validate:"required"`
|
||||
FileType string `json:"file_type" validate:"required"`
|
||||
}
|
||||
|
||||
type CreateDiscussionRequest struct {
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
Message string `json:"message" validate:"required"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
Attachments []CreateDiscussionAttachment `json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateDiscussionRequest struct {
|
||||
Message string `json:"message" validate:"required"`
|
||||
Mentions map[string]interface{} `json:"mentions,omitempty"`
|
||||
}
|
||||
|
||||
type DiscussionResponse struct {
|
||||
ID uuid.UUID `json:"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"`
|
||||
}
|
||||
|
||||
type ApprovalFlowRequest struct {
|
||||
DepartmentID uuid.UUID `json:"department_id" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
IsActive bool `json:"is_active"`
|
||||
Steps []ApprovalFlowStepRequest `json:"steps" validate:"required,dive"`
|
||||
}
|
||||
|
||||
type ApprovalFlowStepRequest struct {
|
||||
StepOrder int `json:"step_order" validate:"required,min=1"`
|
||||
ParallelGroup int `json:"parallel_group" validate:"min=1"`
|
||||
ApproverRoleID *uuid.UUID `json:"approver_role_id,omitempty"`
|
||||
ApproverUserID *uuid.UUID `json:"approver_user_id,omitempty"`
|
||||
Required bool `json:"required"`
|
||||
}
|
||||
|
||||
type ApprovalFlowResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
DepartmentID uuid.UUID `json:"department_id"`
|
||||
Department *DepartmentResponse `json:"department,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
IsActive bool `json:"is_active"`
|
||||
Steps []ApprovalFlowStepResponse `json:"steps,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ApprovalFlowStepResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
StepOrder int `json:"step_order"`
|
||||
ParallelGroup int `json:"parallel_group"`
|
||||
ApproverRoleID *uuid.UUID `json:"approver_role_id,omitempty"`
|
||||
ApproverRole *RoleResponse `json:"approver_role,omitempty"`
|
||||
ApproverUserID *uuid.UUID `json:"approver_user_id,omitempty"`
|
||||
ApproverUser *UserResponse `json:"approver_user,omitempty"`
|
||||
Required bool `json:"required"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ListApprovalFlowsRequest struct {
|
||||
Limit int `json:"limit"`
|
||||
Page int `json:"page"`
|
||||
Search *string `json:"search"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
}
|
||||
|
||||
type ListApprovalFlowsResponse struct {
|
||||
Items []*ApprovalFlowResponse `json:"items"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
// Letter Approval Information for Approver
|
||||
type LetterApprovalInfoResponse struct {
|
||||
IsApproverOnActiveStep bool `json:"is_approver_on_active_step"`
|
||||
DecisionStatus string `json:"decision_status"`
|
||||
CanApprove bool `json:"can_approve"`
|
||||
Actions []ApprovalAction `json:"actions"`
|
||||
NotesVisibility string `json:"notes_visibility"`
|
||||
}
|
||||
|
||||
type ApprovalAction struct {
|
||||
Type string `json:"type"`
|
||||
Href string `json:"href"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
// OutgoingLetterApprovalDiscussionsResponse combines approvals and discussions for outgoing letters
|
||||
type OutgoingLetterApprovalDiscussionsResponse struct {
|
||||
Approvals []EnhancedOutgoingLetterApprovalResponse `json:"approvals"`
|
||||
Discussions []OutgoingLetterDiscussionResponse `json:"discussions"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
StepOrder int `json:"step_order"`
|
||||
ParallelGroup int `json:"parallel_group"`
|
||||
IsRequired bool `json:"is_required"`
|
||||
ApproverID *uuid.UUID `json:"approver_id,omitempty"`
|
||||
RevisionNumber int `json:"revision_number"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type OutgoingLetterApprovalRevisionNumberResponse struct {
|
||||
RevisionNumber int `json:"revision_number"`
|
||||
Approvals []EnhancedOutgoingLetterApprovalResponse `json:"approvals"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
CurrentRevisionNumber int `json:"current_revision_number"`
|
||||
Approvals []OutgoingLetterApprovalRevisionNumberResponse `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"`
|
||||
}
|
||||
|
||||
// OutgoingLetterDiscussionAttachmentResponse represents an attachment in a discussion
|
||||
type OutgoingLetterDiscussionAttachmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
DiscussionID uuid.UUID `json:"discussion_id"`
|
||||
FileURL string `json:"file_url"`
|
||||
FileName string `json:"file_name"`
|
||||
FileType string `json:"file_type"`
|
||||
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"`
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package contract
|
||||
|
||||
import "github.com/google/uuid"
|
||||
|
||||
type TriggerNotificationRequest struct {
|
||||
UserID uuid.UUID `json:"user_id" validate:"required"`
|
||||
TemplateID string `json:"template_id" validate:"required"`
|
||||
TemplateData map[string]interface{} `json:"template_data,omitempty"`
|
||||
To *NotificationTo `json:"to,omitempty"`
|
||||
Overrides *NotificationOverrides `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationTo struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
SubscriberID string `json:"subscriber_id,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationOverrides struct {
|
||||
Email *EmailOverride `json:"email,omitempty"`
|
||||
SMS *SMSOverride `json:"sms,omitempty"`
|
||||
InApp *InAppOverride `json:"in_app,omitempty"`
|
||||
Push *PushOverride `json:"push,omitempty"`
|
||||
Chat *ChatOverride `json:"chat,omitempty"`
|
||||
}
|
||||
|
||||
type EmailOverride struct {
|
||||
Subject string `json:"subject,omitempty"`
|
||||
Body string `json:"body,omitempty"`
|
||||
From string `json:"from,omitempty"`
|
||||
}
|
||||
|
||||
type SMSOverride struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
From string `json:"from,omitempty"`
|
||||
}
|
||||
|
||||
type InAppOverride struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
type PushOverride struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
type ChatOverride struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
type TriggerNotificationResponse struct {
|
||||
Success bool `json:"success"`
|
||||
TransactionID string `json:"transaction_id,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type BulkTriggerNotificationRequest struct {
|
||||
TemplateID string `json:"template_id" validate:"required"`
|
||||
UserIDs []uuid.UUID `json:"user_ids" validate:"required,min=1"`
|
||||
TemplateData map[string]interface{} `json:"template_data,omitempty"`
|
||||
Overrides *NotificationOverrides `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
type BulkTriggerNotificationResponse struct {
|
||||
Success bool `json:"success"`
|
||||
TotalSent int `json:"total_sent"`
|
||||
TotalFailed int `json:"total_failed"`
|
||||
Results []NotificationResult `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationResult struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Success bool `json:"success"`
|
||||
TransactionID string `json:"transaction_id,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type GetSubscriberRequest struct {
|
||||
UserID uuid.UUID `json:"user_id" validate:"required"`
|
||||
}
|
||||
|
||||
type GetSubscriberResponse struct {
|
||||
SubscriberID string `json:"subscriber_id"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Avatar string `json:"avatar,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
Channels []ChannelCredentials `json:"channels,omitempty"`
|
||||
}
|
||||
|
||||
type ChannelCredentials struct {
|
||||
Channel string `json:"channel"`
|
||||
Credentials map[string]interface{} `json:"credentials"`
|
||||
}
|
||||
|
||||
type UpdateSubscriberChannelRequest struct {
|
||||
UserID uuid.UUID `json:"user_id" validate:"required"`
|
||||
Channel string `json:"channel" validate:"required,oneof=email sms push chat in_app"`
|
||||
Credentials map[string]interface{} `json:"credentials" validate:"required"`
|
||||
}
|
||||
|
||||
type UpdateSubscriberChannelResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// OnlyOffice callback status codes
|
||||
const (
|
||||
OnlyOfficeStatusEditing = 1 // Document is being edited
|
||||
OnlyOfficeStatusReady = 2 // Document is ready for saving
|
||||
OnlyOfficeStatusSaveError = 3 // Document saving error occurred
|
||||
OnlyOfficeStatusClosed = 4 // Document is closed with no changes
|
||||
OnlyOfficeStatusForceSave = 6 // Document is being edited, but saved forcefully
|
||||
OnlyOfficeStatusForceSaveError = 7 // Error during force save
|
||||
)
|
||||
|
||||
// OnlyOfficeCallbackRequest represents the callback payload from OnlyOffice Document Server
|
||||
type OnlyOfficeCallbackRequest struct {
|
||||
Key string `json:"key"` // Document identifier
|
||||
Status int `json:"status"` // Status code (1-7)
|
||||
URL string `json:"url,omitempty"` // Document URL when status is 2 or 6
|
||||
ChangesURL string `json:"changesurl,omitempty"` // URL to document changes
|
||||
History *OnlyOfficeHistory `json:"history,omitempty"`
|
||||
Users []string `json:"users,omitempty"` // Users currently editing
|
||||
Actions []OnlyOfficeAction `json:"actions,omitempty"` // User actions
|
||||
LastSave string `json:"lastsave,omitempty"` // Last save time
|
||||
NotModified bool `json:"notmodified,omitempty"` // Document not modified flag
|
||||
ForceSaveType int `json:"forcesavetype,omitempty"` // Force save type
|
||||
UserData string `json:"userdata,omitempty"` // Custom user data
|
||||
Token string `json:"token,omitempty"` // JWT token from OnlyOffice
|
||||
}
|
||||
|
||||
// OnlyOfficeHistory represents document history information
|
||||
type OnlyOfficeHistory struct {
|
||||
ServerVersion string `json:"serverVersion"`
|
||||
Changes []OnlyOfficeHistoryChange `json:"changes"`
|
||||
}
|
||||
|
||||
// OnlyOfficeHistoryChange represents a single change in history
|
||||
type OnlyOfficeHistoryChange struct {
|
||||
User OnlyOfficeUser `json:"user"`
|
||||
Created string `json:"created"`
|
||||
}
|
||||
|
||||
// OnlyOfficeUser represents user information in OnlyOffice
|
||||
type OnlyOfficeUser struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// OnlyOfficeAction represents user actions
|
||||
type OnlyOfficeAction struct {
|
||||
Type int `json:"type"` // Action type (0: user connected, 1: user disconnected)
|
||||
UserID string `json:"userid"` // User identifier
|
||||
User OnlyOfficeUser `json:"user"` // User information
|
||||
}
|
||||
|
||||
// OnlyOfficeCallbackResponse is the required response format for OnlyOffice
|
||||
type OnlyOfficeCallbackResponse struct {
|
||||
Error int `json:"error"` // 0 = success, 1 = document key not found, 2 = callback URL error, 3 = internal server error
|
||||
}
|
||||
|
||||
// OnlyOfficeDocument represents the document section of OnlyOffice config
|
||||
type OnlyOfficeDocument struct {
|
||||
FileType string `json:"fileType"` // Document file extension
|
||||
Key string `json:"key"` // Unique document identifier
|
||||
Title string `json:"title"` // Document title
|
||||
URL string `json:"url"` // Document URL
|
||||
Permissions *OnlyOfficePermissions `json:"permissions,omitempty"`
|
||||
Info *OnlyOfficeDocumentInfo `json:"info,omitempty"`
|
||||
}
|
||||
|
||||
// OnlyOfficeDocumentInfo represents additional document information
|
||||
type OnlyOfficeDocumentInfo struct {
|
||||
Owner string `json:"owner,omitempty"`
|
||||
Uploaded string `json:"uploaded,omitempty"`
|
||||
}
|
||||
|
||||
// OnlyOfficeConfigRequest represents the proper OnlyOffice configuration format
|
||||
type OnlyOfficeConfigRequest struct {
|
||||
Document *OnlyOfficeDocument `json:"document"`
|
||||
DocumentType string `json:"documentType"` // text, spreadsheet, presentation
|
||||
EditorConfig *OnlyOfficeEditorConfig `json:"editorConfig"`
|
||||
Type string `json:"type,omitempty"` // desktop, mobile, embedded
|
||||
Token string `json:"token,omitempty"` // JWT token for security
|
||||
Width string `json:"width,omitempty"`
|
||||
Height string `json:"height,omitempty"`
|
||||
}
|
||||
|
||||
// OnlyOfficeUserConfig represents user configuration for OnlyOffice
|
||||
type OnlyOfficeUserConfig struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// OnlyOfficePermissions represents document permissions
|
||||
type OnlyOfficePermissions struct {
|
||||
Comment bool `json:"comment"`
|
||||
Download bool `json:"download"`
|
||||
Edit bool `json:"edit"`
|
||||
FillForms bool `json:"fillForms"`
|
||||
ModifyContentControl bool `json:"modifyContentControl"`
|
||||
ModifyFilter bool `json:"modifyFilter"`
|
||||
Print bool `json:"print"`
|
||||
Review bool `json:"review"`
|
||||
}
|
||||
|
||||
// OnlyOfficeCustomization represents UI customization options
|
||||
type OnlyOfficeCustomization struct {
|
||||
Autosave bool `json:"autosave"`
|
||||
Comments bool `json:"comments"`
|
||||
CompactHeader bool `json:"compactHeader"`
|
||||
CompactToolbar bool `json:"compactToolbar"`
|
||||
ForceSave bool `json:"forcesave"`
|
||||
ShowReviewChanges bool `json:"showReviewChanges"`
|
||||
Zoom int `json:"zoom"`
|
||||
}
|
||||
|
||||
// OnlyOfficeEditorConfig represents editor configuration
|
||||
type OnlyOfficeEditorConfig struct {
|
||||
CallbackURL string `json:"callbackUrl"`
|
||||
Lang string `json:"lang"`
|
||||
Mode string `json:"mode"` // edit, view
|
||||
User *OnlyOfficeUserConfig `json:"user,omitempty"`
|
||||
Customization *OnlyOfficeCustomization `json:"customization,omitempty"`
|
||||
}
|
||||
|
||||
// Document session tracking for OnlyOffice
|
||||
type DocumentSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
DocumentID uuid.UUID `json:"document_id"`
|
||||
DocumentKey string `json:"document_key"` // OnlyOffice document key
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Status int `json:"status"` // Current OnlyOffice status
|
||||
IsLocked bool `json:"is_locked"` // Document lock status
|
||||
LockedBy *uuid.UUID `json:"locked_by,omitempty"`
|
||||
LockedAt *time.Time `json:"locked_at,omitempty"`
|
||||
LastSavedAt *time.Time `json:"last_saved_at,omitempty"`
|
||||
Version int `json:"version"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// DocumentVersion for tracking document versions
|
||||
type DocumentVersion struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
DocumentID uuid.UUID `json:"document_id"`
|
||||
Version int `json:"version"`
|
||||
FileURL string `json:"file_url"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
ChangesURL *string `json:"changes_url,omitempty"`
|
||||
SavedBy uuid.UUID `json:"saved_by"`
|
||||
SavedAt time.Time `json:"saved_at"`
|
||||
IsActive bool `json:"is_active"`
|
||||
Comments *string `json:"comments,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// GetEditorConfigRequest represents request to get OnlyOffice editor configuration
|
||||
type GetEditorConfigRequest struct {
|
||||
DocumentID uuid.UUID `json:"document_id"`
|
||||
DocumentType string `json:"document_type"` // letter_attachment, outgoing_attachment, etc.
|
||||
Mode string `json:"mode"` // edit, view
|
||||
}
|
||||
|
||||
// GetEditorConfigResponse represents OnlyOffice editor configuration response
|
||||
type GetEditorConfigResponse struct {
|
||||
DocumentServerURL string `json:"document_server_url"`
|
||||
Config *OnlyOfficeConfigRequest `json:"config"`
|
||||
}
|
||||
|
||||
// OnlyOfficeConfigInfo represents the OnlyOffice configuration information
|
||||
type OnlyOfficeConfigInfo struct {
|
||||
URL string `json:"url"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type PermissionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Code string `json:"code"`
|
||||
Action string `json:"action,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
type CreatePermissionRequest struct {
|
||||
Code string `json:"code"` // unique
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
type UpdatePermissionRequest struct {
|
||||
Code *string `json:"code,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
type ListPermissionsResponse struct {
|
||||
Permissions []PermissionResponse `json:"permissions"`
|
||||
}
|
||||
|
||||
type RoleWithPermissionsResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Permissions []PermissionResponse `json:"permissions"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CreateRoleRequest struct {
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PermissionCodes []string `json:"permission_codes,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateRoleRequest struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Code *string `json:"code,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
PermissionCodes *[]string `json:"permission_codes,omitempty"`
|
||||
}
|
||||
|
||||
type ListRolesResponse struct {
|
||||
Roles []RoleWithPermissionsResponse `json:"roles"`
|
||||
}
|
||||
|
||||
// Module contracts
|
||||
type ModuleResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type ModuleWithPermissionsResponse struct {
|
||||
Module ModuleResponse `json:"module"`
|
||||
Permissions []PermissionResponse `json:"permissions"`
|
||||
}
|
||||
|
||||
type PermissionsGroupedResponse struct {
|
||||
Data []ModuleWithPermissionsResponse `json:"data"`
|
||||
}
|
||||
|
||||
// New Role contracts for the required API
|
||||
type ModulePermissionInput struct {
|
||||
Module string `json:"module" binding:"required"`
|
||||
Actions []string `json:"actions" binding:"required"`
|
||||
}
|
||||
|
||||
type CreateOrUpdateRoleRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Permissions []ModulePermissionInput `json:"permissions" binding:"required"`
|
||||
}
|
||||
|
||||
type RoleDetailResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Permissions []RolePermissionModuleResponse `json:"permissions"`
|
||||
}
|
||||
|
||||
type RolePermissionModuleResponse struct {
|
||||
Module ModuleResponse `json:"module"`
|
||||
Actions []PermissionActionResponse `json:"actions"`
|
||||
}
|
||||
|
||||
type PermissionActionResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Action string `json:"action"`
|
||||
Code string `json:"code"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package contract
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CreateRepositoryAttachmentRequest struct {
|
||||
FileURL string `json:"file_url" validate:"required"`
|
||||
FileName string `json:"file_name" validate:"required"`
|
||||
FileType string `json:"file_type" validate:"required"`
|
||||
Category string `json:"category" validate:"required"`
|
||||
}
|
||||
|
||||
type RepositoryAttachmentsResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
FileURL string `json:"file_url"`
|
||||
FileName string `json:"file_name"`
|
||||
FileType string `json:"file_type"`
|
||||
Category string `json:"category"`
|
||||
UploadBy uuid.UUID `json:"upload_by"`
|
||||
UploadAt time.Time `json:"upload_at"`
|
||||
}
|
||||
|
||||
type ListRepositoryAttachmentsResponse struct {
|
||||
Attachments []RepositoryAttachmentsResponse `json:"attachments"`
|
||||
Pagination PaginationResponse `json:"pagination"`
|
||||
}
|
||||
|
||||
type ListRepositoryAttachmentsRequest struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
Search *string `json:"search,omitempty"`
|
||||
}
|
||||
@@ -7,20 +7,15 @@ import (
|
||||
)
|
||||
|
||||
type CreateUserRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=6"`
|
||||
RoleID *uuid.UUID `json:"role_id,omitempty" validate:"required"`
|
||||
DepartmentIDs []uuid.UUID `json:"department_ids,omitempty"`
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=6"`
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Email *string `json:"email,omitempty" validate:"omitempty,email"`
|
||||
Role *uuid.UUID `json:"role,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
Permissions *map[string]interface{} `json:"permissions,omitempty"`
|
||||
DepartmentIDs *[]uuid.UUID `json:"department_ids,omitempty"`
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Email *string `json:"email,omitempty" validate:"omitempty,email"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
}
|
||||
|
||||
type ChangePasswordRequest struct {
|
||||
@@ -28,169 +23,38 @@ type ChangePasswordRequest struct {
|
||||
NewPassword string `json:"new_password" validate:"required,min=6"`
|
||||
}
|
||||
|
||||
type ChangeUserPasswordRequest struct {
|
||||
NewPassword string `json:"new_password" validate:"required,min=6"`
|
||||
}
|
||||
|
||||
type UpdateUserOutletRequest struct {
|
||||
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
User UserResponse `json:"user"`
|
||||
Roles []RoleResponse `json:"roles"`
|
||||
Permissions []string `json:"permissions"`
|
||||
Departments []DepartmentResponse `json:"departments"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
User *UserResponse `json:"user"`
|
||||
}
|
||||
|
||||
type RefreshTokenRequest struct {
|
||||
RefreshToken string `json:"refresh_token" validate:"required"`
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
IsActive bool `json:"is_active"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Roles []RoleResponse `json:"roles,omitempty"`
|
||||
DepartmentResponse []DepartmentResponse `json:"department_response"`
|
||||
Profile *UserProfileResponse `json:"profile,omitempty"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
IsActive bool `json:"is_active"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type ListUsersRequest struct {
|
||||
Page int `json:"page" validate:"min=1"`
|
||||
Limit int `json:"limit" validate:"min=1,max=100"`
|
||||
Role *string `json:"role,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
Search *string `json:"search,omitempty"`
|
||||
RoleCode *string `json:"role_code,omitempty"`
|
||||
}
|
||||
|
||||
type ListUsersResponse struct {
|
||||
type PaginatedUserResponse struct {
|
||||
Users []UserResponse `json:"users"`
|
||||
Pagination PaginationResponse `json:"pagination"`
|
||||
}
|
||||
|
||||
type RoleResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type DepartmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type ListDepartmentsRequest struct {
|
||||
Search string `json:"search,omitempty" form:"search"`
|
||||
Page int `json:"page,omitempty" form:"page"`
|
||||
Limit int `json:"limit,omitempty" form:"limit"`
|
||||
}
|
||||
|
||||
type ListDepartmentsResponse struct {
|
||||
Departments []DepartmentResponse `json:"departments"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
type CreateDepartmentRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Code string `json:"code" validate:"required,min=1,max=50"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateDepartmentRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Code *string `json:"code,omitempty" validate:"omitempty,min=1,max=50"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
}
|
||||
|
||||
type GetDepartmentResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Path string `json:"path"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
ParentName *string `json:"parent_name,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type DepartmentNode struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Path string `json:"path"`
|
||||
Level int `json:"level"`
|
||||
Children []*DepartmentNode `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
type OrganizationalChartResponse struct {
|
||||
Chart []*DepartmentNode `json:"chart"`
|
||||
TotalNodes int `json:"total_nodes"`
|
||||
}
|
||||
|
||||
type UserProfileResponse struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
FullName string `json:"full_name"`
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
Phone *string `json:"phone,omitempty"`
|
||||
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||
JobTitle *string `json:"job_title,omitempty"`
|
||||
EmployeeNo *string `json:"employee_no,omitempty"`
|
||||
Bio *string `json:"bio,omitempty"`
|
||||
Timezone string `json:"timezone"`
|
||||
Locale string `json:"locale"`
|
||||
Preferences map[string]interface{} `json:"preferences"`
|
||||
NotificationPrefs map[string]interface{} `json:"notification_prefs"`
|
||||
LastSeenAt *time.Time `json:"last_seen_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Roles []RoleResponse `json:"roles"`
|
||||
}
|
||||
|
||||
type UpdateUserProfileRequest struct {
|
||||
FullName *string `json:"full_name,omitempty"`
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
Phone *string `json:"phone,omitempty"`
|
||||
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||
JobTitle *string `json:"job_title,omitempty"`
|
||||
EmployeeNo *string `json:"employee_no,omitempty"`
|
||||
Bio *string `json:"bio,omitempty"`
|
||||
Timezone *string `json:"timezone,omitempty"`
|
||||
Locale *string `json:"locale,omitempty"`
|
||||
Preferences *map[string]interface{} `json:"preferences,omitempty"`
|
||||
NotificationPrefs *map[string]interface{} `json:"notification_prefs,omitempty"`
|
||||
}
|
||||
|
||||
type TitleResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Code *string `json:"code,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
type ListTitlesResponse struct {
|
||||
Titles []TitleResponse `json:"titles"`
|
||||
}
|
||||
|
||||
// MentionUsersRequest represents the request for getting users for mention purposes
|
||||
type MentionUsersRequest struct {
|
||||
Search *string `json:"search,omitempty" form:"search"` // Optional search term for username
|
||||
Limit *int `json:"limit,omitempty" form:"limit"` // Optional limit, defaults to 50, max 100
|
||||
}
|
||||
|
||||
// MentionUsersResponse represents the response for getting users for mention purposes
|
||||
type MentionUsersResponse struct {
|
||||
Users []UserResponse `json:"users"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user