@goplusvn/core 0.1.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/dist/audit/index.d.mts +115 -0
- package/dist/audit/index.d.ts +115 -0
- package/dist/audit/index.js +204 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/index.mjs +200 -0
- package/dist/audit/index.mjs.map +1 -0
- package/dist/auth/index.d.mts +86 -0
- package/dist/auth/index.d.ts +86 -0
- package/dist/auth/index.js +210 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +198 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/button-1dWvP9Ib.d.mts +30 -0
- package/dist/button-1dWvP9Ib.d.ts +30 -0
- package/dist/calendar-2QzdEo1z.d.mts +20 -0
- package/dist/calendar-2QzdEo1z.d.ts +20 -0
- package/dist/code-generation/index.d.mts +30 -0
- package/dist/code-generation/index.d.ts +30 -0
- package/dist/code-generation/index.js +31 -0
- package/dist/code-generation/index.js.map +1 -0
- package/dist/code-generation/index.mjs +28 -0
- package/dist/code-generation/index.mjs.map +1 -0
- package/dist/configs/index.d.mts +175 -0
- package/dist/configs/index.d.ts +175 -0
- package/dist/configs/index.js +254 -0
- package/dist/configs/index.js.map +1 -0
- package/dist/configs/index.mjs +233 -0
- package/dist/configs/index.mjs.map +1 -0
- package/dist/crud/index.d.mts +646 -0
- package/dist/crud/index.d.ts +646 -0
- package/dist/crud/index.js +11772 -0
- package/dist/crud/index.js.map +1 -0
- package/dist/crud/index.mjs +11665 -0
- package/dist/crud/index.mjs.map +1 -0
- package/dist/crud/server.d.mts +20 -0
- package/dist/crud/server.d.ts +20 -0
- package/dist/crud/server.js +123 -0
- package/dist/crud/server.js.map +1 -0
- package/dist/crud/server.mjs +120 -0
- package/dist/crud/server.mjs.map +1 -0
- package/dist/data-table-skeleton-12NA8Mjx.d.mts +39 -0
- package/dist/data-table-skeleton-12NA8Mjx.d.ts +39 -0
- package/dist/dialog-bKfjZMTd.d.mts +22 -0
- package/dist/dialog-bKfjZMTd.d.ts +22 -0
- package/dist/dynamic-icon-DrGIiu2N.d.mts +10 -0
- package/dist/dynamic-icon-DrGIiu2N.d.ts +10 -0
- package/dist/home/index.d.mts +269 -0
- package/dist/home/index.d.ts +269 -0
- package/dist/home/index.js +1678 -0
- package/dist/home/index.js.map +1 -0
- package/dist/home/index.mjs +1635 -0
- package/dist/home/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +7 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.js +8316 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +8255 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index-50hpiPrV.d.ts +116 -0
- package/dist/index-B9zQVEVi.d.mts +116 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +118 -0
- package/dist/index.mjs.map +1 -0
- package/dist/infrastructure/index.d.mts +423 -0
- package/dist/infrastructure/index.d.ts +423 -0
- package/dist/infrastructure/index.js +633 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/infrastructure/index.mjs +619 -0
- package/dist/infrastructure/index.mjs.map +1 -0
- package/dist/label-DWTEkNPo.d.ts +226 -0
- package/dist/label-LPpdcoBx.d.mts +226 -0
- package/dist/layout/index.d.mts +48 -0
- package/dist/layout/index.d.ts +48 -0
- package/dist/layout/index.js +117 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/index.mjs +90 -0
- package/dist/layout/index.mjs.map +1 -0
- package/dist/navigation/index.d.mts +16 -0
- package/dist/navigation/index.d.ts +16 -0
- package/dist/navigation/index.js +53 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/index.mjs +50 -0
- package/dist/navigation/index.mjs.map +1 -0
- package/dist/notification/index.d.mts +105 -0
- package/dist/notification/index.d.ts +105 -0
- package/dist/notification/index.js +278 -0
- package/dist/notification/index.js.map +1 -0
- package/dist/notification/index.mjs +274 -0
- package/dist/notification/index.mjs.map +1 -0
- package/dist/organization/index.d.mts +99 -0
- package/dist/organization/index.d.ts +99 -0
- package/dist/organization/index.js +360 -0
- package/dist/organization/index.js.map +1 -0
- package/dist/organization/index.mjs +352 -0
- package/dist/organization/index.mjs.map +1 -0
- package/dist/plugin/index.d.mts +83 -0
- package/dist/plugin/index.d.ts +83 -0
- package/dist/plugin/index.js +86 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/index.mjs +84 -0
- package/dist/plugin/index.mjs.map +1 -0
- package/dist/providers/index.d.mts +25 -0
- package/dist/providers/index.d.ts +25 -0
- package/dist/providers/index.js +84 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/index.mjs +77 -0
- package/dist/providers/index.mjs.map +1 -0
- package/dist/rbac/index.d.mts +226 -0
- package/dist/rbac/index.d.ts +226 -0
- package/dist/rbac/index.js +4784 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/index.mjs +4722 -0
- package/dist/rbac/index.mjs.map +1 -0
- package/dist/rbac/permissions.d.mts +26 -0
- package/dist/rbac/permissions.d.ts +26 -0
- package/dist/rbac/permissions.js +94 -0
- package/dist/rbac/permissions.js.map +1 -0
- package/dist/rbac/permissions.mjs +90 -0
- package/dist/rbac/permissions.mjs.map +1 -0
- package/dist/rbac/server.d.mts +1 -0
- package/dist/rbac/server.d.ts +1 -0
- package/dist/rbac/server.js +128 -0
- package/dist/rbac/server.js.map +1 -0
- package/dist/rbac/server.mjs +124 -0
- package/dist/rbac/server.mjs.map +1 -0
- package/dist/schemas/index.d.mts +1257 -0
- package/dist/schemas/index.d.ts +1257 -0
- package/dist/schemas/index.js +572 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/index.mjs +523 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/server-QuYCTa89.d.mts +83 -0
- package/dist/server-QuYCTa89.d.ts +83 -0
- package/dist/sonner-C74GlRDQ.d.mts +71 -0
- package/dist/sonner-C74GlRDQ.d.ts +71 -0
- package/dist/status-BOXZgIqX.d.mts +12 -0
- package/dist/status-BOXZgIqX.d.ts +12 -0
- package/dist/system/index.d.mts +77 -0
- package/dist/system/index.d.ts +77 -0
- package/dist/system/index.js +102 -0
- package/dist/system/index.js.map +1 -0
- package/dist/system/index.mjs +100 -0
- package/dist/system/index.mjs.map +1 -0
- package/dist/tabs-C6FfBwPY.d.mts +18 -0
- package/dist/tabs-C6FfBwPY.d.ts +18 -0
- package/dist/tenant-provider-B8eC_Wpb.d.mts +27 -0
- package/dist/tenant-provider-B8eC_Wpb.d.ts +27 -0
- package/dist/types/index.d.mts +469 -0
- package/dist/types/index.d.ts +469 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +21 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/ui/auth.d.mts +39 -0
- package/dist/ui/auth.d.ts +39 -0
- package/dist/ui/auth.js +4941 -0
- package/dist/ui/auth.js.map +1 -0
- package/dist/ui/auth.mjs +4896 -0
- package/dist/ui/auth.mjs.map +1 -0
- package/dist/ui/crud.d.mts +2 -0
- package/dist/ui/crud.d.ts +2 -0
- package/dist/ui/crud.js +4 -0
- package/dist/ui/crud.js.map +1 -0
- package/dist/ui/crud.mjs +3 -0
- package/dist/ui/crud.mjs.map +1 -0
- package/dist/ui/data-display.d.mts +596 -0
- package/dist/ui/data-display.d.ts +596 -0
- package/dist/ui/data-display.js +5307 -0
- package/dist/ui/data-display.js.map +1 -0
- package/dist/ui/data-display.mjs +5212 -0
- package/dist/ui/data-display.mjs.map +1 -0
- package/dist/ui/feedback.d.mts +55 -0
- package/dist/ui/feedback.d.ts +55 -0
- package/dist/ui/feedback.js +2608 -0
- package/dist/ui/feedback.js.map +1 -0
- package/dist/ui/feedback.mjs +2526 -0
- package/dist/ui/feedback.mjs.map +1 -0
- package/dist/ui/forms.d.mts +309 -0
- package/dist/ui/forms.d.ts +309 -0
- package/dist/ui/forms.js +4656 -0
- package/dist/ui/forms.js.map +1 -0
- package/dist/ui/forms.mjs +4571 -0
- package/dist/ui/forms.mjs.map +1 -0
- package/dist/ui/index.d.mts +331 -0
- package/dist/ui/index.d.ts +331 -0
- package/dist/ui/index.js +16953 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/index.mjs +16598 -0
- package/dist/ui/index.mjs.map +1 -0
- package/dist/ui/primitives/client.d.mts +61 -0
- package/dist/ui/primitives/client.d.ts +61 -0
- package/dist/ui/primitives/client.js +3408 -0
- package/dist/ui/primitives/client.js.map +1 -0
- package/dist/ui/primitives/client.mjs +3256 -0
- package/dist/ui/primitives/client.mjs.map +1 -0
- package/dist/ui/primitives.d.mts +113 -0
- package/dist/ui/primitives.d.ts +113 -0
- package/dist/ui/primitives.js +3356 -0
- package/dist/ui/primitives.js.map +1 -0
- package/dist/ui/primitives.mjs +3227 -0
- package/dist/ui/primitives.mjs.map +1 -0
- package/dist/user/index.d.mts +228 -0
- package/dist/user/index.d.ts +228 -0
- package/dist/user/index.js +4306 -0
- package/dist/user/index.js.map +1 -0
- package/dist/user/index.mjs +4260 -0
- package/dist/user/index.mjs.map +1 -0
- package/dist/utils/index.d.mts +205 -0
- package/dist/utils/index.d.ts +205 -0
- package/dist/utils/index.js +574 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +514 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/workflow/index.d.mts +40 -0
- package/dist/workflow/index.d.ts +40 -0
- package/dist/workflow/index.js +3710 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/index.mjs +3677 -0
- package/dist/workflow/index.mjs.map +1 -0
- package/package.json +311 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lucideReact = require('lucide-react');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
// src/organization/branches.config.ts
|
|
7
|
+
|
|
8
|
+
// src/configs/status.ts
|
|
9
|
+
var STATUS_ACTIVE = "active";
|
|
10
|
+
var STATUS_INACTIVE = "inactive";
|
|
11
|
+
var STATUS_OPTIONS = [
|
|
12
|
+
{ label: "crud.common.options.active", value: STATUS_ACTIVE },
|
|
13
|
+
{ label: "crud.common.options.inactive", value: STATUS_INACTIVE }
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
// src/organization/branches.config.ts
|
|
17
|
+
var branchesConfig = {
|
|
18
|
+
name: "branch",
|
|
19
|
+
permissionResource: "branch",
|
|
20
|
+
label: "Chi nh\xE1nh",
|
|
21
|
+
pluralLabel: "Danh s\xE1ch chi nh\xE1nh",
|
|
22
|
+
icon: lucideReact.GitBranch,
|
|
23
|
+
description: "Qu\u1EA3n l\xFD danh s\xE1ch chi nh\xE1nh",
|
|
24
|
+
apiEndpoint: "/api/branches",
|
|
25
|
+
idField: "id",
|
|
26
|
+
displayField: "name",
|
|
27
|
+
fields: [
|
|
28
|
+
{
|
|
29
|
+
name: "id",
|
|
30
|
+
label: "ID",
|
|
31
|
+
type: "text",
|
|
32
|
+
hideInForm: true,
|
|
33
|
+
hideInTable: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "companyId",
|
|
37
|
+
label: "C\xF4ng ty",
|
|
38
|
+
type: "select",
|
|
39
|
+
required: true,
|
|
40
|
+
placeholder: "Ch\u1ECDn c\xF4ng ty",
|
|
41
|
+
filterable: true,
|
|
42
|
+
dataSource: {
|
|
43
|
+
type: "api",
|
|
44
|
+
endpoint: "/api/companies",
|
|
45
|
+
labelField: "name",
|
|
46
|
+
valueField: "id"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "code",
|
|
51
|
+
label: "M\xE3 chi nh\xE1nh",
|
|
52
|
+
type: "text",
|
|
53
|
+
required: true,
|
|
54
|
+
placeholder: "Nh\u1EADp m\xE3 chi nh\xE1nh",
|
|
55
|
+
filterable: true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "name",
|
|
59
|
+
label: "T\xEAn chi nh\xE1nh",
|
|
60
|
+
type: "text",
|
|
61
|
+
required: true,
|
|
62
|
+
placeholder: "Nh\u1EADp t\xEAn chi nh\xE1nh",
|
|
63
|
+
filterable: true
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "address",
|
|
67
|
+
label: "\u0110\u1ECBa ch\u1EC9",
|
|
68
|
+
type: "textarea",
|
|
69
|
+
required: false,
|
|
70
|
+
placeholder: "Nh\u1EADp \u0111\u1ECBa ch\u1EC9",
|
|
71
|
+
rows: 2
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "phone",
|
|
75
|
+
label: "S\u1ED1 \u0111i\u1EC7n tho\u1EA1i",
|
|
76
|
+
type: "text",
|
|
77
|
+
required: false,
|
|
78
|
+
placeholder: "Nh\u1EADp s\u1ED1 \u0111i\u1EC7n tho\u1EA1i"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "email",
|
|
82
|
+
label: "Email",
|
|
83
|
+
type: "email",
|
|
84
|
+
required: false,
|
|
85
|
+
placeholder: "Nh\u1EADp email"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "status",
|
|
89
|
+
label: "Tr\u1EA1ng th\xE1i",
|
|
90
|
+
type: "switch",
|
|
91
|
+
required: true,
|
|
92
|
+
defaultValue: "active",
|
|
93
|
+
filterable: true,
|
|
94
|
+
options: STATUS_OPTIONS
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "createdAt",
|
|
98
|
+
label: "Ng\xE0y t\u1EA1o",
|
|
99
|
+
type: "datetime",
|
|
100
|
+
hideInForm: true,
|
|
101
|
+
renderCell: (value) => {
|
|
102
|
+
return new Date(value).toLocaleDateString("vi-VN");
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "updatedAt",
|
|
107
|
+
label: "Ng\xE0y c\u1EADp nh\u1EADt",
|
|
108
|
+
type: "datetime",
|
|
109
|
+
hideInForm: true,
|
|
110
|
+
hideInTable: true
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
filters: [
|
|
114
|
+
{
|
|
115
|
+
name: "search",
|
|
116
|
+
label: "T\xECm ki\u1EBFm",
|
|
117
|
+
type: "text",
|
|
118
|
+
field: "name",
|
|
119
|
+
operator: "contains"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "companyId",
|
|
123
|
+
label: "C\xF4ng ty",
|
|
124
|
+
type: "select",
|
|
125
|
+
field: "companyId",
|
|
126
|
+
operator: "eq",
|
|
127
|
+
dataSource: {
|
|
128
|
+
type: "api",
|
|
129
|
+
endpoint: "/api/companies",
|
|
130
|
+
labelField: "name",
|
|
131
|
+
valueField: "id"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "status",
|
|
136
|
+
label: "Tr\u1EA1ng th\xE1i",
|
|
137
|
+
type: "checkbox",
|
|
138
|
+
field: "status",
|
|
139
|
+
operator: "in",
|
|
140
|
+
options: [
|
|
141
|
+
{ label: "Ho\u1EA1t \u0111\u1ED9ng", value: "active" },
|
|
142
|
+
{ label: "Ng\u1EEBng ho\u1EA1t \u0111\u1ED9ng", value: "inactive" }
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
permissions: {
|
|
147
|
+
create: true,
|
|
148
|
+
read: true,
|
|
149
|
+
update: true,
|
|
150
|
+
delete: true,
|
|
151
|
+
export: true,
|
|
152
|
+
import: false
|
|
153
|
+
},
|
|
154
|
+
features: {
|
|
155
|
+
search: true,
|
|
156
|
+
bulkActions: true,
|
|
157
|
+
export: true,
|
|
158
|
+
import: false
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
var branchSchema = zod.z.object({
|
|
162
|
+
companyId: zod.z.string().min(1, "C\xF4ng ty l\xE0 b\u1EAFt bu\u1ED9c"),
|
|
163
|
+
code: zod.z.string().min(1, "M\xE3 chi nh\xE1nh l\xE0 b\u1EAFt bu\u1ED9c").max(50, "M\xE3 chi nh\xE1nh t\u1ED1i \u0111a 50 k\xFD t\u1EF1").trim(),
|
|
164
|
+
name: zod.z.string().min(1, "T\xEAn chi nh\xE1nh l\xE0 b\u1EAFt bu\u1ED9c").max(255, "T\xEAn chi nh\xE1nh t\u1ED1i \u0111a 255 k\xFD t\u1EF1").trim(),
|
|
165
|
+
address: zod.z.string().max(500, "\u0110\u1ECBa ch\u1EC9 t\u1ED1i \u0111a 500 k\xFD t\u1EF1").trim().optional().nullable(),
|
|
166
|
+
phone: zod.z.string().max(20, "S\u1ED1 \u0111i\u1EC7n tho\u1EA1i t\u1ED1i \u0111a 20 k\xFD t\u1EF1").trim().optional().nullable(),
|
|
167
|
+
email: zod.z.string().max(255, "Email t\u1ED1i \u0111a 255 k\xFD t\u1EF1").email("Email kh\xF4ng h\u1EE3p l\u1EC7").trim().optional().nullable().or(zod.z.literal("")),
|
|
168
|
+
status: zod.z.enum(["active", "inactive"]).default("active")
|
|
169
|
+
});
|
|
170
|
+
var branchUpdateSchema = branchSchema.partial();
|
|
171
|
+
|
|
172
|
+
// src/organization/branch-service.ts
|
|
173
|
+
var BranchServiceError = class extends Error {
|
|
174
|
+
constructor(message, status, options) {
|
|
175
|
+
super(message);
|
|
176
|
+
this.name = "BranchServiceError";
|
|
177
|
+
this.status = status;
|
|
178
|
+
this.field = options?.field;
|
|
179
|
+
this.details = options?.details;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
var BRANCH_INCLUDE = {
|
|
183
|
+
company: {
|
|
184
|
+
select: { id: true, name: true }
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
var ensureUserId = (userId) => {
|
|
188
|
+
if (!userId) {
|
|
189
|
+
throw new BranchServiceError("Unauthorized", 401);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
async function listBranches(db, params) {
|
|
193
|
+
const page = Number(params.page || 1);
|
|
194
|
+
const pageSize = Math.min(Number(params.pageSize || 10), 100);
|
|
195
|
+
const skip = (page - 1) * pageSize;
|
|
196
|
+
const search = params.search?.trim() || void 0;
|
|
197
|
+
const companyId = params.companyId?.trim() || void 0;
|
|
198
|
+
const status = params.status?.trim() || void 0;
|
|
199
|
+
const where = {};
|
|
200
|
+
if (search) {
|
|
201
|
+
where.OR = [
|
|
202
|
+
{ name: { contains: search, mode: "insensitive" } },
|
|
203
|
+
{ code: { contains: search, mode: "insensitive" } },
|
|
204
|
+
{ email: { contains: search, mode: "insensitive" } }
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
if (companyId) {
|
|
208
|
+
where.companyId = companyId;
|
|
209
|
+
}
|
|
210
|
+
if (status) {
|
|
211
|
+
where.status = status;
|
|
212
|
+
}
|
|
213
|
+
const [total, data] = await Promise.all([
|
|
214
|
+
db.branch.count({ where }),
|
|
215
|
+
db.branch.findMany({
|
|
216
|
+
where,
|
|
217
|
+
orderBy: { name: "asc" },
|
|
218
|
+
skip,
|
|
219
|
+
take: pageSize,
|
|
220
|
+
include: BRANCH_INCLUDE
|
|
221
|
+
})
|
|
222
|
+
]);
|
|
223
|
+
return {
|
|
224
|
+
data,
|
|
225
|
+
pagination: {
|
|
226
|
+
page,
|
|
227
|
+
pageSize,
|
|
228
|
+
total,
|
|
229
|
+
totalPages: Math.ceil(total / pageSize)
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async function getBranchById(db, id) {
|
|
234
|
+
const branch = await db.branch.findUnique({
|
|
235
|
+
where: { id },
|
|
236
|
+
include: BRANCH_INCLUDE
|
|
237
|
+
});
|
|
238
|
+
if (!branch) {
|
|
239
|
+
throw new BranchServiceError("Chi nh\xE1nh kh\xF4ng t\u1ED3n t\u1EA1i", 404);
|
|
240
|
+
}
|
|
241
|
+
return branch;
|
|
242
|
+
}
|
|
243
|
+
async function createBranch(db, input, userId) {
|
|
244
|
+
ensureUserId(userId);
|
|
245
|
+
const result = branchSchema.safeParse(input);
|
|
246
|
+
if (!result.success) {
|
|
247
|
+
const errors = result.error.issues || [];
|
|
248
|
+
const firstError = errors[0];
|
|
249
|
+
throw new BranchServiceError(
|
|
250
|
+
firstError?.message || "Validation error",
|
|
251
|
+
400,
|
|
252
|
+
{
|
|
253
|
+
field: firstError?.path?.join("."),
|
|
254
|
+
details: errors
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
const validData = result.data;
|
|
259
|
+
const existing = await db.branch.findUnique({
|
|
260
|
+
where: { code: validData.code }
|
|
261
|
+
});
|
|
262
|
+
if (existing) {
|
|
263
|
+
throw new BranchServiceError("M\xE3 chi nh\xE1nh \u0111\xE3 t\u1ED3n t\u1EA1i", 400, {
|
|
264
|
+
field: "code"
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const company = await db.company.findUnique({
|
|
268
|
+
where: { id: validData.companyId }
|
|
269
|
+
});
|
|
270
|
+
if (!company) {
|
|
271
|
+
throw new BranchServiceError("C\xF4ng ty kh\xF4ng t\u1ED3n t\u1EA1i", 400, {
|
|
272
|
+
field: "companyId"
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return db.branch.create({
|
|
276
|
+
data: {
|
|
277
|
+
id: crypto.randomUUID(),
|
|
278
|
+
companyId: validData.companyId,
|
|
279
|
+
code: validData.code,
|
|
280
|
+
name: validData.name,
|
|
281
|
+
address: validData.address,
|
|
282
|
+
phone: validData.phone,
|
|
283
|
+
email: validData.email,
|
|
284
|
+
status: validData.status,
|
|
285
|
+
createdBy: userId,
|
|
286
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
287
|
+
updatedBy: userId
|
|
288
|
+
},
|
|
289
|
+
include: BRANCH_INCLUDE
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
async function updateBranch(db, id, input, userId) {
|
|
293
|
+
ensureUserId(userId);
|
|
294
|
+
const result = branchUpdateSchema.safeParse(input);
|
|
295
|
+
if (!result.success) {
|
|
296
|
+
const errors = result.error.issues || [];
|
|
297
|
+
const firstError = errors[0];
|
|
298
|
+
throw new BranchServiceError(
|
|
299
|
+
firstError?.message || "Validation error",
|
|
300
|
+
400,
|
|
301
|
+
{
|
|
302
|
+
field: firstError?.path?.join("."),
|
|
303
|
+
details: errors
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const validData = result.data;
|
|
308
|
+
const existingBranch = await db.branch.findUnique({
|
|
309
|
+
where: { id }
|
|
310
|
+
});
|
|
311
|
+
if (!existingBranch) {
|
|
312
|
+
throw new BranchServiceError("Chi nh\xE1nh kh\xF4ng t\u1ED3n t\u1EA1i", 404);
|
|
313
|
+
}
|
|
314
|
+
if (validData.code && validData.code !== existingBranch.code) {
|
|
315
|
+
const duplicate = await db.branch.findUnique({
|
|
316
|
+
where: { code: validData.code }
|
|
317
|
+
});
|
|
318
|
+
if (duplicate) {
|
|
319
|
+
throw new BranchServiceError("M\xE3 chi nh\xE1nh \u0111\xE3 t\u1ED3n t\u1EA1i", 400, {
|
|
320
|
+
field: "code"
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (validData.companyId) {
|
|
325
|
+
const company = await db.company.findUnique({
|
|
326
|
+
where: { id: validData.companyId }
|
|
327
|
+
});
|
|
328
|
+
if (!company) {
|
|
329
|
+
throw new BranchServiceError("C\xF4ng ty kh\xF4ng t\u1ED3n t\u1EA1i", 400, {
|
|
330
|
+
field: "companyId"
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return db.branch.update({
|
|
335
|
+
where: { id },
|
|
336
|
+
data: {
|
|
337
|
+
...validData,
|
|
338
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
339
|
+
updatedBy: userId
|
|
340
|
+
},
|
|
341
|
+
include: BRANCH_INCLUDE
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
async function deleteBranch(db, id) {
|
|
345
|
+
const branch = await db.branch.findUnique({ where: { id } });
|
|
346
|
+
if (!branch) {
|
|
347
|
+
throw new BranchServiceError("Chi nh\xE1nh kh\xF4ng t\u1ED3n t\u1EA1i", 404);
|
|
348
|
+
}
|
|
349
|
+
return db.branch.delete({ where: { id } });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
exports.BranchServiceError = BranchServiceError;
|
|
353
|
+
exports.branchesConfig = branchesConfig;
|
|
354
|
+
exports.createBranch = createBranch;
|
|
355
|
+
exports.deleteBranch = deleteBranch;
|
|
356
|
+
exports.getBranchById = getBranchById;
|
|
357
|
+
exports.listBranches = listBranches;
|
|
358
|
+
exports.updateBranch = updateBranch;
|
|
359
|
+
//# sourceMappingURL=index.js.map
|
|
360
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/configs/status.ts","../../src/organization/branches.config.ts","../../src/schemas/branch.schema.ts","../../src/organization/branch-service.ts"],"names":["GitBranch","z"],"mappings":"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","file":"index.js","sourcesContent":["export const STATUS_ACTIVE = \"active\";\nexport const STATUS_INACTIVE = \"inactive\";\n\nexport const STATUS_VALUES = [STATUS_ACTIVE, STATUS_INACTIVE] as const;\n\nexport const STATUS_OPTIONS = [\n { label: \"crud.common.options.active\", value: STATUS_ACTIVE },\n { label: \"crud.common.options.inactive\", value: STATUS_INACTIVE },\n];\n\nexport const STATUS_COLORS: Record<\n string,\n \"success\" | \"warning\" | \"default\" | \"destructive\" | \"secondary\" | \"outline\"\n> = {\n [STATUS_ACTIVE]: \"success\",\n [STATUS_INACTIVE]: \"warning\",\n};\n\nexport function booleanToStatus(value: boolean): string {\n return value ? STATUS_ACTIVE : STATUS_INACTIVE;\n}\n\nexport function statusToBoolean(value: string): boolean {\n return value === STATUS_ACTIVE;\n}\n","import { GitBranch } from \"lucide-react\";\n\nimport type { EntityConfig } from \"../types\";\n\nimport { STATUS_OPTIONS } from \"../configs/status\";\n\nexport const branchesConfig: EntityConfig = {\n name: \"branch\",\n permissionResource: \"branch\",\n label: \"Chi nhánh\",\n pluralLabel: \"Danh sách chi nhánh\",\n icon: GitBranch,\n description: \"Quản lý danh sách chi nhánh\",\n apiEndpoint: \"/api/branches\",\n idField: \"id\",\n displayField: \"name\",\n\n fields: [\n {\n name: \"id\",\n label: \"ID\",\n type: \"text\",\n hideInForm: true,\n hideInTable: true,\n },\n {\n name: \"companyId\",\n label: \"Công ty\",\n type: \"select\",\n required: true,\n placeholder: \"Chọn công ty\",\n filterable: true,\n dataSource: {\n type: \"api\",\n endpoint: \"/api/companies\",\n labelField: \"name\",\n valueField: \"id\",\n },\n },\n {\n name: \"code\",\n label: \"Mã chi nhánh\",\n type: \"text\",\n required: true,\n placeholder: \"Nhập mã chi nhánh\",\n filterable: true,\n },\n {\n name: \"name\",\n label: \"Tên chi nhánh\",\n type: \"text\",\n required: true,\n placeholder: \"Nhập tên chi nhánh\",\n filterable: true,\n },\n {\n name: \"address\",\n label: \"Địa chỉ\",\n type: \"textarea\",\n required: false,\n placeholder: \"Nhập địa chỉ\",\n rows: 2,\n },\n {\n name: \"phone\",\n label: \"Số điện thoại\",\n type: \"text\",\n required: false,\n placeholder: \"Nhập số điện thoại\",\n },\n {\n name: \"email\",\n label: \"Email\",\n type: \"email\",\n required: false,\n placeholder: \"Nhập email\",\n },\n {\n name: \"status\",\n label: \"Trạng thái\",\n type: \"switch\",\n required: true,\n defaultValue: \"active\",\n filterable: true,\n options: STATUS_OPTIONS,\n },\n {\n name: \"createdAt\",\n label: \"Ngày tạo\",\n type: \"datetime\",\n hideInForm: true,\n renderCell: (value) => {\n return new Date(value as string).toLocaleDateString(\"vi-VN\");\n },\n },\n {\n name: \"updatedAt\",\n label: \"Ngày cập nhật\",\n type: \"datetime\",\n hideInForm: true,\n hideInTable: true,\n },\n ],\n\n filters: [\n {\n name: \"search\",\n label: \"Tìm kiếm\",\n type: \"text\",\n field: \"name\",\n operator: \"contains\",\n },\n {\n name: \"companyId\",\n label: \"Công ty\",\n type: \"select\",\n field: \"companyId\",\n operator: \"eq\",\n dataSource: {\n type: \"api\",\n endpoint: \"/api/companies\",\n labelField: \"name\",\n valueField: \"id\",\n },\n },\n {\n name: \"status\",\n label: \"Trạng thái\",\n type: \"checkbox\",\n field: \"status\",\n operator: \"in\",\n options: [\n { label: \"Hoạt động\", value: \"active\" },\n { label: \"Ngừng hoạt động\", value: \"inactive\" },\n ],\n },\n ],\n\n permissions: {\n create: true,\n read: true,\n update: true,\n delete: true,\n export: true,\n import: false,\n },\n\n features: {\n search: true,\n bulkActions: true,\n export: true,\n import: false,\n },\n};\n","import { z } from \"zod\";\n\n/**\n * Branch Validation Schema\n *\n * Validates branch form submissions on both client & server.\n */\n\nexport const branchSchema = z.object({\n companyId: z.string().min(1, \"Công ty là bắt buộc\"),\n\n code: z\n .string()\n .min(1, \"Mã chi nhánh là bắt buộc\")\n .max(50, \"Mã chi nhánh tối đa 50 ký tự\")\n .trim(),\n\n name: z\n .string()\n .min(1, \"Tên chi nhánh là bắt buộc\")\n .max(255, \"Tên chi nhánh tối đa 255 ký tự\")\n .trim(),\n\n address: z\n .string()\n .max(500, \"Địa chỉ tối đa 500 ký tự\")\n .trim()\n .optional()\n .nullable(),\n\n phone: z\n .string()\n .max(20, \"Số điện thoại tối đa 20 ký tự\")\n .trim()\n .optional()\n .nullable(),\n\n email: z\n .string()\n .max(255, \"Email tối đa 255 ký tự\")\n .email(\"Email không hợp lệ\")\n .trim()\n .optional()\n .nullable()\n .or(z.literal(\"\")),\n\n status: z.enum([\"active\", \"inactive\"]).default(\"active\"),\n});\n\nexport type BranchInput = z.infer<typeof branchSchema>;\n\nexport const branchUpdateSchema = branchSchema.partial();\n","import { branchSchema, branchUpdateSchema } from \"../schemas\";\n\nexport interface BranchRecord {\n id: string;\n companyId?: string;\n code: string;\n name: string;\n address?: string | null;\n phone?: string | null;\n email?: string | null;\n status?: string;\n company?: { id: string; name: string };\n}\n\nexport interface BranchDbClient {\n branch: {\n count: (args: { where?: Record<string, unknown> }) => Promise<number>;\n findMany: (args: {\n where?: Record<string, unknown>;\n orderBy?: Record<string, unknown>;\n skip?: number;\n take?: number;\n include?: Record<string, unknown>;\n }) => Promise<BranchRecord[]>;\n findUnique: (args: {\n where: { id?: string; code?: string };\n include?: Record<string, unknown>;\n }) => Promise<BranchRecord | null>;\n create: (args: {\n data: Record<string, unknown>;\n include?: Record<string, unknown>;\n }) => Promise<BranchRecord>;\n update: (args: {\n where: { id: string };\n data: Record<string, unknown>;\n include?: Record<string, unknown>;\n }) => Promise<BranchRecord>;\n delete: (args: { where: { id: string } }) => Promise<BranchRecord>;\n };\n company: {\n findUnique: (args: {\n where: { id: string };\n }) => Promise<{ id: string } | null>;\n };\n}\n\nexport interface BranchListParams {\n page?: number;\n pageSize?: number;\n search?: string | null;\n companyId?: string | null;\n status?: string | null;\n}\n\nexport interface BranchListResponse {\n data: BranchRecord[];\n pagination: {\n page: number;\n pageSize: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport class BranchServiceError extends Error {\n status: number;\n field?: string;\n details?: unknown;\n\n constructor(\n message: string,\n status: number,\n options?: { field?: string; details?: unknown },\n ) {\n super(message);\n this.name = \"BranchServiceError\";\n this.status = status;\n this.field = options?.field;\n this.details = options?.details;\n }\n}\n\nconst BRANCH_INCLUDE = {\n company: {\n select: { id: true, name: true },\n },\n};\n\nconst ensureUserId = (userId?: string) => {\n if (!userId) {\n throw new BranchServiceError(\"Unauthorized\", 401);\n }\n};\n\nexport async function listBranches(\n db: BranchDbClient,\n params: BranchListParams,\n): Promise<BranchListResponse> {\n const page = Number(params.page || 1);\n const pageSize = Math.min(Number(params.pageSize || 10), 100);\n const skip = (page - 1) * pageSize;\n\n const search = params.search?.trim() || undefined;\n const companyId = params.companyId?.trim() || undefined;\n const status = params.status?.trim() || undefined;\n\n const where: Record<string, unknown> = {};\n\n if (search) {\n where.OR = [\n { name: { contains: search, mode: \"insensitive\" } },\n { code: { contains: search, mode: \"insensitive\" } },\n { email: { contains: search, mode: \"insensitive\" } },\n ];\n }\n\n if (companyId) {\n where.companyId = companyId;\n }\n\n if (status) {\n where.status = status;\n }\n\n // ⚡ Bolt: Run count and findMany concurrently to reduce latency\n const [total, data] = await Promise.all([\n db.branch.count({ where }),\n db.branch.findMany({\n where,\n orderBy: { name: \"asc\" },\n skip,\n take: pageSize,\n include: BRANCH_INCLUDE,\n }),\n ]);\n\n return {\n data,\n pagination: {\n page,\n pageSize,\n total,\n totalPages: Math.ceil(total / pageSize),\n },\n };\n}\n\nexport async function getBranchById(\n db: BranchDbClient,\n id: string,\n): Promise<BranchRecord> {\n const branch = await db.branch.findUnique({\n where: { id },\n include: BRANCH_INCLUDE,\n });\n\n if (!branch) {\n throw new BranchServiceError(\"Chi nhánh không tồn tại\", 404);\n }\n\n return branch;\n}\n\nexport async function createBranch(\n db: BranchDbClient,\n input: unknown,\n userId?: string,\n): Promise<BranchRecord> {\n ensureUserId(userId);\n\n const result = branchSchema.safeParse(input);\n if (!result.success) {\n const errors = result.error.issues || [];\n const firstError = errors[0];\n throw new BranchServiceError(\n firstError?.message || \"Validation error\",\n 400,\n {\n field: firstError?.path?.join(\".\"),\n details: errors,\n },\n );\n }\n\n const validData = result.data;\n\n const existing = await db.branch.findUnique({\n where: { code: validData.code },\n });\n\n if (existing) {\n throw new BranchServiceError(\"Mã chi nhánh đã tồn tại\", 400, {\n field: \"code\",\n });\n }\n\n const company = await db.company.findUnique({\n where: { id: validData.companyId },\n });\n\n if (!company) {\n throw new BranchServiceError(\"Công ty không tồn tại\", 400, {\n field: \"companyId\",\n });\n }\n\n return db.branch.create({\n data: {\n id: crypto.randomUUID(),\n companyId: validData.companyId,\n code: validData.code,\n name: validData.name,\n address: validData.address,\n phone: validData.phone,\n email: validData.email,\n status: validData.status,\n createdBy: userId,\n updatedAt: new Date(),\n updatedBy: userId,\n },\n include: BRANCH_INCLUDE,\n });\n}\n\nexport async function updateBranch(\n db: BranchDbClient,\n id: string,\n input: unknown,\n userId?: string,\n): Promise<BranchRecord> {\n ensureUserId(userId);\n\n const result = branchUpdateSchema.safeParse(input);\n if (!result.success) {\n const errors = result.error.issues || [];\n const firstError = errors[0];\n throw new BranchServiceError(\n firstError?.message || \"Validation error\",\n 400,\n {\n field: firstError?.path?.join(\".\"),\n details: errors,\n },\n );\n }\n\n const validData = result.data;\n const existingBranch = await db.branch.findUnique({\n where: { id },\n });\n\n if (!existingBranch) {\n throw new BranchServiceError(\"Chi nhánh không tồn tại\", 404);\n }\n\n if (validData.code && validData.code !== existingBranch.code) {\n const duplicate = await db.branch.findUnique({\n where: { code: validData.code },\n });\n if (duplicate) {\n throw new BranchServiceError(\"Mã chi nhánh đã tồn tại\", 400, {\n field: \"code\",\n });\n }\n }\n\n if (validData.companyId) {\n const company = await db.company.findUnique({\n where: { id: validData.companyId },\n });\n if (!company) {\n throw new BranchServiceError(\"Công ty không tồn tại\", 400, {\n field: \"companyId\",\n });\n }\n }\n\n return db.branch.update({\n where: { id },\n data: {\n ...validData,\n updatedAt: new Date(),\n updatedBy: userId,\n },\n include: BRANCH_INCLUDE,\n });\n}\n\nexport async function deleteBranch(\n db: BranchDbClient,\n id: string,\n): Promise<BranchRecord> {\n const branch = await db.branch.findUnique({ where: { id } });\n if (!branch) {\n throw new BranchServiceError(\"Chi nhánh không tồn tại\", 404);\n }\n\n return db.branch.delete({ where: { id } });\n}\n"]}
|