@titus-system/syncdesk 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +4 -1
- package/package.json +1 -1
- package/src/auth/hooks/useAuth.ts +64 -0
- package/src/auth/types/auth.ts +28 -2
- package/src/health/hooks/useHealth.ts +11 -5
- package/src/index.ts +1 -0
- package/src/permissions/hooks/usePermissions.ts +12 -9
- package/src/roles/hooks/useRoles.ts +30 -9
- package/src/ticket/hooks/useTickets.ts +77 -0
- package/src/ticket/index.ts +2 -0
- package/src/ticket/types/ticket.ts +88 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
### Deprecated
|
|
14
|
+
|
|
15
|
+
### Removed
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
|
|
21
|
+
### Dev Notes
|
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ npm install @titus-system/syncdesk
|
|
|
14
14
|
|
|
15
15
|
### Install locally
|
|
16
16
|
|
|
17
|
+
Alternatively, you can install locally bypassing the npm registry.
|
|
18
|
+
|
|
17
19
|
```sh
|
|
18
20
|
npm run build
|
|
19
21
|
npm pack
|
|
@@ -31,7 +33,8 @@ npm install /path/to/your/library-1.0.0.tgz
|
|
|
31
33
|
# You may have to login to npm registry first with `npm login`
|
|
32
34
|
npm login
|
|
33
35
|
|
|
34
|
-
npm run build
|
|
36
|
+
npm run build
|
|
37
|
+
npm publish --access public
|
|
35
38
|
```
|
|
36
39
|
|
|
37
40
|
---
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { apiClient, ApiResponse } from "../../api";
|
|
3
3
|
import {
|
|
4
|
+
AdminRegisterUserRequest,
|
|
5
|
+
ChangePasswordRequest,
|
|
6
|
+
ForgotPasswordRequest,
|
|
7
|
+
ForgotPasswordResponse,
|
|
4
8
|
LoginResponse,
|
|
5
9
|
RegisterUserRequest,
|
|
10
|
+
ResetPasswordRequest,
|
|
6
11
|
UserCreatedResponse,
|
|
7
12
|
UserLoginRequest,
|
|
8
13
|
UserWithRoles,
|
|
9
14
|
} from "../types/auth";
|
|
15
|
+
import { User } from "../../users/types/user";
|
|
10
16
|
|
|
11
17
|
const PATH = "auth";
|
|
12
18
|
|
|
@@ -93,3 +99,61 @@ export const useLogout = () => {
|
|
|
93
99
|
},
|
|
94
100
|
});
|
|
95
101
|
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Register a new user as admin.
|
|
105
|
+
*/
|
|
106
|
+
export const useAdminRegister = () => {
|
|
107
|
+
const queryClient = useQueryClient();
|
|
108
|
+
|
|
109
|
+
return useMutation({
|
|
110
|
+
mutationFn: async (userData: AdminRegisterUserRequest): Promise<User> => {
|
|
111
|
+
const response = await apiClient.post<ApiResponse<User>>(
|
|
112
|
+
`${PATH}/admin/register`,
|
|
113
|
+
userData,
|
|
114
|
+
);
|
|
115
|
+
return response.data.data;
|
|
116
|
+
},
|
|
117
|
+
onSuccess: () => {
|
|
118
|
+
queryClient.invalidateQueries({ queryKey: ["users"] });
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Change the password of the current user.
|
|
125
|
+
*/
|
|
126
|
+
export const useChangePassword = () => {
|
|
127
|
+
return useMutation({
|
|
128
|
+
mutationFn: async (data: ChangePasswordRequest): Promise<void> => {
|
|
129
|
+
await apiClient.post(`${PATH}/change-password`, data);
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Request a password reset email.
|
|
136
|
+
*/
|
|
137
|
+
export const useForgotPassword = () => {
|
|
138
|
+
return useMutation({
|
|
139
|
+
mutationFn: async (
|
|
140
|
+
data: ForgotPasswordRequest,
|
|
141
|
+
): Promise<ForgotPasswordResponse> => {
|
|
142
|
+
const response = await apiClient.post<
|
|
143
|
+
ApiResponse<ForgotPasswordResponse>
|
|
144
|
+
>(`${PATH}/forgot-password`, data);
|
|
145
|
+
return response.data.data;
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Reset a user's password using a valid reset token.
|
|
152
|
+
*/
|
|
153
|
+
export const useResetPassword = () => {
|
|
154
|
+
return useMutation({
|
|
155
|
+
mutationFn: async (data: ResetPasswordRequest): Promise<void> => {
|
|
156
|
+
await apiClient.post(`${PATH}/reset-password`, data);
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
};
|
package/src/auth/types/auth.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type OAuthProvider = "local" | "google" | "microsoft";
|
|
|
3
3
|
export interface LoginResponse {
|
|
4
4
|
access_token: string;
|
|
5
5
|
refresh_token: string;
|
|
6
|
+
must_change_password?: boolean;
|
|
7
|
+
must_accept_terms?: boolean;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export interface UserCreatedResponse {
|
|
@@ -20,11 +22,35 @@ export interface UserLoginRequest {
|
|
|
20
22
|
|
|
21
23
|
export interface RegisterUserRequest {
|
|
22
24
|
email: string;
|
|
23
|
-
name
|
|
24
|
-
username
|
|
25
|
+
name?: string;
|
|
26
|
+
username?: string;
|
|
25
27
|
password: string;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
export interface AdminRegisterUserRequest {
|
|
31
|
+
email: string;
|
|
32
|
+
name?: string | null;
|
|
33
|
+
role_ids?: number[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ChangePasswordRequest {
|
|
37
|
+
current_password: string;
|
|
38
|
+
new_password: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ForgotPasswordRequest {
|
|
42
|
+
email: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ResetPasswordRequest {
|
|
46
|
+
token: string;
|
|
47
|
+
new_password: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ForgotPasswordResponse {
|
|
51
|
+
message: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
28
54
|
// I am making a safe assumption for your /me route based on "user_with_roles"
|
|
29
55
|
export interface UserWithRoles {
|
|
30
56
|
id: string;
|
|
@@ -6,6 +6,8 @@ import type {
|
|
|
6
6
|
ReadyResponse,
|
|
7
7
|
} from "../types/health";
|
|
8
8
|
|
|
9
|
+
const PATH = "";
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Ping the server to check for basic connectivity.
|
|
11
13
|
*/
|
|
@@ -13,7 +15,9 @@ export const usePing = () => {
|
|
|
13
15
|
return useQuery({
|
|
14
16
|
queryKey: ["health", "ping"],
|
|
15
17
|
queryFn: async (): Promise<PingResponse> => {
|
|
16
|
-
const response = await apiClient.get<ApiResponse<PingResponse>>(
|
|
18
|
+
const response = await apiClient.get<ApiResponse<PingResponse>>(
|
|
19
|
+
`${PATH}/ping`,
|
|
20
|
+
);
|
|
17
21
|
return response.data.data;
|
|
18
22
|
},
|
|
19
23
|
});
|
|
@@ -26,8 +30,9 @@ export const useHealth = () => {
|
|
|
26
30
|
return useQuery({
|
|
27
31
|
queryKey: ["health", "status"],
|
|
28
32
|
queryFn: async (): Promise<HealthResponse> => {
|
|
29
|
-
const response =
|
|
30
|
-
|
|
33
|
+
const response = await apiClient.get<ApiResponse<HealthResponse>>(
|
|
34
|
+
`${PATH}/health`,
|
|
35
|
+
);
|
|
31
36
|
return response.data.data;
|
|
32
37
|
},
|
|
33
38
|
});
|
|
@@ -40,8 +45,9 @@ export const useReady = () => {
|
|
|
40
45
|
return useQuery({
|
|
41
46
|
queryKey: ["health", "ready"],
|
|
42
47
|
queryFn: async (): Promise<ReadyResponse> => {
|
|
43
|
-
const response =
|
|
44
|
-
|
|
48
|
+
const response = await apiClient.get<ApiResponse<ReadyResponse>>(
|
|
49
|
+
`${PATH}/ready`,
|
|
50
|
+
);
|
|
45
51
|
return response.data.data;
|
|
46
52
|
},
|
|
47
53
|
});
|
package/src/index.ts
CHANGED
|
@@ -9,12 +9,15 @@ import type {
|
|
|
9
9
|
AddPermissionRolesDTO,
|
|
10
10
|
} from "../types/permission";
|
|
11
11
|
|
|
12
|
+
const PATH = "/permissions";
|
|
13
|
+
|
|
12
14
|
export function usePermissions() {
|
|
13
15
|
return useQuery<Permission[]>({
|
|
14
16
|
queryKey: ["permissions"],
|
|
15
17
|
queryFn: async () => {
|
|
16
|
-
const response =
|
|
17
|
-
|
|
18
|
+
const response = await apiClient.get<ApiResponse<Permission[]>>(
|
|
19
|
+
`${PATH}/`,
|
|
20
|
+
);
|
|
18
21
|
return response.data.data;
|
|
19
22
|
},
|
|
20
23
|
});
|
|
@@ -25,7 +28,7 @@ export function usePermission(id: number) {
|
|
|
25
28
|
queryKey: ["permissions", id],
|
|
26
29
|
queryFn: async () => {
|
|
27
30
|
const response = await apiClient.get<ApiResponse<Permission>>(
|
|
28
|
-
|
|
31
|
+
`${PATH}/${id}`,
|
|
29
32
|
);
|
|
30
33
|
return response.data.data;
|
|
31
34
|
},
|
|
@@ -38,7 +41,7 @@ export function useCreatePermission() {
|
|
|
38
41
|
return useMutation<Permission, Error, CreatePermissionDTO>({
|
|
39
42
|
mutationFn: async (dto) => {
|
|
40
43
|
const response = await apiClient.post<ApiResponse<Permission>>(
|
|
41
|
-
|
|
44
|
+
`${PATH}/`,
|
|
42
45
|
dto,
|
|
43
46
|
);
|
|
44
47
|
return response.data.data;
|
|
@@ -58,7 +61,7 @@ export function useReplacePermission() {
|
|
|
58
61
|
>({
|
|
59
62
|
mutationFn: async ({ id, dto }) => {
|
|
60
63
|
const response = await apiClient.put<ApiResponse<Permission>>(
|
|
61
|
-
|
|
64
|
+
`${PATH}/${id}`,
|
|
62
65
|
dto,
|
|
63
66
|
);
|
|
64
67
|
return response.data.data;
|
|
@@ -79,7 +82,7 @@ export function useUpdatePermission() {
|
|
|
79
82
|
>({
|
|
80
83
|
mutationFn: async ({ id, dto }) => {
|
|
81
84
|
const response = await apiClient.patch<ApiResponse<Permission>>(
|
|
82
|
-
|
|
85
|
+
`${PATH}/${id}`,
|
|
83
86
|
dto,
|
|
84
87
|
);
|
|
85
88
|
return response.data.data;
|
|
@@ -96,7 +99,7 @@ export function useDeletePermission() {
|
|
|
96
99
|
return useMutation<Permission, Error, number>({
|
|
97
100
|
mutationFn: async (id) => {
|
|
98
101
|
const response = await apiClient.delete<ApiResponse<Permission>>(
|
|
99
|
-
|
|
102
|
+
`${PATH}/${id}`,
|
|
100
103
|
);
|
|
101
104
|
return response.data.data;
|
|
102
105
|
},
|
|
@@ -112,7 +115,7 @@ export function usePermissionRoles(id: number) {
|
|
|
112
115
|
queryKey: ["permissions", id, "roles"],
|
|
113
116
|
queryFn: async () => {
|
|
114
117
|
const response = await apiClient.get<ApiResponse<Permission>>(
|
|
115
|
-
|
|
118
|
+
`${PATH}/${id}/roles`,
|
|
116
119
|
);
|
|
117
120
|
return response.data.data;
|
|
118
121
|
},
|
|
@@ -129,7 +132,7 @@ export function useAddPermissionRoles() {
|
|
|
129
132
|
>({
|
|
130
133
|
mutationFn: async ({ id, dto }) => {
|
|
131
134
|
const response = await apiClient.post<ApiResponse<Permission>>(
|
|
132
|
-
|
|
135
|
+
`${PATH}/${id}/roles`,
|
|
133
136
|
dto,
|
|
134
137
|
);
|
|
135
138
|
return response.data.data;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { apiClient, ApiResponse } from "../../api";
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
Role,
|
|
5
|
+
CreateRoleDTO,
|
|
6
|
+
ReplaceRoleDTO,
|
|
7
|
+
UpdateRoleDTO,
|
|
8
|
+
AddRolePermissionsDTO,
|
|
9
|
+
} from "../types/role";
|
|
10
|
+
|
|
11
|
+
const PATH = "/roles";
|
|
4
12
|
|
|
5
13
|
export function useRoles() {
|
|
6
14
|
return useQuery<Role[]>({
|
|
7
15
|
queryKey: ["roles"],
|
|
8
16
|
queryFn: async () => {
|
|
9
|
-
const response = await apiClient.get<ApiResponse<Role[]>>(
|
|
17
|
+
const response = await apiClient.get<ApiResponse<Role[]>>(`${PATH}/`);
|
|
10
18
|
return response.data.data;
|
|
11
19
|
},
|
|
12
20
|
});
|
|
@@ -16,7 +24,7 @@ export function useRole(id: number) {
|
|
|
16
24
|
return useQuery<Role>({
|
|
17
25
|
queryKey: ["roles", id],
|
|
18
26
|
queryFn: async () => {
|
|
19
|
-
const response = await apiClient.get<ApiResponse<Role>>(
|
|
27
|
+
const response = await apiClient.get<ApiResponse<Role>>(`${PATH}/${id}`);
|
|
20
28
|
return response.data.data;
|
|
21
29
|
},
|
|
22
30
|
enabled: !!id,
|
|
@@ -27,7 +35,7 @@ export function useCreateRole() {
|
|
|
27
35
|
const queryClient = useQueryClient();
|
|
28
36
|
return useMutation<Role, Error, CreateRoleDTO>({
|
|
29
37
|
mutationFn: async (dto) => {
|
|
30
|
-
const response = await apiClient.post<ApiResponse<Role>>(
|
|
38
|
+
const response = await apiClient.post<ApiResponse<Role>>(`${PATH}/`, dto);
|
|
31
39
|
return response.data.data;
|
|
32
40
|
},
|
|
33
41
|
onSuccess: () => {
|
|
@@ -40,7 +48,10 @@ export function useReplaceRole() {
|
|
|
40
48
|
const queryClient = useQueryClient();
|
|
41
49
|
return useMutation<Role, Error, { id: number; dto: ReplaceRoleDTO }>({
|
|
42
50
|
mutationFn: async ({ id, dto }) => {
|
|
43
|
-
const response = await apiClient.put<ApiResponse<Role>>(
|
|
51
|
+
const response = await apiClient.put<ApiResponse<Role>>(
|
|
52
|
+
`${PATH}/${id}`,
|
|
53
|
+
dto,
|
|
54
|
+
);
|
|
44
55
|
return response.data.data;
|
|
45
56
|
},
|
|
46
57
|
onSuccess: (_, { id }) => {
|
|
@@ -54,7 +65,10 @@ export function useUpdateRole() {
|
|
|
54
65
|
const queryClient = useQueryClient();
|
|
55
66
|
return useMutation<Role, Error, { id: number; dto: UpdateRoleDTO }>({
|
|
56
67
|
mutationFn: async ({ id, dto }) => {
|
|
57
|
-
const response = await apiClient.patch<ApiResponse<Role>>(
|
|
68
|
+
const response = await apiClient.patch<ApiResponse<Role>>(
|
|
69
|
+
`${PATH}/${id}`,
|
|
70
|
+
dto,
|
|
71
|
+
);
|
|
58
72
|
return response.data.data;
|
|
59
73
|
},
|
|
60
74
|
onSuccess: (_, { id }) => {
|
|
@@ -68,7 +82,9 @@ export function useDeleteRole() {
|
|
|
68
82
|
const queryClient = useQueryClient();
|
|
69
83
|
return useMutation<Role, Error, number>({
|
|
70
84
|
mutationFn: async (id) => {
|
|
71
|
-
const response = await apiClient.delete<ApiResponse<Role>>(
|
|
85
|
+
const response = await apiClient.delete<ApiResponse<Role>>(
|
|
86
|
+
`${PATH}/${id}`,
|
|
87
|
+
);
|
|
72
88
|
return response.data.data;
|
|
73
89
|
},
|
|
74
90
|
onSuccess: (_, id) => {
|
|
@@ -82,7 +98,9 @@ export function useRolePermissions(id: number) {
|
|
|
82
98
|
return useQuery<Role>({
|
|
83
99
|
queryKey: ["roles", id, "permissions"],
|
|
84
100
|
queryFn: async () => {
|
|
85
|
-
const response = await apiClient.get<ApiResponse<Role>>(
|
|
101
|
+
const response = await apiClient.get<ApiResponse<Role>>(
|
|
102
|
+
`${PATH}/${id}/permissions`,
|
|
103
|
+
);
|
|
86
104
|
return response.data.data;
|
|
87
105
|
},
|
|
88
106
|
enabled: !!id,
|
|
@@ -93,7 +111,10 @@ export function useAddRolePermissions() {
|
|
|
93
111
|
const queryClient = useQueryClient();
|
|
94
112
|
return useMutation<Role, Error, { id: number; dto: AddRolePermissionsDTO }>({
|
|
95
113
|
mutationFn: async ({ id, dto }) => {
|
|
96
|
-
const response = await apiClient.post<ApiResponse<Role>>(
|
|
114
|
+
const response = await apiClient.post<ApiResponse<Role>>(
|
|
115
|
+
`${PATH}/${id}/permissions`,
|
|
116
|
+
dto,
|
|
117
|
+
);
|
|
97
118
|
return response.data.data;
|
|
98
119
|
},
|
|
99
120
|
onSuccess: (_, { id }) => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { apiClient, ApiResponse } from "../../api";
|
|
3
|
+
import {
|
|
4
|
+
CreateTicketRequest,
|
|
5
|
+
CreateTicketResponse,
|
|
6
|
+
TicketResponse,
|
|
7
|
+
TicketSearchFilters,
|
|
8
|
+
UpdateTicketStatusRequest,
|
|
9
|
+
UpdateTicketStatusResponse,
|
|
10
|
+
} from "../types/ticket";
|
|
11
|
+
|
|
12
|
+
const PATH = "/tickets";
|
|
13
|
+
|
|
14
|
+
// Query keys
|
|
15
|
+
export const TICKET_KEYS = {
|
|
16
|
+
all: ["tickets"] as const,
|
|
17
|
+
list: (filters: TicketSearchFilters) =>
|
|
18
|
+
[...TICKET_KEYS.all, "list", filters] as const,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Get all tickets. */
|
|
22
|
+
export const useTickets = (filters: TicketSearchFilters = {}) => {
|
|
23
|
+
return useQuery({
|
|
24
|
+
queryKey: TICKET_KEYS.list(filters),
|
|
25
|
+
queryFn: async (): Promise<TicketResponse[]> => {
|
|
26
|
+
const response = await apiClient.get<ApiResponse<TicketResponse[]>>(
|
|
27
|
+
`${PATH}/`,
|
|
28
|
+
{ params: filters },
|
|
29
|
+
);
|
|
30
|
+
return response.data.data;
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Create a new ticket. */
|
|
36
|
+
export const useCreateTicket = () => {
|
|
37
|
+
const queryClient = useQueryClient();
|
|
38
|
+
|
|
39
|
+
return useMutation({
|
|
40
|
+
mutationFn: async (
|
|
41
|
+
payload: CreateTicketRequest,
|
|
42
|
+
): Promise<CreateTicketResponse> => {
|
|
43
|
+
const response = await apiClient.post<ApiResponse<CreateTicketResponse>>(
|
|
44
|
+
`${PATH}/`,
|
|
45
|
+
payload,
|
|
46
|
+
);
|
|
47
|
+
return response.data.data;
|
|
48
|
+
},
|
|
49
|
+
onSuccess: () => {
|
|
50
|
+
// Invalidate tickets list queries on success
|
|
51
|
+
queryClient.invalidateQueries({ queryKey: TICKET_KEYS.all });
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Update a ticket's status. */
|
|
57
|
+
export const useUpdateTicketStatus = () => {
|
|
58
|
+
const queryClient = useQueryClient();
|
|
59
|
+
|
|
60
|
+
return useMutation({
|
|
61
|
+
mutationFn: async ({
|
|
62
|
+
ticketId,
|
|
63
|
+
payload,
|
|
64
|
+
}: {
|
|
65
|
+
ticketId: string;
|
|
66
|
+
payload: UpdateTicketStatusRequest;
|
|
67
|
+
}): Promise<UpdateTicketStatusResponse> => {
|
|
68
|
+
const response = await apiClient.patch<
|
|
69
|
+
ApiResponse<UpdateTicketStatusResponse>
|
|
70
|
+
>(`${PATH}/${ticketId}/status`, payload);
|
|
71
|
+
return response.data.data;
|
|
72
|
+
},
|
|
73
|
+
onSuccess: () => {
|
|
74
|
+
queryClient.invalidateQueries({ queryKey: TICKET_KEYS.all });
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type TicketType = "issue" | "access" | "new_feature";
|
|
2
|
+
export type TicketCriticality = "high" | "medium" | "low";
|
|
3
|
+
export type TicketStatus =
|
|
4
|
+
| "open"
|
|
5
|
+
| "in_progress"
|
|
6
|
+
| "waiting_for_provider"
|
|
7
|
+
| "waiting_for_validation"
|
|
8
|
+
| "finished";
|
|
9
|
+
|
|
10
|
+
export interface CreateTicketRequest {
|
|
11
|
+
triage_id: string; // PydanticObjectId as string
|
|
12
|
+
type: TicketType;
|
|
13
|
+
criticality: TicketCriticality;
|
|
14
|
+
product: string;
|
|
15
|
+
description: string;
|
|
16
|
+
chat_ids: string[]; // List of PydanticObjectId as string
|
|
17
|
+
client_id: string; // UUID as string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CreateTicketResponse {
|
|
21
|
+
id: string;
|
|
22
|
+
status: TicketStatus;
|
|
23
|
+
creation_date: string; // ISO datetime
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TicketSearchFilters {
|
|
27
|
+
ticket_id?: string;
|
|
28
|
+
client_id?: string;
|
|
29
|
+
triage_id?: string;
|
|
30
|
+
status?: TicketStatus;
|
|
31
|
+
criticality?: TicketCriticality;
|
|
32
|
+
type?: TicketType;
|
|
33
|
+
product?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface TicketCompanyResponse {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TicketClientResponse {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
email: string;
|
|
45
|
+
company: TicketCompanyResponse;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface TicketHistoryResponse {
|
|
49
|
+
agent_id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
level: string;
|
|
52
|
+
assignment_date: string;
|
|
53
|
+
exit_date: string;
|
|
54
|
+
transfer_reason: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface TicketCommentResponse {
|
|
58
|
+
comment_id: string;
|
|
59
|
+
author: string;
|
|
60
|
+
text: string;
|
|
61
|
+
date: string;
|
|
62
|
+
internal: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TicketResponse {
|
|
66
|
+
id: string;
|
|
67
|
+
triage_id: string;
|
|
68
|
+
type: TicketType;
|
|
69
|
+
criticality: TicketCriticality;
|
|
70
|
+
product: string;
|
|
71
|
+
status: TicketStatus;
|
|
72
|
+
creation_date: string;
|
|
73
|
+
description: string;
|
|
74
|
+
chat_ids: string[];
|
|
75
|
+
agent_history: TicketHistoryResponse[];
|
|
76
|
+
client: TicketClientResponse;
|
|
77
|
+
comments: TicketCommentResponse[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface UpdateTicketStatusRequest {
|
|
81
|
+
status: TicketStatus;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface UpdateTicketStatusResponse {
|
|
85
|
+
id: string;
|
|
86
|
+
previous_status: TicketStatus;
|
|
87
|
+
current_status: TicketStatus;
|
|
88
|
+
}
|