@zerosls/clm-sdk 1.0.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.
Files changed (81) hide show
  1. package/.docs/publicacion-npm.md +111 -0
  2. package/.env.example +14 -0
  3. package/.gitlab-ci.yml +23 -0
  4. package/README.md +202 -0
  5. package/dist/config/config.d.ts +3 -0
  6. package/dist/config/config.js +21 -0
  7. package/dist/core/api-client.d.ts +27 -0
  8. package/dist/core/api-client.js +183 -0
  9. package/dist/core/api-error.d.ts +15 -0
  10. package/dist/core/api-error.js +46 -0
  11. package/dist/core/event-emitter.d.ts +11 -0
  12. package/dist/core/event-emitter.js +32 -0
  13. package/dist/index.d.ts +41 -0
  14. package/dist/index.js +59 -0
  15. package/dist/modules/legacy/areas/areas-api.d.ts +34 -0
  16. package/dist/modules/legacy/areas/areas-api.js +44 -0
  17. package/dist/modules/legacy/areas/types.d.ts +37 -0
  18. package/dist/modules/legacy/areas/types.js +1 -0
  19. package/dist/modules/legacy/classificationtypes/classificationtypes-api.d.ts +34 -0
  20. package/dist/modules/legacy/classificationtypes/classificationtypes-api.js +46 -0
  21. package/dist/modules/legacy/classificationtypes/types.d.ts +41 -0
  22. package/dist/modules/legacy/classificationtypes/types.js +1 -0
  23. package/dist/modules/v1/auth/auth-api.d.ts +17 -0
  24. package/dist/modules/v1/auth/auth-api.js +63 -0
  25. package/dist/modules/v1/auth/types.d.ts +18 -0
  26. package/dist/modules/v1/auth/types.js +1 -0
  27. package/dist/modules/v1/main/main-api.d.ts +11 -0
  28. package/dist/modules/v1/main/main-api.js +14 -0
  29. package/dist/modules/v1/main/types.d.ts +3 -0
  30. package/dist/modules/v1/main/types.js +1 -0
  31. package/dist/modules/v1/notifications/notification-api.d.ts +16 -0
  32. package/dist/modules/v1/notifications/notification-api.js +26 -0
  33. package/dist/modules/v1/notifications/types.d.ts +53 -0
  34. package/dist/modules/v1/notifications/types.js +1 -0
  35. package/dist/modules/v1/users/types.d.ts +64 -0
  36. package/dist/modules/v1/users/types.js +1 -0
  37. package/dist/modules/v1/users/users-api.d.ts +81 -0
  38. package/dist/modules/v1/users/users-api.js +113 -0
  39. package/dist/types/common.d.ts +18 -0
  40. package/dist/types/common.js +1 -0
  41. package/dist/types/sdk.d.ts +42 -0
  42. package/dist/types/sdk.js +11 -0
  43. package/dist/utils/cache.d.ts +10 -0
  44. package/dist/utils/cache.js +43 -0
  45. package/dist/utils/http.d.ts +5 -0
  46. package/dist/utils/http.js +56 -0
  47. package/package.json +38 -0
  48. package/src/config/config.ts +24 -0
  49. package/src/core/api-client.ts +272 -0
  50. package/src/core/api-error.ts +54 -0
  51. package/src/core/event-emitter.ts +43 -0
  52. package/src/index.ts +89 -0
  53. package/src/modules/legacy/areas/areas-api.ts +73 -0
  54. package/src/modules/legacy/areas/types.ts +49 -0
  55. package/src/modules/legacy/classificationtypes/classificationtypes-api.ts +80 -0
  56. package/src/modules/legacy/classificationtypes/types.ts +52 -0
  57. package/src/modules/v1/auth/auth-api.ts +75 -0
  58. package/src/modules/v1/auth/types.ts +20 -0
  59. package/src/modules/v1/main/main-api.ts +20 -0
  60. package/src/modules/v1/main/types.ts +3 -0
  61. package/src/modules/v1/notifications/notification-api.ts +55 -0
  62. package/src/modules/v1/notifications/types.ts +58 -0
  63. package/src/modules/v1/users/types.ts +83 -0
  64. package/src/modules/v1/users/users-api.ts +148 -0
  65. package/src/types/common.ts +22 -0
  66. package/src/types/sdk.ts +38 -0
  67. package/src/utils/cache.ts +58 -0
  68. package/src/utils/http.ts +77 -0
  69. package/tests/integration/legacy/auth-areas.test.ts +115 -0
  70. package/tests/integration/legacy/auth-classification-types.test.ts +80 -0
  71. package/tests/integration/v1/auth-logs.test.ts +145 -0
  72. package/tests/integration/v1/auth-users.test.ts +189 -0
  73. package/tests/modules/legacy/areas/areas-api.test.ts +232 -0
  74. package/tests/modules/legacy/classification-types/classification-types-api.test.ts +100 -0
  75. package/tests/modules/v1/auth/auth-api.test.ts +134 -0
  76. package/tests/modules/v1/users/users-api.test.ts +176 -0
  77. package/tests/setup.ts +12 -0
  78. package/tests/utils/test-utils.ts +453 -0
  79. package/tsconfig.json +16 -0
  80. package/tsconfig.test.json +13 -0
  81. package/vitest.config.ts +16 -0
@@ -0,0 +1,272 @@
1
+ import { SdkConfig, SdkEventType, SdkEvents } from "../types/sdk";
2
+ import { PaginatedResponse, RequestOptions } from "../types/common";
3
+ import { EventEmitter } from "./event-emitter";
4
+ import { ApiError } from "./api-error";
5
+ import { Cache } from "../utils/cache";
6
+ import {
7
+ buildUrl,
8
+ buildHeaders,
9
+ generateCacheKey,
10
+ parseResponse,
11
+ } from "../utils/http";
12
+
13
+ export class ApiClient {
14
+ private baseUrl: string;
15
+ private organization: string;
16
+ private token: string | null = null;
17
+ private eventEmitter: EventEmitter;
18
+ private cache: Cache;
19
+ private debug: boolean;
20
+ private cacheEnabled: boolean;
21
+
22
+ constructor(config: SdkConfig, eventEmitter: EventEmitter) {
23
+ this.baseUrl = config.baseUrl;
24
+ this.organization = config.organization;
25
+ this.token = config.token || null;
26
+ this.eventEmitter = eventEmitter;
27
+ this.cacheEnabled = config.cache?.enabled !== false;
28
+ this.cache = new Cache(config.cache?.ttl);
29
+ this.debug = config.debug || false;
30
+ }
31
+
32
+ // Métodos para gestión del token
33
+ public setToken(token: string | null): void {
34
+ this.token = token;
35
+ this.eventEmitter.emit("tokenChanged", token);
36
+ }
37
+
38
+ public getToken(): string | null {
39
+ return this.token;
40
+ }
41
+
42
+ public setOrganization(organization: string): void {
43
+ this.organization = organization;
44
+ }
45
+
46
+ // Método GET
47
+ public async get<T>(
48
+ endpoint: string,
49
+ params?: Record<string, any>,
50
+ options?: RequestOptions
51
+ ): Promise<T> {
52
+ return this.request<T>("GET", endpoint, undefined, params, options);
53
+ }
54
+
55
+ // Método POST
56
+ public async post<T>(
57
+ endpoint: string,
58
+ data?: any,
59
+ options?: RequestOptions
60
+ ): Promise<T> {
61
+ return this.request<T>("POST", endpoint, data, undefined, options);
62
+ }
63
+
64
+ // Método PATCH
65
+ public async patch<T>(
66
+ endpoint: string,
67
+ data?: any,
68
+ options?: RequestOptions
69
+ ): Promise<T> {
70
+ const result = await this.request<T>(
71
+ "PATCH",
72
+ endpoint,
73
+ data,
74
+ undefined,
75
+ options
76
+ );
77
+ this.invalidateCache(endpoint);
78
+ return result;
79
+ }
80
+
81
+ // Método PUT
82
+ public async put<T>(
83
+ endpoint: string,
84
+ data?: any,
85
+ options?: RequestOptions
86
+ ): Promise<T> {
87
+ const result = await this.request<T>(
88
+ "PUT",
89
+ endpoint,
90
+ data,
91
+ undefined,
92
+ options
93
+ );
94
+ this.invalidateCache(endpoint);
95
+ return result;
96
+ }
97
+
98
+ // ✅ Método DELETE - CORREGIDO
99
+ public async delete<T>(
100
+ endpoint: string,
101
+ data?: any, // ✅ Cambiar params por data para enviarlo en el body
102
+ options?: RequestOptions
103
+ ): Promise<T> {
104
+ console.log("🗑️ DELETE request:", { endpoint, data });
105
+
106
+ const result = await this.request<T>(
107
+ "DELETE",
108
+ endpoint,
109
+ data, // ✅ Enviar como body (data)
110
+ undefined, // ✅ params es undefined
111
+ options
112
+ );
113
+
114
+ this.invalidateCache(endpoint);
115
+ console.log("✅ DELETE response:", result);
116
+ return result;
117
+ }
118
+
119
+ /**
120
+ * Invalida la caché relacionada con un endpoint específico
121
+ */
122
+ private invalidateCache(endpoint: string): void {
123
+ if (this.cacheEnabled) {
124
+ const basePath = endpoint.split("/").slice(0, 2).join("/");
125
+ this.cache.clearByPrefix(`GET:${this.baseUrl}${basePath}`);
126
+
127
+ if (this.debug) {
128
+ console.log(`[SDK-Cache] Invalidated cache for: ${basePath}`);
129
+ }
130
+ }
131
+ }
132
+
133
+ // Método central para todas las peticiones HTTP
134
+ private async request<T>(
135
+ method: string,
136
+ endpoint: string,
137
+ data?: any,
138
+ params?: Record<string, any>,
139
+ options: RequestOptions = {}
140
+ ): Promise<T> {
141
+ const url = buildUrl(this.baseUrl, endpoint, params);
142
+
143
+ // =====================================================
144
+ // 1. Construir headers base
145
+ // =====================================================
146
+ const base: HeadersInit = buildHeaders(this.token, {
147
+ "X-Organization": this.organization,
148
+ ...(options.headers || {}),
149
+ });
150
+
151
+ const headers = new Headers(base);
152
+
153
+ if (!this.token) {
154
+ headers.delete("Authorization");
155
+ }
156
+
157
+ // =====================================================
158
+ // 2. Si el endpoint es /legacy/** → agregar Bearer legacy
159
+ // =====================================================
160
+ if (endpoint.startsWith("/legacy/")) {
161
+ const legacyToken =
162
+ (window as any).__LEGACY_TOKEN__ ||
163
+ sessionStorage.getItem("legacy_token") ||
164
+ null;
165
+
166
+ if (legacyToken) {
167
+ headers.set("Authorization", `Bearer ${legacyToken}`);
168
+ }
169
+ }
170
+
171
+ // =====================================================
172
+ // 3. Cache
173
+ // =====================================================
174
+ const useCache = this.cacheEnabled && options.useCache !== false;
175
+ if (useCache && method === "GET") {
176
+ const cacheKey = generateCacheKey(method, url, data);
177
+ const cachedData = this.cache.get<T>(cacheKey);
178
+ if (cachedData) {
179
+ if (this.debug) {
180
+ console.log(`[SDK-Cache] Hit: ${cacheKey}`);
181
+ }
182
+ return cachedData;
183
+ }
184
+ }
185
+
186
+ this.eventEmitter.emit("beforeRequest", {
187
+ url,
188
+ method,
189
+ data,
190
+ });
191
+
192
+ try {
193
+ // =====================================================
194
+ // 4. Preparar options de fetch
195
+ // =====================================================
196
+ const fetchOptions: RequestInit = {
197
+ method,
198
+ headers,
199
+ credentials: "include",
200
+ };
201
+
202
+ // ✅ CRÍTICO: Agregar body para POST, PUT, PATCH y DELETE
203
+ if (data && method !== "GET") {
204
+ fetchOptions.body = JSON.stringify(data);
205
+ console.log(`📤 ${method} Body:`, data);
206
+ }
207
+
208
+ // =====================================================
209
+ // 5. Hacer la llamada real
210
+ // =====================================================
211
+ console.log(`🌐 ${method} ${url}`, fetchOptions);
212
+ const response = await fetch(url, fetchOptions);
213
+
214
+ // Manejo de errores HTTP
215
+ if (!response.ok) {
216
+ let errorData;
217
+ try {
218
+ errorData = await response.json();
219
+ } catch {
220
+ errorData = { message: response.statusText };
221
+ }
222
+
223
+ console.error(`❌ ${method} ${response.status}:`, errorData);
224
+
225
+ if (response.status === 401) {
226
+ this.eventEmitter.emit("authError", {
227
+ statusCode: 401,
228
+ message: errorData.message || "Authentication required",
229
+ });
230
+ }
231
+
232
+ return errorData as T;
233
+ }
234
+
235
+ // Parsear respuesta exitosa
236
+ const responseData = await parseResponse<T>(response);
237
+
238
+ // Guardar en caché si aplica
239
+ if (useCache && method === "GET") {
240
+ const cacheKey = generateCacheKey(method, url, data);
241
+ const cacheTime = options.cacheTime || undefined;
242
+ this.cache.set(cacheKey, responseData, cacheTime);
243
+
244
+ if (this.debug) {
245
+ console.log(`[SDK-Cache] Set: ${cacheKey}`);
246
+ }
247
+ }
248
+
249
+ this.eventEmitter.emit("afterRequest", {
250
+ url,
251
+ method,
252
+ response: responseData,
253
+ });
254
+
255
+ return responseData;
256
+ } catch (error) {
257
+ this.eventEmitter.emit("requestError", {
258
+ url,
259
+ method,
260
+ error,
261
+ });
262
+
263
+ if (error instanceof ApiError) {
264
+ throw error;
265
+ }
266
+
267
+ throw new ApiError((error as Error).message || "Network error", 0, {
268
+ originalError: error,
269
+ });
270
+ }
271
+ }
272
+ }
@@ -0,0 +1,54 @@
1
+ import { ErrorType } from '../types/sdk';
2
+
3
+ export class ApiError extends Error {
4
+ public readonly isApiError = true;
5
+ public readonly statusCode: number;
6
+ public readonly type: ErrorType;
7
+ public readonly details?: any;
8
+
9
+ constructor(message: string, statusCode: number, details?: any) {
10
+ super(message);
11
+ this.name = 'ApiError';
12
+ this.statusCode = statusCode;
13
+ this.details = details;
14
+ this.type = this.determineErrorType(statusCode);
15
+
16
+ // Para que instanceof funcione correctamente con clases extendidas
17
+ Object.setPrototypeOf(this, ApiError.prototype);
18
+ }
19
+
20
+ // Determina el tipo de error según el código HTTP
21
+ private determineErrorType(statusCode: number): ErrorType {
22
+ if (statusCode === 401) return ErrorType.AUTHENTICATION;
23
+ if (statusCode === 403) return ErrorType.AUTHORIZATION;
24
+ if (statusCode === 404) return ErrorType.NOT_FOUND;
25
+ if (statusCode >= 400 && statusCode < 500) return ErrorType.VALIDATION;
26
+ if (statusCode >= 500) return ErrorType.SERVER;
27
+ return ErrorType.UNKNOWN;
28
+ }
29
+
30
+ // Propiedades útiles para verificación de tipo de error
31
+ get isNetworkError(): boolean {
32
+ return this.type === ErrorType.NETWORK;
33
+ }
34
+
35
+ get isAuthenticationError(): boolean {
36
+ return this.type === ErrorType.AUTHENTICATION;
37
+ }
38
+
39
+ get isAuthorizationError(): boolean {
40
+ return this.type === ErrorType.AUTHORIZATION;
41
+ }
42
+
43
+ get isNotFoundError(): boolean {
44
+ return this.type === ErrorType.NOT_FOUND;
45
+ }
46
+
47
+ get isValidationError(): boolean {
48
+ return this.type === ErrorType.VALIDATION;
49
+ }
50
+
51
+ get isServerError(): boolean {
52
+ return this.type === ErrorType.SERVER;
53
+ }
54
+ }
@@ -0,0 +1,43 @@
1
+ import { SdkEventType, SdkEvents } from '../types/sdk';
2
+
3
+ type Listener<T> = (data: T) => void;
4
+
5
+ interface Subscription {
6
+ unsubscribe: () => void;
7
+ }
8
+
9
+ export class EventEmitter {
10
+ private listeners: Map<string, Array<Listener<any>>> = new Map();
11
+
12
+ // Suscribirse a un evento
13
+ public on<K extends SdkEventType>(event: K, listener: Listener<SdkEvents[K]>): Subscription {
14
+ if (!this.listeners.has(event)) {
15
+ this.listeners.set(event, []);
16
+ }
17
+
18
+ const eventListeners = this.listeners.get(event)!;
19
+ eventListeners.push(listener);
20
+
21
+ // Devolver objeto para cancelar suscripción
22
+ return {
23
+ unsubscribe: () => {
24
+ const index = eventListeners.indexOf(listener);
25
+ if (index !== -1) {
26
+ eventListeners.splice(index, 1);
27
+ }
28
+ }
29
+ };
30
+ }
31
+
32
+ // Emitir un evento con datos
33
+ public emit<K extends SdkEventType>(event: K, data: SdkEvents[K]): void {
34
+ if (!this.listeners.has(event)) {
35
+ return;
36
+ }
37
+
38
+ const eventListeners = this.listeners.get(event)!;
39
+ for (const listener of eventListeners) {
40
+ listener(data);
41
+ }
42
+ }
43
+ }
package/src/index.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { SdkConfig } from "./types/sdk";
2
+ import { mergeWithDefaultConfig } from "./config/config";
3
+ import { ApiClient } from "./core/api-client";
4
+ import { EventEmitter } from "./core/event-emitter";
5
+ import { Cache } from "./utils/cache";
6
+ import { SdkEventType } from "./types/sdk";
7
+
8
+ // v1
9
+ import { AuthApi } from "./modules/v1/auth/auth-api";
10
+ import { UsersApi } from "./modules/v1/users/users-api";
11
+ import { MainApi } from "./modules/v1/main/main-api";
12
+ import { NotificationsApi } from "./modules/v1/notifications/notification-api";
13
+ //import { LogsApi } from "./modules/v1/logs/logs-api";
14
+
15
+ // Legacy
16
+ import { AreasApi } from "./modules/legacy/areas/areas-api";
17
+ import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/classificationtypes-api";
18
+
19
+ /**
20
+ * Main SDK for consuming CLM API
21
+ */
22
+ export class ClmSdk {
23
+ private apiClient: ApiClient;
24
+ private eventEmitter: EventEmitter;
25
+ private cacheInstance: Cache;
26
+
27
+ // Public modules v1
28
+ public auth: AuthApi;
29
+ public users: UsersApi;
30
+ public main: MainApi;
31
+ public notifications: NotificationsApi;
32
+ //public logs: LogsApi;
33
+
34
+ // Public modules legacy
35
+ public areas: AreasApi;
36
+ public classificationTypes: ClassificationTypesApi;
37
+
38
+ constructor(config: Partial<SdkConfig>) {
39
+ this.eventEmitter = new EventEmitter();
40
+
41
+ // Apply default configuration
42
+ const fullConfig = mergeWithDefaultConfig(config);
43
+
44
+ // Initialize core utilities
45
+ this.cacheInstance = new Cache(fullConfig.cache?.ttl);
46
+ this.apiClient = new ApiClient(fullConfig, this.eventEmitter);
47
+
48
+ // Initialize modules v1
49
+ this.auth = new AuthApi(this.apiClient);
50
+ this.users = new UsersApi(this.apiClient);
51
+ this.main = new MainApi(this.apiClient);
52
+ this.notifications = new NotificationsApi(this.apiClient);
53
+ //this.logs = new LogsApi(this.apiClient);
54
+
55
+ // Initialize legacy modules
56
+ this.areas = new AreasApi(this.apiClient);
57
+ this.classificationTypes = new ClassificationTypesApi(this.apiClient);
58
+ }
59
+
60
+ /**
61
+ * Access to events system
62
+ */
63
+ public on(
64
+ event: SdkEventType,
65
+ listener: any
66
+ ): ReturnType<typeof this.eventEmitter.on> {
67
+ return this.eventEmitter.on(event, listener);
68
+ }
69
+
70
+ /**
71
+ * Access to cache functions
72
+ */
73
+ public cache = {
74
+ clear: () => this.cacheInstance.clear(),
75
+ clearByPrefix: (prefix: string) => this.cacheInstance.clearByPrefix(prefix),
76
+ };
77
+ }
78
+
79
+ export * from "./types/common";
80
+ export * from "./types/sdk";
81
+
82
+ // Export v1 types
83
+ export * from "./modules/v1/auth/types";
84
+ export * from "./modules/v1/users/types";
85
+ export * from "./modules/v1/notifications/types";
86
+ //export * from "./modules/v1/logs/types";
87
+ // Export legacy types
88
+ export * from "./modules/legacy/areas/types";
89
+ export * from "./modules/legacy/classificationtypes/types";
@@ -0,0 +1,73 @@
1
+ import { ApiClient } from "../../../core/api-client";
2
+ import {
3
+ CreateAreaRequest,
4
+ UpdateAreaRequest,
5
+ DeleteAreaRequest,
6
+ AreaResponse,
7
+ AreasResponse
8
+ } from "./types";
9
+
10
+ export class AreasApi {
11
+ private apiClient: ApiClient;
12
+ private readonly basePath = "/legacy/catalog/areas"; //Siempre debe empezar con /legacy/ por que lo usa en el Gateway del API para que todas las request de API LEGACY y API V1 salgan de http://localhost:3001 URL del API que fusiona el API LEGACY y el API V1 y que el puerto lo toma por defecto del manifest
13
+
14
+ constructor(apiClient: ApiClient) {
15
+ this.apiClient = apiClient;
16
+ }
17
+
18
+ /**
19
+ * GET - Obtener todas las áreas
20
+ */
21
+ async getAreas(): Promise<AreasResponse> {
22
+ return await this.apiClient.get<AreasResponse>(
23
+ this.basePath,
24
+ undefined,
25
+ { useCache: false }
26
+ );
27
+ }
28
+
29
+ /**
30
+ * POST - Crear una nueva área
31
+ */
32
+ async createArea(data: CreateAreaRequest): Promise<AreaResponse> {
33
+ return await this.apiClient.post<AreaResponse>(
34
+ this.basePath,
35
+ data
36
+ );
37
+ }
38
+
39
+ /**
40
+ * PATCH - Actualizar datos de un área existente
41
+ */
42
+ async updateArea(data: UpdateAreaRequest): Promise<AreaResponse> {
43
+ return await this.apiClient.patch<AreaResponse>(
44
+ this.basePath,
45
+ data
46
+ );
47
+ }
48
+
49
+ /**
50
+ * DELETE - Eliminar un área existente
51
+ */
52
+ async deleteArea(data: DeleteAreaRequest): Promise<AreaResponse> {
53
+ return await this.apiClient.delete<AreaResponse>(
54
+ this.basePath,
55
+ data
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Helper: Generar datos de auditoría actuales
61
+ */
62
+ generateAuditData(userId: string, userName: string) {
63
+ const now = new Date().toISOString();
64
+ return {
65
+ createdBy: userId,
66
+ createdByName: userName,
67
+ createdOn: now,
68
+ lastModBy: userId,
69
+ lastModByName: userName,
70
+ lastModOn: now
71
+ };
72
+ }
73
+ }
@@ -0,0 +1,49 @@
1
+ // Entidad base con metadatos de auditoría
2
+ export interface AreaBase {
3
+ createdBy: string;
4
+ createdByName: string;
5
+ createdOn: string; // ISO DateTime
6
+ lastModBy: string;
7
+ lastModByName: string;
8
+ lastModOn: string; // ISO DateTime
9
+ name: string;
10
+ description: string;
11
+ }
12
+
13
+ // Entidad completa (con ID)
14
+ export interface Area extends AreaBase {
15
+ id: number;
16
+ }
17
+
18
+ // Request para crear área
19
+ export interface CreateAreaRequest extends AreaBase {}
20
+
21
+ // Request para actualizar área
22
+ export interface UpdateAreaRequest extends AreaBase {
23
+ id: number;
24
+ }
25
+
26
+ // Request para eliminar área
27
+ export interface DeleteAreaRequest {
28
+ id: number;
29
+ }
30
+
31
+ // Respuesta del GET (lista de áreas)
32
+ export interface AreasResponse {
33
+ dataResult: Area[];
34
+ statusResponse: {
35
+ code: number;
36
+ success: boolean;
37
+ message: string;
38
+ };
39
+ }
40
+
41
+ // Respuesta genérica para POST/PUT/DELETE
42
+ export interface AreaResponse {
43
+ dataResult?: Area;
44
+ statusResponse: {
45
+ code: number;
46
+ success: boolean;
47
+ message: string;
48
+ };
49
+ }
@@ -0,0 +1,80 @@
1
+ import { ApiClient } from "../../../core/api-client";
2
+ import {
3
+ CreateClassificationTypeRequest,
4
+ UpdateClassificationTypeRequest,
5
+ DeleteClassificationTypeRequest,
6
+ ClassificationTypeResponse,
7
+ ClassificationTypesResponse
8
+ } from "./types";
9
+
10
+ export class ClassificationTypesApi {
11
+ private apiClient: ApiClient;
12
+ private readonly basePath = "/legacy/catalog/clasificationtype";
13
+
14
+ constructor(apiClient: ApiClient) {
15
+ this.apiClient = apiClient;
16
+ }
17
+
18
+ /**
19
+ * GET - Obtener todos los tipos de clasificación
20
+ */
21
+ async getClassificationTypes(): Promise<ClassificationTypesResponse> {
22
+ return await this.apiClient.get<ClassificationTypesResponse>(
23
+ this.basePath,
24
+ undefined,
25
+ { useCache: false }
26
+ );
27
+ }
28
+
29
+ /**
30
+ * POST - Crear un nuevo tipo de clasificación
31
+ */
32
+ async createClassificationType(
33
+ data: CreateClassificationTypeRequest
34
+ ): Promise<ClassificationTypeResponse> {
35
+ const response = await this.apiClient.post<ClassificationTypeResponse>(
36
+ `${this.basePath}/create`,
37
+ data
38
+ );
39
+ return response;
40
+ }
41
+
42
+ /**
43
+ * PUT - Actualizar un tipo de clasificación existente
44
+ */
45
+ async updateClassificationType(
46
+ data: UpdateClassificationTypeRequest
47
+ ): Promise<ClassificationTypeResponse> {
48
+ return await this.apiClient.put<ClassificationTypeResponse>(
49
+ `${this.basePath}/update`, // Puede necesitar /update
50
+ data
51
+ );
52
+ }
53
+
54
+ /**
55
+ * DELETE - Eliminar un tipo de clasificación
56
+ */
57
+ async deleteClassificationType(
58
+ data: DeleteClassificationTypeRequest
59
+ ): Promise<ClassificationTypeResponse> {
60
+ return await this.apiClient.delete<ClassificationTypeResponse>(
61
+ `${this.basePath}/delete`,
62
+ data
63
+ );
64
+ }
65
+
66
+ /**
67
+ * Helper: Generar datos de auditoría actuales
68
+ */
69
+ generateAuditData(userId: string, userName: string) {
70
+ const now = new Date().toISOString();
71
+ return {
72
+ createdBy: userId,
73
+ createdByName: userName,
74
+ createdOn: now,
75
+ lastModBy: userId,
76
+ lastModByName: userName,
77
+ lastModOn: now
78
+ };
79
+ }
80
+ }