@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.
Files changed (48) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/dist/client.d.ts +29 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +9 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/ice.d.ts +17 -0
  7. package/dist/ice.d.ts.map +1 -0
  8. package/dist/ice.js +63 -0
  9. package/dist/ice.js.map +1 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +14 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/invoice.d.ts +129 -0
  15. package/dist/invoice.d.ts.map +1 -0
  16. package/dist/invoice.js +36 -0
  17. package/dist/invoice.js.map +1 -0
  18. package/dist/product.d.ts +20 -0
  19. package/dist/product.d.ts.map +1 -0
  20. package/dist/product.js +2 -0
  21. package/dist/product.js.map +1 -0
  22. package/dist/schemas/client.schema.d.ts +34 -0
  23. package/dist/schemas/client.schema.d.ts.map +1 -0
  24. package/dist/schemas/client.schema.js +13 -0
  25. package/dist/schemas/client.schema.js.map +1 -0
  26. package/dist/schemas/invoice.schema.d.ts +204 -0
  27. package/dist/schemas/invoice.schema.d.ts.map +1 -0
  28. package/dist/schemas/invoice.schema.js +44 -0
  29. package/dist/schemas/invoice.schema.js.map +1 -0
  30. package/dist/sri.d.ts +46 -0
  31. package/dist/sri.d.ts.map +1 -0
  32. package/dist/sri.js +21 -0
  33. package/dist/sri.js.map +1 -0
  34. package/dist/user.d.ts +41 -0
  35. package/dist/user.d.ts.map +1 -0
  36. package/dist/user.js +2 -0
  37. package/dist/user.js.map +1 -0
  38. package/package.json +32 -0
  39. package/src/client.ts +30 -0
  40. package/src/ice.ts +71 -0
  41. package/src/index.ts +15 -0
  42. package/src/invoice.ts +137 -0
  43. package/src/product.ts +16 -0
  44. package/src/schemas/client.schema.ts +15 -0
  45. package/src/schemas/invoice.schema.ts +56 -0
  46. package/src/sri.ts +54 -0
  47. package/src/user.ts +44 -0
  48. 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":"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"}
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
@@ -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
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=user.js.map
@@ -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
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "@timbra-ec/config-ts/library.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src"]
8
+ }