@timbra-ec/types 0.1.0-dev.20260403050717
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/.turbo/turbo-build.log +4 -0
- package/dist/client.d.ts +29 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -0
- package/dist/ice.d.ts +17 -0
- package/dist/ice.d.ts.map +1 -0
- package/dist/ice.js +63 -0
- package/dist/ice.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/invoice.d.ts +129 -0
- package/dist/invoice.d.ts.map +1 -0
- package/dist/invoice.js +36 -0
- package/dist/invoice.js.map +1 -0
- package/dist/product.d.ts +20 -0
- package/dist/product.d.ts.map +1 -0
- package/dist/product.js +2 -0
- package/dist/product.js.map +1 -0
- package/dist/schemas/client.schema.d.ts +34 -0
- package/dist/schemas/client.schema.d.ts.map +1 -0
- package/dist/schemas/client.schema.js +13 -0
- package/dist/schemas/client.schema.js.map +1 -0
- package/dist/schemas/invoice.schema.d.ts +204 -0
- package/dist/schemas/invoice.schema.d.ts.map +1 -0
- package/dist/schemas/invoice.schema.js +44 -0
- package/dist/schemas/invoice.schema.js.map +1 -0
- package/dist/sri.d.ts +46 -0
- package/dist/sri.d.ts.map +1 -0
- package/dist/sri.js +21 -0
- package/dist/sri.js.map +1 -0
- package/dist/user.d.ts +41 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +2 -0
- package/dist/user.js.map +1 -0
- package/package.json +32 -0
- package/src/client.ts +30 -0
- package/src/ice.ts +71 -0
- package/src/index.ts +15 -0
- package/src/invoice.ts +137 -0
- package/src/product.ts +16 -0
- package/src/schemas/client.schema.ts +15 -0
- package/src/schemas/invoice.schema.ts +56 -0
- package/src/sri.ts +54 -0
- package/src/user.ts +44 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const invoiceItemSchema = z.object({
|
|
3
|
+
codigoPrincipal: z.string().max(25),
|
|
4
|
+
descripcion: z.string().min(1).max(300),
|
|
5
|
+
cantidad: z.number().positive(),
|
|
6
|
+
precioUnitario: z.number().nonnegative(),
|
|
7
|
+
descuento: z.number().nonnegative().default(0),
|
|
8
|
+
codigoPorcentajeIva: z.enum(['0', '2', '3', '4', '5', '8']),
|
|
9
|
+
iceCodigoPorcentaje: z.string().max(4).optional(),
|
|
10
|
+
iceTarifa: z.number().nonnegative().optional(),
|
|
11
|
+
detallesAdicionales: z
|
|
12
|
+
.array(z.object({ nombre: z.string().min(1).max(100), valor: z.string().min(1).max(300) }))
|
|
13
|
+
.max(3)
|
|
14
|
+
.optional(),
|
|
15
|
+
});
|
|
16
|
+
/** Valid SRI payment method codes — Ficha Tecnica v2.30, Formas de Pago Vigentes */
|
|
17
|
+
export const SRI_PAYMENT_CODES = ['01', '15', '16', '17', '18', '19', '20', '21'];
|
|
18
|
+
export const paymentDetailSchema = z.object({
|
|
19
|
+
formaPago: z.enum(SRI_PAYMENT_CODES),
|
|
20
|
+
total: z.number().positive(),
|
|
21
|
+
plazo: z.number().nonnegative().optional(),
|
|
22
|
+
unidadTiempo: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
export const createInvoiceSchema = z.object({
|
|
25
|
+
// Buyer
|
|
26
|
+
tipoIdentificacionComprador: z.enum(['04', '05', '06', '07', '08']),
|
|
27
|
+
identificacionComprador: z.string().min(1).max(20),
|
|
28
|
+
razonSocialComprador: z.string().min(1).max(300),
|
|
29
|
+
emailComprador: z.string().email().optional(),
|
|
30
|
+
telefonoComprador: z.string().optional(),
|
|
31
|
+
// Date
|
|
32
|
+
fechaEmision: z.string().regex(/^\d{2}\/\d{2}\/\d{4}$/, 'Format: dd/MM/yyyy'),
|
|
33
|
+
// Items
|
|
34
|
+
items: z.array(invoiceItemSchema).min(1),
|
|
35
|
+
// Payment
|
|
36
|
+
pagos: z.array(paymentDetailSchema).min(1),
|
|
37
|
+
// Optional
|
|
38
|
+
propina: z.number().nonnegative().default(0),
|
|
39
|
+
infoAdicional: z.record(z.string()).optional(),
|
|
40
|
+
// Delivery preferences
|
|
41
|
+
sendEmail: z.boolean().default(true),
|
|
42
|
+
sendWhatsApp: z.boolean().default(false),
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=invoice.schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice.schema.js","sourceRoot":"","sources":["../../src/schemas/invoice.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;IACxC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9C,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3D,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC9C,mBAAmB,EAAE,CAAC;SACnB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAC1F,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;CACd,CAAC,CAAA;AAEF,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAA;AAI1F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC1C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,QAAQ;IACR,2BAA2B,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnE,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAClD,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAChD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAC7C,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAExC,OAAO;IACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,uBAAuB,EAAE,oBAAoB,CAAC;IAE7E,QAAQ;IACR,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAExC,UAAU;IACV,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE1C,WAAW;IACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAE9C,uBAAuB;IACvB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACpC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACzC,CAAC,CAAA"}
|
package/dist/sri.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SriAuthStatus } from './invoice.js';
|
|
2
|
+
/** SRI SOAP reception response */
|
|
3
|
+
export interface SriRecepcionResponse {
|
|
4
|
+
estado: 'RECIBIDA' | 'DEVUELTA';
|
|
5
|
+
comprobantes: {
|
|
6
|
+
claveAcceso: string;
|
|
7
|
+
mensajes: SriMensaje[];
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
/** SRI SOAP authorization response */
|
|
11
|
+
export interface SriAutorizacionResponse {
|
|
12
|
+
estado: SriAuthStatus;
|
|
13
|
+
numeroAutorizacion: string;
|
|
14
|
+
fechaAutorizacion: string;
|
|
15
|
+
ambiente: string;
|
|
16
|
+
comprobante: string;
|
|
17
|
+
mensajes: SriMensaje[];
|
|
18
|
+
}
|
|
19
|
+
/** SRI error/warning message */
|
|
20
|
+
export interface SriMensaje {
|
|
21
|
+
identificador: string;
|
|
22
|
+
mensaje: string;
|
|
23
|
+
informacionAdicional?: string;
|
|
24
|
+
tipo: 'ERROR' | 'ADVERTENCIA' | 'INFORMATIVO';
|
|
25
|
+
}
|
|
26
|
+
/** Common SRI error codes */
|
|
27
|
+
export declare const SRI_ERROR_CODES: {
|
|
28
|
+
readonly CLAVE_REGISTRADA: "35";
|
|
29
|
+
readonly FECHA_NO_CORRESPONDE: "43";
|
|
30
|
+
readonly RUC_INACTIVO: "46";
|
|
31
|
+
readonly TOTAL_INCORRECTO: "65";
|
|
32
|
+
readonly CERTIFICADO_INVALIDO: "70";
|
|
33
|
+
readonly FIRMA_NO_VALIDA: "72";
|
|
34
|
+
};
|
|
35
|
+
/** SRI environment URLs */
|
|
36
|
+
export declare const SRI_URLS: {
|
|
37
|
+
readonly TEST: {
|
|
38
|
+
readonly RECEPCION: "https://celcer.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl";
|
|
39
|
+
readonly AUTORIZACION: "https://celcer.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl";
|
|
40
|
+
};
|
|
41
|
+
readonly PRODUCTION: {
|
|
42
|
+
readonly RECEPCION: "https://cel.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl";
|
|
43
|
+
readonly AUTORIZACION: "https://cel.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=sri.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sri.d.ts","sourceRoot":"","sources":["../src/sri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAA;IAC/B,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,EAAE,UAAU,EAAE,CAAA;KACvB,EAAE,CAAA;CACJ;AAED,sCAAsC;AACtC,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAA;CACvB;AAED,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,CAAA;CAC9C;AAED,6BAA6B;AAC7B,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAA;AAEV,2BAA2B;AAC3B,eAAO,MAAM,QAAQ;;;;;;;;;CAaX,CAAA"}
|
package/dist/sri.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Common SRI error codes */
|
|
2
|
+
export const SRI_ERROR_CODES = {
|
|
3
|
+
CLAVE_REGISTRADA: '35',
|
|
4
|
+
FECHA_NO_CORRESPONDE: '43',
|
|
5
|
+
RUC_INACTIVO: '46',
|
|
6
|
+
TOTAL_INCORRECTO: '65',
|
|
7
|
+
CERTIFICADO_INVALIDO: '70',
|
|
8
|
+
FIRMA_NO_VALIDA: '72',
|
|
9
|
+
};
|
|
10
|
+
/** SRI environment URLs */
|
|
11
|
+
export const SRI_URLS = {
|
|
12
|
+
TEST: {
|
|
13
|
+
RECEPCION: 'https://celcer.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl',
|
|
14
|
+
AUTORIZACION: 'https://celcer.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl',
|
|
15
|
+
},
|
|
16
|
+
PRODUCTION: {
|
|
17
|
+
RECEPCION: 'https://cel.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl',
|
|
18
|
+
AUTORIZACION: 'https://cel.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=sri.js.map
|
package/dist/sri.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sri.js","sourceRoot":"","sources":["../src/sri.ts"],"names":[],"mappings":"AA6BA,6BAA6B;AAC7B,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,gBAAgB,EAAE,IAAI;IACtB,oBAAoB,EAAE,IAAI;IAC1B,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,oBAAoB,EAAE,IAAI;IAC1B,eAAe,EAAE,IAAI;CACb,CAAA;AAEV,2BAA2B;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE;QACJ,SAAS,EACP,0FAA0F;QAC5F,YAAY,EACV,6FAA6F;KAChG;IACD,UAAU,EAAE;QACV,SAAS,EACP,uFAAuF;QACzF,YAAY,EACV,0FAA0F;KAC7F;CACO,CAAA"}
|
package/dist/user.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** User roles in the system */
|
|
2
|
+
export type UserRole = 'owner' | 'accountant' | 'employee';
|
|
3
|
+
/** RIMPE regime type */
|
|
4
|
+
export type RimpeRegime = 'emprendedor' | 'negocio_popular' | null;
|
|
5
|
+
/** Organization (a business entity with a RUC) */
|
|
6
|
+
export interface Organization {
|
|
7
|
+
id: string;
|
|
8
|
+
ruc: string;
|
|
9
|
+
razonSocial: string;
|
|
10
|
+
nombreComercial?: string;
|
|
11
|
+
direccionMatriz: string;
|
|
12
|
+
estab: string;
|
|
13
|
+
ptoEmi: string;
|
|
14
|
+
obligadoContabilidad: boolean;
|
|
15
|
+
regimenRimpe: RimpeRegime;
|
|
16
|
+
ambiente: '1' | '2';
|
|
17
|
+
preciosIncluyenIva: boolean;
|
|
18
|
+
telefono?: string;
|
|
19
|
+
contactEmail?: string;
|
|
20
|
+
logoUrl?: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
/** Organization membership (user <-> org relationship) */
|
|
25
|
+
export interface OrgMember {
|
|
26
|
+
id: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
organizationId: string;
|
|
29
|
+
role: UserRole;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
}
|
|
32
|
+
/** User profile */
|
|
33
|
+
export interface UserProfile {
|
|
34
|
+
id: string;
|
|
35
|
+
email: string;
|
|
36
|
+
nombreCompleto: string;
|
|
37
|
+
telefono?: string;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
updatedAt: string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,CAAA;AAE1D,wBAAwB;AACxB,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAAA;AAElE,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,oBAAoB,EAAE,OAAO,CAAA;IAC7B,YAAY,EAAE,WAAW,CAAA;IACzB,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAA;IACnB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,mBAAmB;AACnB,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB"}
|
package/dist/user.js
ADDED
package/dist/user.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../src/user.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@timbra-ec/types",
|
|
3
|
+
"version": "0.1.0-dev.20260403050717",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/timbra-ec/timbra-app.git",
|
|
10
|
+
"directory": "packages/types"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"zod": "^3.24.2"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^5.8.2"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"lint": "echo 'no lint configured yet'"
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** SRI identification type codes */
|
|
2
|
+
export const ID_TYPES = {
|
|
3
|
+
RUC: '04',
|
|
4
|
+
CEDULA: '05',
|
|
5
|
+
PASAPORTE: '06',
|
|
6
|
+
CONSUMIDOR_FINAL: '07',
|
|
7
|
+
EXTERIOR: '08',
|
|
8
|
+
} as const
|
|
9
|
+
|
|
10
|
+
export type IdTypeCode = (typeof ID_TYPES)[keyof typeof ID_TYPES]
|
|
11
|
+
|
|
12
|
+
/** Client / customer of a business */
|
|
13
|
+
export interface Client {
|
|
14
|
+
id: string
|
|
15
|
+
organizationId: string
|
|
16
|
+
tipoIdentificacion: IdTypeCode
|
|
17
|
+
identificacion: string
|
|
18
|
+
razonSocial: string
|
|
19
|
+
nombreComercial?: string
|
|
20
|
+
direccion?: string
|
|
21
|
+
email?: string
|
|
22
|
+
telefono?: string
|
|
23
|
+
tags?: string[]
|
|
24
|
+
notes?: string
|
|
25
|
+
preferredPaymentMethod?: string
|
|
26
|
+
sendEmailDefault: boolean
|
|
27
|
+
sendWhatsappDefault: boolean
|
|
28
|
+
createdAt: string
|
|
29
|
+
updatedAt: string
|
|
30
|
+
}
|
package/src/ice.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** SRI ICE (Impuesto a los Consumos Especiales) tax categories.
|
|
2
|
+
* codigo = '3' (ICE) per SRI ficha tecnica.
|
|
3
|
+
* Rates are approximate — consult SRI tables for current values. */
|
|
4
|
+
|
|
5
|
+
export interface IceCategory {
|
|
6
|
+
codigo: '3'
|
|
7
|
+
codigoPorcentaje: string
|
|
8
|
+
descripcion: string
|
|
9
|
+
tarifa: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Common ICE categories. codigoPorcentaje values align with SRI Anexo 7.
|
|
14
|
+
* Not exhaustive — covers the most common product types that carry ICE.
|
|
15
|
+
*/
|
|
16
|
+
export const ICE_CATEGORIES: IceCategory[] = [
|
|
17
|
+
{ codigo: '3', codigoPorcentaje: '3011', descripcion: 'Bebidas alcoholicas', tarifa: 75 },
|
|
18
|
+
{ codigo: '3', codigoPorcentaje: '3021', descripcion: 'Cerveza artesanal', tarifa: 20 },
|
|
19
|
+
{ codigo: '3', codigoPorcentaje: '3023', descripcion: 'Cerveza industrial', tarifa: 75 },
|
|
20
|
+
{ codigo: '3', codigoPorcentaje: '3031', descripcion: 'Cigarrillos', tarifa: 150 },
|
|
21
|
+
{ codigo: '3', codigoPorcentaje: '3041', descripcion: 'Bebidas gaseosas', tarifa: 10 },
|
|
22
|
+
{
|
|
23
|
+
codigo: '3',
|
|
24
|
+
codigoPorcentaje: '3051',
|
|
25
|
+
descripcion: 'Bebidas energizantes',
|
|
26
|
+
tarifa: 10,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
codigo: '3',
|
|
30
|
+
codigoPorcentaje: '3072',
|
|
31
|
+
descripcion: 'Vehiculos motorizados (hasta 20k)',
|
|
32
|
+
tarifa: 5,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
codigo: '3',
|
|
36
|
+
codigoPorcentaje: '3073',
|
|
37
|
+
descripcion: 'Vehiculos motorizados (20k-30k)',
|
|
38
|
+
tarifa: 10,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
codigo: '3',
|
|
42
|
+
codigoPorcentaje: '3074',
|
|
43
|
+
descripcion: 'Vehiculos motorizados (30k-40k)',
|
|
44
|
+
tarifa: 15,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
codigo: '3',
|
|
48
|
+
codigoPorcentaje: '3075',
|
|
49
|
+
descripcion: 'Vehiculos motorizados (40k-50k)',
|
|
50
|
+
tarifa: 20,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
codigo: '3',
|
|
54
|
+
codigoPorcentaje: '3076',
|
|
55
|
+
descripcion: 'Vehiculos motorizados (50k-60k)',
|
|
56
|
+
tarifa: 25,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
codigo: '3',
|
|
60
|
+
codigoPorcentaje: '3077',
|
|
61
|
+
descripcion: 'Vehiculos motorizados (60k-70k)',
|
|
62
|
+
tarifa: 30,
|
|
63
|
+
},
|
|
64
|
+
{ codigo: '3', codigoPorcentaje: '3092', descripcion: 'Perfumes y aguas de tocador', tarifa: 20 },
|
|
65
|
+
{ codigo: '3', codigoPorcentaje: '3610', descripcion: 'Fundas plasticas', tarifa: 0.04 },
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
/** Lookup an ICE category by codigoPorcentaje */
|
|
69
|
+
export function getIceCategory(codigoPorcentaje: string): IceCategory | undefined {
|
|
70
|
+
return ICE_CATEGORIES.find((c) => c.codigoPorcentaje === codigoPorcentaje)
|
|
71
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @timbra-ec/types — Shared type definitions and Zod schemas
|
|
2
|
+
// This package is the stability anchor for the entire monorepo.
|
|
3
|
+
// All other packages depend on these types.
|
|
4
|
+
|
|
5
|
+
// Re-export all types
|
|
6
|
+
export * from './invoice.js'
|
|
7
|
+
export * from './client.js'
|
|
8
|
+
export * from './product.js'
|
|
9
|
+
export * from './user.js'
|
|
10
|
+
export * from './sri.js'
|
|
11
|
+
export * from './ice.js'
|
|
12
|
+
|
|
13
|
+
// Re-export schemas
|
|
14
|
+
export * from './schemas/invoice.schema.js'
|
|
15
|
+
export * from './schemas/client.schema.js'
|
package/src/invoice.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { SriMensaje } from './sri.js'
|
|
2
|
+
|
|
3
|
+
/** SRI Document type codes */
|
|
4
|
+
export type DocumentTypeCode = '01' | '03' | '04' | '05' | '06' | '07'
|
|
5
|
+
|
|
6
|
+
export const DOCUMENT_TYPES = {
|
|
7
|
+
FACTURA: '01',
|
|
8
|
+
LIQUIDACION_COMPRA: '03',
|
|
9
|
+
NOTA_CREDITO: '04',
|
|
10
|
+
NOTA_DEBITO: '05',
|
|
11
|
+
GUIA_REMISION: '06',
|
|
12
|
+
COMPROBANTE_RETENCION: '07',
|
|
13
|
+
} as const
|
|
14
|
+
|
|
15
|
+
/** SRI IVA rate codes */
|
|
16
|
+
export const IVA_RATES = {
|
|
17
|
+
/** 0% IVA */
|
|
18
|
+
ZERO: { codigoPorcentaje: '0', tarifa: '0.00' },
|
|
19
|
+
/** 12% IVA (historical, pre-2024) */
|
|
20
|
+
TWELVE: { codigoPorcentaje: '2', tarifa: '12.00' },
|
|
21
|
+
/** 14% IVA (historical) */
|
|
22
|
+
FOURTEEN: { codigoPorcentaje: '3', tarifa: '14.00' },
|
|
23
|
+
/** 15% IVA (current since 2024) */
|
|
24
|
+
FIFTEEN: { codigoPorcentaje: '4', tarifa: '15.00' },
|
|
25
|
+
/** 5% IVA (special reduced rate) — SRI Ficha Tecnica v2.30 Tabla 17, code 5 */
|
|
26
|
+
FIVE: { codigoPorcentaje: '5', tarifa: '5.00' },
|
|
27
|
+
/** 8% IVA diferenciado (tourism, up to 12 days/year by executive decree) — SRI Tabla 17 code 8 */
|
|
28
|
+
EIGHT: { codigoPorcentaje: '8', tarifa: '8.00' },
|
|
29
|
+
} as const
|
|
30
|
+
|
|
31
|
+
/** Payment method codes — SRI Ficha Tecnica v2.30, Formas de Pago Vigentes */
|
|
32
|
+
export const PAYMENT_METHODS = {
|
|
33
|
+
EFECTIVO: '01', // Sin utilizacion del sistema financiero
|
|
34
|
+
COMPENSACION_DEUDAS: '15',
|
|
35
|
+
TARJETA_DEBITO: '16',
|
|
36
|
+
DINERO_ELECTRONICO: '17',
|
|
37
|
+
TARJETA_PREPAGO: '18',
|
|
38
|
+
TARJETA_CREDITO: '19',
|
|
39
|
+
/** "Otros con utilizacion del sistema financiero" — covers bank transfers */
|
|
40
|
+
TRANSFERENCIA: '20',
|
|
41
|
+
ENDOSO_TITULOS: '21',
|
|
42
|
+
} as const
|
|
43
|
+
|
|
44
|
+
/** SRI environment */
|
|
45
|
+
export type SriEnvironment = '1' | '2' // 1=pruebas, 2=produccion
|
|
46
|
+
|
|
47
|
+
/** SRI emission type */
|
|
48
|
+
export type EmissionType = '1' | '2' // 1=normal, 2=contingencia
|
|
49
|
+
|
|
50
|
+
/** SRI authorization status */
|
|
51
|
+
export type SriAuthStatus =
|
|
52
|
+
| 'PENDIENTE'
|
|
53
|
+
| 'RECIBIDA'
|
|
54
|
+
| 'DEVUELTA'
|
|
55
|
+
| 'AUTORIZADO'
|
|
56
|
+
| 'NO AUTORIZADO'
|
|
57
|
+
| 'EN PROCESO'
|
|
58
|
+
| 'ANULADO'
|
|
59
|
+
| 'FALLIDO'
|
|
60
|
+
|
|
61
|
+
/** Invoice line item */
|
|
62
|
+
export interface InvoiceItem {
|
|
63
|
+
codigoPrincipal: string
|
|
64
|
+
descripcion: string
|
|
65
|
+
cantidad: number
|
|
66
|
+
precioUnitario: number
|
|
67
|
+
descuento: number
|
|
68
|
+
precioTotalSinImpuesto: number
|
|
69
|
+
impuestos: {
|
|
70
|
+
codigo: string // '2' = IVA
|
|
71
|
+
codigoPorcentaje: string
|
|
72
|
+
tarifa: number
|
|
73
|
+
baseImponible: number
|
|
74
|
+
valor: number
|
|
75
|
+
}[]
|
|
76
|
+
detallesAdicionales?: { nombre: string; valor: string }[]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Payment detail */
|
|
80
|
+
export interface PaymentDetail {
|
|
81
|
+
formaPago: string
|
|
82
|
+
total: number
|
|
83
|
+
plazo?: number
|
|
84
|
+
unidadTiempo?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Core invoice data */
|
|
88
|
+
export interface Invoice {
|
|
89
|
+
id: string
|
|
90
|
+
organizationId: string
|
|
91
|
+
claveAcceso: string
|
|
92
|
+
codDoc: DocumentTypeCode
|
|
93
|
+
estab: string
|
|
94
|
+
ptoEmi: string
|
|
95
|
+
secuencial: string
|
|
96
|
+
fechaEmision: string
|
|
97
|
+
ambiente: SriEnvironment
|
|
98
|
+
tipoEmision: EmissionType
|
|
99
|
+
|
|
100
|
+
// Buyer
|
|
101
|
+
tipoIdentificacionComprador: string
|
|
102
|
+
identificacionComprador: string
|
|
103
|
+
razonSocialComprador: string
|
|
104
|
+
|
|
105
|
+
// Totals
|
|
106
|
+
totalSinImpuestos: number
|
|
107
|
+
totalDescuento: number
|
|
108
|
+
propina: number
|
|
109
|
+
importeTotal: number
|
|
110
|
+
moneda: string
|
|
111
|
+
|
|
112
|
+
// Details
|
|
113
|
+
items: InvoiceItem[]
|
|
114
|
+
pagos: PaymentDetail[]
|
|
115
|
+
infoAdicional?: Record<string, string>
|
|
116
|
+
|
|
117
|
+
// Status
|
|
118
|
+
sriStatus: SriAuthStatus
|
|
119
|
+
sriMensajes?: SriMensaje[]
|
|
120
|
+
numeroAutorizacion?: string
|
|
121
|
+
fechaAutorizacion?: string
|
|
122
|
+
authorizedXmlUrl?: string
|
|
123
|
+
ridePdfUrl?: string
|
|
124
|
+
|
|
125
|
+
/** Transport data for guia de remision (cod_doc='06'), stored as jsonb */
|
|
126
|
+
guiaData?: Record<string, unknown>
|
|
127
|
+
/** Fiscal period MM/YYYY for retenciones (cod_doc='07') */
|
|
128
|
+
periodoFiscal?: string
|
|
129
|
+
|
|
130
|
+
// Retry tracking
|
|
131
|
+
retryCount: number
|
|
132
|
+
retryAfter?: string
|
|
133
|
+
lastSriError?: string
|
|
134
|
+
|
|
135
|
+
createdAt: string
|
|
136
|
+
updatedAt: string
|
|
137
|
+
}
|
package/src/product.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Product or service in a business catalog */
|
|
2
|
+
export interface Product {
|
|
3
|
+
id: string
|
|
4
|
+
organizationId: string
|
|
5
|
+
codigoPrincipal: string
|
|
6
|
+
descripcion: string
|
|
7
|
+
precioUnitario: number
|
|
8
|
+
codigoPorcentajeIva: string // '0', '2', '3', '4', '5', '8' — SRI Ficha Tecnica v2.30 Tabla 17
|
|
9
|
+
detallesAdicionales?: { nombre: string; valor: string }[]
|
|
10
|
+
iceCodigoPorcentaje?: string
|
|
11
|
+
iceTarifa?: number
|
|
12
|
+
activo: boolean
|
|
13
|
+
lastUsedAt?: string
|
|
14
|
+
createdAt: string
|
|
15
|
+
updatedAt: string
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
export const createClientSchema = z.object({
|
|
4
|
+
tipoIdentificacion: z.enum(['04', '05', '06', '07', '08']),
|
|
5
|
+
identificacion: z.string().min(1).max(20),
|
|
6
|
+
razonSocial: z.string().min(1).max(300),
|
|
7
|
+
nombreComercial: z.string().max(300).optional(),
|
|
8
|
+
direccion: z.string().max(300).optional(),
|
|
9
|
+
email: z.string().email(),
|
|
10
|
+
telefono: z.string().max(20).optional(),
|
|
11
|
+
tags: z.array(z.string()).optional(),
|
|
12
|
+
notes: z.string().max(500).optional(),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export type CreateClientInput = z.infer<typeof createClientSchema>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
export const invoiceItemSchema = z.object({
|
|
4
|
+
codigoPrincipal: z.string().max(25),
|
|
5
|
+
descripcion: z.string().min(1).max(300),
|
|
6
|
+
cantidad: z.number().positive(),
|
|
7
|
+
precioUnitario: z.number().nonnegative(),
|
|
8
|
+
descuento: z.number().nonnegative().default(0),
|
|
9
|
+
codigoPorcentajeIva: z.enum(['0', '2', '3', '4', '5', '8']),
|
|
10
|
+
iceCodigoPorcentaje: z.string().max(4).optional(),
|
|
11
|
+
iceTarifa: z.number().nonnegative().optional(),
|
|
12
|
+
detallesAdicionales: z
|
|
13
|
+
.array(z.object({ nombre: z.string().min(1).max(100), valor: z.string().min(1).max(300) }))
|
|
14
|
+
.max(3)
|
|
15
|
+
.optional(),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
/** Valid SRI payment method codes — Ficha Tecnica v2.30, Formas de Pago Vigentes */
|
|
19
|
+
export const SRI_PAYMENT_CODES = ['01', '15', '16', '17', '18', '19', '20', '21'] as const
|
|
20
|
+
|
|
21
|
+
export type SriPaymentCode = (typeof SRI_PAYMENT_CODES)[number]
|
|
22
|
+
|
|
23
|
+
export const paymentDetailSchema = z.object({
|
|
24
|
+
formaPago: z.enum(SRI_PAYMENT_CODES),
|
|
25
|
+
total: z.number().positive(),
|
|
26
|
+
plazo: z.number().nonnegative().optional(),
|
|
27
|
+
unidadTiempo: z.string().optional(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
export const createInvoiceSchema = z.object({
|
|
31
|
+
// Buyer
|
|
32
|
+
tipoIdentificacionComprador: z.enum(['04', '05', '06', '07', '08']),
|
|
33
|
+
identificacionComprador: z.string().min(1).max(20),
|
|
34
|
+
razonSocialComprador: z.string().min(1).max(300),
|
|
35
|
+
emailComprador: z.string().email().optional(),
|
|
36
|
+
telefonoComprador: z.string().optional(),
|
|
37
|
+
|
|
38
|
+
// Date
|
|
39
|
+
fechaEmision: z.string().regex(/^\d{2}\/\d{2}\/\d{4}$/, 'Format: dd/MM/yyyy'),
|
|
40
|
+
|
|
41
|
+
// Items
|
|
42
|
+
items: z.array(invoiceItemSchema).min(1),
|
|
43
|
+
|
|
44
|
+
// Payment
|
|
45
|
+
pagos: z.array(paymentDetailSchema).min(1),
|
|
46
|
+
|
|
47
|
+
// Optional
|
|
48
|
+
propina: z.number().nonnegative().default(0),
|
|
49
|
+
infoAdicional: z.record(z.string()).optional(),
|
|
50
|
+
|
|
51
|
+
// Delivery preferences
|
|
52
|
+
sendEmail: z.boolean().default(true),
|
|
53
|
+
sendWhatsApp: z.boolean().default(false),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export type CreateInvoiceInput = z.infer<typeof createInvoiceSchema>
|
package/src/sri.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SriAuthStatus } from './invoice.js'
|
|
2
|
+
|
|
3
|
+
/** SRI SOAP reception response */
|
|
4
|
+
export interface SriRecepcionResponse {
|
|
5
|
+
estado: 'RECIBIDA' | 'DEVUELTA'
|
|
6
|
+
comprobantes: {
|
|
7
|
+
claveAcceso: string
|
|
8
|
+
mensajes: SriMensaje[]
|
|
9
|
+
}[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** SRI SOAP authorization response */
|
|
13
|
+
export interface SriAutorizacionResponse {
|
|
14
|
+
estado: SriAuthStatus
|
|
15
|
+
numeroAutorizacion: string
|
|
16
|
+
fechaAutorizacion: string
|
|
17
|
+
ambiente: string
|
|
18
|
+
comprobante: string // the authorized XML as string
|
|
19
|
+
mensajes: SriMensaje[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** SRI error/warning message */
|
|
23
|
+
export interface SriMensaje {
|
|
24
|
+
identificador: string
|
|
25
|
+
mensaje: string
|
|
26
|
+
informacionAdicional?: string
|
|
27
|
+
tipo: 'ERROR' | 'ADVERTENCIA' | 'INFORMATIVO'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Common SRI error codes */
|
|
31
|
+
export const SRI_ERROR_CODES = {
|
|
32
|
+
CLAVE_REGISTRADA: '35',
|
|
33
|
+
FECHA_NO_CORRESPONDE: '43',
|
|
34
|
+
RUC_INACTIVO: '46',
|
|
35
|
+
TOTAL_INCORRECTO: '65',
|
|
36
|
+
CERTIFICADO_INVALIDO: '70',
|
|
37
|
+
FIRMA_NO_VALIDA: '72',
|
|
38
|
+
} as const
|
|
39
|
+
|
|
40
|
+
/** SRI environment URLs */
|
|
41
|
+
export const SRI_URLS = {
|
|
42
|
+
TEST: {
|
|
43
|
+
RECEPCION:
|
|
44
|
+
'https://celcer.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl',
|
|
45
|
+
AUTORIZACION:
|
|
46
|
+
'https://celcer.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl',
|
|
47
|
+
},
|
|
48
|
+
PRODUCTION: {
|
|
49
|
+
RECEPCION:
|
|
50
|
+
'https://cel.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl',
|
|
51
|
+
AUTORIZACION:
|
|
52
|
+
'https://cel.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl',
|
|
53
|
+
},
|
|
54
|
+
} as const
|
package/src/user.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** User roles in the system */
|
|
2
|
+
export type UserRole = 'owner' | 'accountant' | 'employee'
|
|
3
|
+
|
|
4
|
+
/** RIMPE regime type */
|
|
5
|
+
export type RimpeRegime = 'emprendedor' | 'negocio_popular' | null
|
|
6
|
+
|
|
7
|
+
/** Organization (a business entity with a RUC) */
|
|
8
|
+
export interface Organization {
|
|
9
|
+
id: string
|
|
10
|
+
ruc: string
|
|
11
|
+
razonSocial: string
|
|
12
|
+
nombreComercial?: string
|
|
13
|
+
direccionMatriz: string
|
|
14
|
+
estab: string // default '001'
|
|
15
|
+
ptoEmi: string // default '001'
|
|
16
|
+
obligadoContabilidad: boolean
|
|
17
|
+
regimenRimpe: RimpeRegime
|
|
18
|
+
ambiente: '1' | '2' // 1=pruebas, 2=produccion
|
|
19
|
+
preciosIncluyenIva: boolean
|
|
20
|
+
telefono?: string
|
|
21
|
+
contactEmail?: string
|
|
22
|
+
logoUrl?: string
|
|
23
|
+
createdAt: string
|
|
24
|
+
updatedAt: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Organization membership (user <-> org relationship) */
|
|
28
|
+
export interface OrgMember {
|
|
29
|
+
id: string
|
|
30
|
+
userId: string
|
|
31
|
+
organizationId: string
|
|
32
|
+
role: UserRole
|
|
33
|
+
createdAt: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** User profile */
|
|
37
|
+
export interface UserProfile {
|
|
38
|
+
id: string
|
|
39
|
+
email: string
|
|
40
|
+
nombreCompleto: string
|
|
41
|
+
telefono?: string
|
|
42
|
+
createdAt: string
|
|
43
|
+
updatedAt: string
|
|
44
|
+
}
|