evo360-types 1.3.514 → 1.3.518

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.
@@ -739,3 +739,185 @@ export const zServiceInvoiceSchema = zFireDocSchema
739
739
  snapshots: z.array(zProviderPayloadSnapshotSchema).optional(),
740
740
  })
741
741
  .passthrough();
742
+
743
+ // ---- Nexus FinOps Proposal (feat-128) ----
744
+
745
+ export const zNexFinopsProposalStatusSchema = z.enum([
746
+ "draft",
747
+ "sent",
748
+ "viewed",
749
+ "accepted",
750
+ "expired",
751
+ "canceled",
752
+ ]);
753
+
754
+ export const zNexFinopsProposalPaymentMethodSchema = z.enum([
755
+ "boleto",
756
+ "card_subscription",
757
+ "payment_link",
758
+ ]);
759
+
760
+ export const zNexFinopsProposalPrefillSchema = z
761
+ .object({
762
+ name: z.string().max(255).nullable().optional(),
763
+ email: z.string().max(255).nullable().optional(),
764
+ phone: z.string().max(50).nullable().optional(),
765
+ company: z.string().max(255).nullable().optional(),
766
+ })
767
+ .passthrough();
768
+
769
+ /**
770
+ * Payload de escrita da proposta (fronteira HTTP). Campos opcionais usam
771
+ * `.nullable()` além de `.optional()` porque o cliente pode mandar `null`
772
+ * explícito (Vuetify `clearable` grava null; callable converte undefined em null).
773
+ *
774
+ * `short_code`, `status` e `currency` NÃO entram aqui: são resolvidos no servidor.
775
+ */
776
+ export const zNexFinopsProposalWriteSchema = z
777
+ .object({
778
+ origem: z.string().min(1).max(64).optional(),
779
+ customer_id: z.string().max(128).nullable().optional(),
780
+ customer_ref: z.string().max(512).nullable().optional(),
781
+ prefill: zNexFinopsProposalPrefillSchema.nullable().optional(),
782
+ name: z.string().max(255).nullable().optional(),
783
+ html_content: z.string().optional(),
784
+ base_amount: z.number().nonnegative().optional(),
785
+ due_day: z.number().int().min(1).max(31).optional(),
786
+ accepted_payment_methods: z.array(zNexFinopsProposalPaymentMethodSchema).optional(),
787
+ terms: z.string().nullable().optional(),
788
+ valid_until: z
789
+ .string()
790
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "valid_until must be an ISO date (YYYY-MM-DD)")
791
+ .optional(),
792
+ notes: z.string().nullable().optional(),
793
+ })
794
+ .strip();
795
+
796
+ export const zNexFinopsProposalSchema = zNexFinopsProposalWriteSchema.extend({
797
+ short_code: z.string().min(1),
798
+ status: zNexFinopsProposalStatusSchema,
799
+ currency: z.literal("BRL"),
800
+ });
801
+
802
+ // ---- Nexus FinOps / Vendas Payment (feat-131) ----
803
+
804
+ export const zNexFinopsPaymentMethodSchema = z.enum([
805
+ "pix",
806
+ "boleto",
807
+ "payment_link",
808
+ "card_subscription",
809
+ ]);
810
+
811
+ export const zNexFinopsAsaasSubscriptionStatusSchema = z.enum([
812
+ "ACTIVE",
813
+ "EXPIRED",
814
+ "INACTIVE",
815
+ ]);
816
+
817
+ /**
818
+ * Vínculo contrato ↔ assinatura Asaas. O checkout é hospedado (SAQ-A): nunca
819
+ * existe campo de número completo, CCV ou token de cartão neste schema.
820
+ */
821
+ export const zNexFinopsContractAsaasInfoSchema = z
822
+ .object({
823
+ customer_id: z.string().max(128).optional().nullable(),
824
+ subscription_id: z.string().max(128).optional().nullable(),
825
+ subscription_status: zNexFinopsAsaasSubscriptionStatusSchema.optional().nullable(),
826
+ cycle: z.string().max(32).optional().nullable(),
827
+ value: z.number().nonnegative().optional().nullable(),
828
+ next_due_date: z
829
+ .string()
830
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "next_due_date must be an ISO date (YYYY-MM-DD)")
831
+ .optional()
832
+ .nullable(),
833
+ card_last4: z.string().max(4).optional().nullable(),
834
+ card_brand: z.string().max(32).optional().nullable(),
835
+ checkout_id: z.string().max(128).optional().nullable(),
836
+ env: z.enum(["sandbox", "production"]).optional().nullable(),
837
+ })
838
+ .strip();
839
+
840
+ export const zNexVendasJourneyPaymentMethodSchema = z.enum([
841
+ "card_subscription",
842
+ "boleto",
843
+ "payment_link",
844
+ ]);
845
+
846
+ export const zNexVendasJourneyPaymentKindSchema = z.enum([
847
+ "asaas_checkout",
848
+ "boleto",
849
+ "payment_link",
850
+ ]);
851
+
852
+ export const zNexVendasJourneyPaymentStateSchema = z.enum([
853
+ "none",
854
+ "awaiting_payment",
855
+ "compensating",
856
+ "paid",
857
+ ]);
858
+
859
+ /** Body de `POST /journeys/:short_code/payment`. */
860
+ export const zNexVendasJourneyPaymentChooseSchema = z
861
+ .object({
862
+ method: zNexVendasJourneyPaymentMethodSchema,
863
+ })
864
+ .strip();
865
+
866
+ export const zNexVendasJourneyBoletoSchema = z
867
+ .object({
868
+ payment_id: z.string().max(128).optional().nullable(),
869
+ invoice_url: z.string().max(2048).optional().nullable(),
870
+ bank_slip_url: z.string().max(2048).optional().nullable(),
871
+ pix_qr_code: z.string().optional().nullable(),
872
+ pix_copy_paste: z.string().optional().nullable(),
873
+ due_date: z
874
+ .string()
875
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "due_date must be an ISO date (YYYY-MM-DD)")
876
+ .optional()
877
+ .nullable(),
878
+ value: z.number().nonnegative().optional().nullable(),
879
+ })
880
+ .strip();
881
+
882
+ export const zNexVendasJourneyPaymentWebhookEventSchema = z
883
+ .object({
884
+ event: z.string().min(1).max(64),
885
+ payment_id: z.string().max(128).optional().nullable(),
886
+ payment_status: z.string().max(64).optional().nullable(),
887
+ subscription_id: z.string().max(128).optional().nullable(),
888
+ at: zFirestoreDateSchema,
889
+ })
890
+ .strip();
891
+
892
+ export const zNexVendasJourneyPaymentSupersededSchema = z
893
+ .object({
894
+ method: zNexVendasJourneyPaymentMethodSchema,
895
+ kind: zNexVendasJourneyPaymentKindSchema,
896
+ checkout_id: z.string().max(128).optional().nullable(),
897
+ payment_id: z.string().max(128).optional().nullable(),
898
+ payment_link_id: z.string().max(128).optional().nullable(),
899
+ at: zFirestoreDateSchema,
900
+ revoked: z.boolean().optional().nullable(),
901
+ })
902
+ .strip();
903
+
904
+ export const zNexVendasJourneyPaymentSchema = z
905
+ .object({
906
+ state: zNexVendasJourneyPaymentStateSchema,
907
+ method: zNexVendasJourneyPaymentMethodSchema.optional().nullable(),
908
+ kind: zNexVendasJourneyPaymentKindSchema.optional().nullable(),
909
+ checkout_id: z.string().max(128).optional().nullable(),
910
+ redirect_url: z.string().max(2048).optional().nullable(),
911
+ expires_at: zFirestoreDateSchema.optional().nullable(),
912
+ boleto: zNexVendasJourneyBoletoSchema.optional().nullable(),
913
+ payment_link_id: z.string().max(128).optional().nullable(),
914
+ link: z.string().max(2048).optional().nullable(),
915
+ first_payment_id: z.string().max(128).optional().nullable(),
916
+ subscription_id: z.string().max(128).optional().nullable(),
917
+ paid_at: zFirestoreDateSchema.optional().nullable(),
918
+ created_at: zFirestoreDateSchema.optional().nullable(),
919
+ webhook_events: z.array(zNexVendasJourneyPaymentWebhookEventSchema).optional().nullable(),
920
+ superseded: z.array(zNexVendasJourneyPaymentSupersededSchema).optional().nullable(),
921
+ last_error: z.string().optional().nullable(),
922
+ })
923
+ .strip();
@@ -44,7 +44,6 @@ export declare const zTissConfigSchema: z.ZodObject<{
44
44
  }, "strip", z.ZodTypeAny, {
45
45
  version: string;
46
46
  active: boolean;
47
- current_batch: number;
48
47
  contract: {
49
48
  name: string;
50
49
  type: "PJ" | "PF";
@@ -52,10 +51,10 @@ export declare const zTissConfigSchema: z.ZodObject<{
52
51
  taxId: string;
53
52
  cnes: string;
54
53
  };
54
+ current_batch: number;
55
55
  }, {
56
56
  version: string;
57
57
  active: boolean;
58
- current_batch: number;
59
58
  contract: {
60
59
  name: string;
61
60
  type: "PJ" | "PF";
@@ -63,6 +62,7 @@ export declare const zTissConfigSchema: z.ZodObject<{
63
62
  taxId: string;
64
63
  cnes: string;
65
64
  };
65
+ current_batch: number;
66
66
  }>;
67
67
  export declare const zInsuranceCompanySchema: z.ZodObject<{
68
68
  id: z.ZodString;
@@ -105,7 +105,6 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
105
105
  }, "strip", z.ZodTypeAny, {
106
106
  version: string;
107
107
  active: boolean;
108
- current_batch: number;
109
108
  contract: {
110
109
  name: string;
111
110
  type: "PJ" | "PF";
@@ -113,10 +112,10 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
113
112
  taxId: string;
114
113
  cnes: string;
115
114
  };
115
+ current_batch: number;
116
116
  }, {
117
117
  version: string;
118
118
  active: boolean;
119
- current_batch: number;
120
119
  contract: {
121
120
  name: string;
122
121
  type: "PJ" | "PF";
@@ -124,6 +123,7 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
124
123
  taxId: string;
125
124
  cnes: string;
126
125
  };
126
+ current_batch: number;
127
127
  }>>;
128
128
  address: z.ZodOptional<z.ZodObject<{
129
129
  name: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -241,7 +241,6 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
241
241
  }, "strip", z.ZodTypeAny, {
242
242
  version: string;
243
243
  active: boolean;
244
- current_batch: number;
245
244
  contract: {
246
245
  name: string;
247
246
  type: "PJ" | "PF";
@@ -249,10 +248,10 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
249
248
  taxId: string;
250
249
  cnes: string;
251
250
  };
251
+ current_batch: number;
252
252
  }, {
253
253
  version: string;
254
254
  active: boolean;
255
- current_batch: number;
256
255
  contract: {
257
256
  name: string;
258
257
  type: "PJ" | "PF";
@@ -260,6 +259,7 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
260
259
  taxId: string;
261
260
  cnes: string;
262
261
  };
262
+ current_batch: number;
263
263
  }>>;
264
264
  address: z.ZodOptional<z.ZodObject<{
265
265
  name: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -377,7 +377,6 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
377
377
  }, "strip", z.ZodTypeAny, {
378
378
  version: string;
379
379
  active: boolean;
380
- current_batch: number;
381
380
  contract: {
382
381
  name: string;
383
382
  type: "PJ" | "PF";
@@ -385,10 +384,10 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
385
384
  taxId: string;
386
385
  cnes: string;
387
386
  };
387
+ current_batch: number;
388
388
  }, {
389
389
  version: string;
390
390
  active: boolean;
391
- current_batch: number;
392
391
  contract: {
393
392
  name: string;
394
393
  type: "PJ" | "PF";
@@ -396,6 +395,7 @@ export declare const zInsuranceCompanySchema: z.ZodObject<{
396
395
  taxId: string;
397
396
  cnes: string;
398
397
  };
398
+ current_batch: number;
399
399
  }>>;
400
400
  address: z.ZodOptional<z.ZodObject<{
401
401
  name: z.ZodDefault<z.ZodOptional<z.ZodString>>;
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ export * from "./types/domain-events";
29
29
  export * from "./types/evo-integrations";
30
30
  export * from "./types/nex-customers";
31
31
  export * from "./types/nex-tenants";
32
+ export * from "./types/nex-vendas";
32
33
  export * from "./types/nexus-webhooks";
33
34
  export * from "./types/evo-hub-ia";
34
35
  export * from "./types/evo-mcp";
package/dist/index.js CHANGED
@@ -46,6 +46,7 @@ __exportStar(require("./types/domain-events"), exports);
46
46
  __exportStar(require("./types/evo-integrations"), exports);
47
47
  __exportStar(require("./types/nex-customers"), exports);
48
48
  __exportStar(require("./types/nex-tenants"), exports);
49
+ __exportStar(require("./types/nex-vendas"), exports);
49
50
  __exportStar(require("./types/nexus-webhooks"), exports);
50
51
  __exportStar(require("./types/evo-hub-ia"), exports);
51
52
  __exportStar(require("./types/evo-mcp"), exports);
package/dist/index.ts CHANGED
@@ -30,6 +30,7 @@ export * from "./types/domain-events";
30
30
  export * from "./types/evo-integrations";
31
31
  export * from "./types/nex-customers";
32
32
  export * from "./types/nex-tenants";
33
+ export * from "./types/nex-vendas";
33
34
  export * from "./types/nexus-webhooks";
34
35
  export * from "./types/evo-hub-ia";
35
36
  export * from "./types/evo-mcp";
@@ -7,7 +7,37 @@ import type { IFireGlobalDoc } from '../../shared';
7
7
  */
8
8
  export type NexFinopsContractStatus = 'draft' | 'active' | 'cancellation_requested' | 'inactive' | 'ended' | 'canceled';
9
9
  export type NexFinopsContractRecurrence = 'one_time' | 'monthly';
10
- export type NexFinopsPaymentMethod = 'pix' | 'boleto' | 'payment_link';
10
+ /**
11
+ * `card_subscription` entra na feat-131 para convergir com
12
+ * `NexFinopsProposalPaymentMethod`: o que a proposta aceita é o que o contrato
13
+ * registra. `pix` continua porque o operador ainda lança cobrança avulsa por pix.
14
+ */
15
+ export type NexFinopsPaymentMethod = 'pix' | 'boleto' | 'payment_link' | 'card_subscription';
16
+ /** Status da assinatura no Asaas. */
17
+ export type NexFinopsAsaasSubscriptionStatus = 'ACTIVE' | 'EXPIRED' | 'INACTIVE';
18
+ /**
19
+ * Vínculo contrato ↔ assinatura Asaas (D2). Escrito uma vez, na confirmação do
20
+ * primeiro pagamento, a partir de `GET /v3/subscriptions/{id}`.
21
+ *
22
+ * PCI: o checkout é hospedado pelo Asaas (SAQ-A) e o cartão nunca toca este
23
+ * backend. Por isso aqui só cabem os 4 últimos dígitos e a bandeira — número
24
+ * completo, CCV, trilha ou token de cartão NÃO têm campo neste tipo e não devem
25
+ * ganhar um.
26
+ */
27
+ export interface INexFinopsContractAsaasInfo {
28
+ customer_id?: string | null;
29
+ subscription_id?: string | null;
30
+ subscription_status?: NexFinopsAsaasSubscriptionStatus | null;
31
+ cycle?: string | null;
32
+ value?: number | null;
33
+ /** Data civil `YYYY-MM-DD`, igual ao resto do finops. */
34
+ next_due_date?: string | null;
35
+ card_last4?: string | null;
36
+ card_brand?: string | null;
37
+ /** Sessão de checkout hospedado que originou a assinatura. */
38
+ checkout_id?: string | null;
39
+ env?: 'sandbox' | 'production' | null;
40
+ }
11
41
  export interface INexFinopsContractServiceItem {
12
42
  category: string;
13
43
  description: string;
@@ -29,6 +59,18 @@ export interface INexFinopsContract extends IFireGlobalDoc {
29
59
  total_amount: number;
30
60
  currency: 'BRL';
31
61
  notes?: string | null;
62
+ /** Doc id (= `short_code`) da jornada que originou este contrato. */
63
+ journey_ref?: string | null;
64
+ /** Path Firestore da proposta que originou este contrato. */
65
+ proposal_ref?: string | null;
66
+ /**
67
+ * D5 — contrato fechado pelo próprio cliente no site (`origem === 'site-hm'`)
68
+ * nasce com direito a estorno; venda assistida, não. Default `false`.
69
+ */
70
+ refund_eligible?: boolean | null;
71
+ /** Método com que o primeiro pagamento foi feito. `accepted_payment_methods` é a oferta; este é o fato. */
72
+ payment_method?: NexFinopsPaymentMethod | null;
73
+ asaas?: INexFinopsContractAsaasInfo | null;
32
74
  }
33
75
  export declare const NEX_FINOPS_CONTRACT_STATUS_TRANSITIONS: Record<NexFinopsContractStatus, NexFinopsContractStatus[]>;
34
76
  /**
@@ -10,7 +10,40 @@ import type { IFireGlobalDoc } from '../../shared';
10
10
  */
11
11
  export type NexFinopsContractStatus = 'draft' | 'active' | 'cancellation_requested' | 'inactive' | 'ended' | 'canceled';
12
12
  export type NexFinopsContractRecurrence = 'one_time' | 'monthly';
13
- export type NexFinopsPaymentMethod = 'pix' | 'boleto' | 'payment_link';
13
+
14
+ /**
15
+ * `card_subscription` entra na feat-131 para convergir com
16
+ * `NexFinopsProposalPaymentMethod`: o que a proposta aceita é o que o contrato
17
+ * registra. `pix` continua porque o operador ainda lança cobrança avulsa por pix.
18
+ */
19
+ export type NexFinopsPaymentMethod = 'pix' | 'boleto' | 'payment_link' | 'card_subscription';
20
+
21
+ /** Status da assinatura no Asaas. */
22
+ export type NexFinopsAsaasSubscriptionStatus = 'ACTIVE' | 'EXPIRED' | 'INACTIVE';
23
+
24
+ /**
25
+ * Vínculo contrato ↔ assinatura Asaas (D2). Escrito uma vez, na confirmação do
26
+ * primeiro pagamento, a partir de `GET /v3/subscriptions/{id}`.
27
+ *
28
+ * PCI: o checkout é hospedado pelo Asaas (SAQ-A) e o cartão nunca toca este
29
+ * backend. Por isso aqui só cabem os 4 últimos dígitos e a bandeira — número
30
+ * completo, CCV, trilha ou token de cartão NÃO têm campo neste tipo e não devem
31
+ * ganhar um.
32
+ */
33
+ export interface INexFinopsContractAsaasInfo {
34
+ customer_id?: string | null;
35
+ subscription_id?: string | null;
36
+ subscription_status?: NexFinopsAsaasSubscriptionStatus | null;
37
+ cycle?: string | null;
38
+ value?: number | null;
39
+ /** Data civil `YYYY-MM-DD`, igual ao resto do finops. */
40
+ next_due_date?: string | null;
41
+ card_last4?: string | null;
42
+ card_brand?: string | null;
43
+ /** Sessão de checkout hospedado que originou a assinatura. */
44
+ checkout_id?: string | null;
45
+ env?: 'sandbox' | 'production' | null;
46
+ }
14
47
 
15
48
  // ── Service Item ──
16
49
 
@@ -55,6 +88,24 @@ export interface INexFinopsContract extends IFireGlobalDoc {
55
88
 
56
89
  // Observações
57
90
  notes?: string | null;
91
+
92
+ // ── Origem na jornada de contratação (feat-130) ──
93
+
94
+ /** Doc id (= `short_code`) da jornada que originou este contrato. */
95
+ journey_ref?: string | null;
96
+ /** Path Firestore da proposta que originou este contrato. */
97
+ proposal_ref?: string | null;
98
+ /**
99
+ * D5 — contrato fechado pelo próprio cliente no site (`origem === 'site-hm'`)
100
+ * nasce com direito a estorno; venda assistida, não. Default `false`.
101
+ */
102
+ refund_eligible?: boolean | null;
103
+
104
+ // ── Pagamento efetivo (feat-131) ──
105
+
106
+ /** Método com que o primeiro pagamento foi feito. `accepted_payment_methods` é a oferta; este é o fato. */
107
+ payment_method?: NexFinopsPaymentMethod | null;
108
+ asaas?: INexFinopsContractAsaasInfo | null;
58
109
  }
59
110
 
60
111
  // ── Status transitions ──
@@ -0,0 +1,71 @@
1
+ import type { IFireGlobalDoc } from '../../shared';
2
+ /**
3
+ * `viewed` é carimbado pelo endpoint público no primeiro acesso ao `short_code`.
4
+ * `expired` é **derivado** de `valid_until` na leitura (não há cron): o documento
5
+ * pode continuar gravado como `sent` depois da data — quem lê é que resolve.
6
+ */
7
+ export type NexFinopsProposalStatus = 'draft' | 'sent' | 'viewed' | 'accepted' | 'expired' | 'canceled';
8
+ /**
9
+ * Aberto para extensão de propósito: novos canais de originação entram sem
10
+ * mudança de tipo. Os valores em uso hoje são `vendas` e `site-hm`.
11
+ */
12
+ export type NexFinopsProposalOrigem = 'vendas' | 'site-hm' | (string & {});
13
+ /**
14
+ * Não confundir com `NexFinopsPaymentMethod` (contratos), que é
15
+ * `'pix' | 'boleto' | 'payment_link'`. A proposta aceita assinatura em cartão e
16
+ * não oferece pix avulso; os dois conjuntos divergem de propósito.
17
+ */
18
+ export type NexFinopsProposalPaymentMethod = 'boleto' | 'card_subscription' | 'payment_link';
19
+ /** Dados que o vendedor já conhece e a página pública usa para pré-preencher. */
20
+ export interface INexFinopsProposalPrefill {
21
+ name?: string | null;
22
+ email?: string | null;
23
+ phone?: string | null;
24
+ company?: string | null;
25
+ }
26
+ export interface INexFinopsProposal extends IFireGlobalDoc {
27
+ origem: NexFinopsProposalOrigem;
28
+ customer_id?: string | null;
29
+ customer_ref?: string | null;
30
+ prefill?: INexFinopsProposalPrefill | null;
31
+ /** Gerado no servidor, único, sem caracteres ambíguos. Nunca vem do cliente. */
32
+ short_code: string;
33
+ name?: string | null;
34
+ status: NexFinopsProposalStatus;
35
+ /** HTML descritivo escrito pelo vendedor. Sanitizar na renderização. */
36
+ html_content: string;
37
+ /** Mensalidade base em reais (decimal), mesma convenção do contrato. */
38
+ base_amount: number;
39
+ due_day: number;
40
+ accepted_payment_methods: NexFinopsProposalPaymentMethod[];
41
+ terms?: string | null;
42
+ currency: 'BRL';
43
+ valid_until: string;
44
+ sent_at?: Date | null;
45
+ viewed_at?: Date | null;
46
+ accepted_at?: Date | null;
47
+ notes?: string | null;
48
+ }
49
+ /** O que o endpoint sem auth expõe. Sem ids internos, sem dado sensível. */
50
+ export interface INexFinopsProposalPublic {
51
+ short_code: string;
52
+ status: NexFinopsProposalStatus;
53
+ html_content: string;
54
+ base_amount: number;
55
+ due_day: number;
56
+ accepted_payment_methods: NexFinopsProposalPaymentMethod[];
57
+ terms: string | null;
58
+ valid_until: string;
59
+ /** Só nome de exibição — nunca e-mail, telefone ou documento completos. */
60
+ prefill_masked: {
61
+ name: string | null;
62
+ };
63
+ }
64
+ export declare const NEX_FINOPS_PROPOSAL_STATUS_TRANSITIONS: Record<NexFinopsProposalStatus, NexFinopsProposalStatus[]>;
65
+ /**
66
+ * Status em que `valid_until` no passado deve ser lido como `expired`.
67
+ * `readonly string[]` para que `.includes(x)` aceite qualquer string sem cast.
68
+ */
69
+ export declare const NEX_FINOPS_PROPOSAL_EXPIRABLE_STATUSES: readonly string[];
70
+ /** Status em que a página pública deve mostrar a proposta. Os demais são 410. */
71
+ export declare const NEX_FINOPS_PROPOSAL_PUBLIC_VISIBLE_STATUSES: readonly string[];
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NEX_FINOPS_PROPOSAL_PUBLIC_VISIBLE_STATUSES = exports.NEX_FINOPS_PROPOSAL_EXPIRABLE_STATUSES = exports.NEX_FINOPS_PROPOSAL_STATUS_TRANSITIONS = void 0;
4
+ // ── Transições de status ──
5
+ exports.NEX_FINOPS_PROPOSAL_STATUS_TRANSITIONS = {
6
+ draft: ['sent', 'canceled'],
7
+ sent: ['viewed', 'accepted', 'expired', 'canceled'],
8
+ viewed: ['accepted', 'expired', 'canceled'],
9
+ accepted: [],
10
+ expired: [],
11
+ canceled: [],
12
+ };
13
+ /**
14
+ * Status em que `valid_until` no passado deve ser lido como `expired`.
15
+ * `readonly string[]` para que `.includes(x)` aceite qualquer string sem cast.
16
+ */
17
+ exports.NEX_FINOPS_PROPOSAL_EXPIRABLE_STATUSES = ['draft', 'sent', 'viewed'];
18
+ /** Status em que a página pública deve mostrar a proposta. Os demais são 410. */
19
+ exports.NEX_FINOPS_PROPOSAL_PUBLIC_VISIBLE_STATUSES = [
20
+ 'sent',
21
+ 'viewed',
22
+ 'accepted',
23
+ ];
@@ -0,0 +1,122 @@
1
+ import type { IFireGlobalDoc } from '../../shared';
2
+
3
+ // ── Status, origem e formas de pagamento ──
4
+
5
+ /**
6
+ * `viewed` é carimbado pelo endpoint público no primeiro acesso ao `short_code`.
7
+ * `expired` é **derivado** de `valid_until` na leitura (não há cron): o documento
8
+ * pode continuar gravado como `sent` depois da data — quem lê é que resolve.
9
+ */
10
+ export type NexFinopsProposalStatus =
11
+ | 'draft'
12
+ | 'sent'
13
+ | 'viewed'
14
+ | 'accepted'
15
+ | 'expired'
16
+ | 'canceled';
17
+
18
+ /**
19
+ * Aberto para extensão de propósito: novos canais de originação entram sem
20
+ * mudança de tipo. Os valores em uso hoje são `vendas` e `site-hm`.
21
+ */
22
+ export type NexFinopsProposalOrigem = 'vendas' | 'site-hm' | (string & {});
23
+
24
+ /**
25
+ * Não confundir com `NexFinopsPaymentMethod` (contratos), que é
26
+ * `'pix' | 'boleto' | 'payment_link'`. A proposta aceita assinatura em cartão e
27
+ * não oferece pix avulso; os dois conjuntos divergem de propósito.
28
+ */
29
+ export type NexFinopsProposalPaymentMethod = 'boleto' | 'card_subscription' | 'payment_link';
30
+
31
+ // ── Prefill do cliente ──
32
+
33
+ /** Dados que o vendedor já conhece e a página pública usa para pré-preencher. */
34
+ export interface INexFinopsProposalPrefill {
35
+ name?: string | null;
36
+ email?: string | null;
37
+ phone?: string | null;
38
+ company?: string | null;
39
+ }
40
+
41
+ // ── Documento principal ──
42
+
43
+ export interface INexFinopsProposal extends IFireGlobalDoc {
44
+ // Originação
45
+ origem: NexFinopsProposalOrigem;
46
+
47
+ // Vínculos (opcionais — a proposta pode nascer antes do cadastro do cliente)
48
+ customer_id?: string | null;
49
+ customer_ref?: string | null;
50
+ prefill?: INexFinopsProposalPrefill | null;
51
+
52
+ // Identificação
53
+ /** Gerado no servidor, único, sem caracteres ambíguos. Nunca vem do cliente. */
54
+ short_code: string;
55
+ name?: string | null;
56
+ status: NexFinopsProposalStatus;
57
+
58
+ // Conteúdo
59
+ /** HTML descritivo escrito pelo vendedor. Sanitizar na renderização. */
60
+ html_content: string;
61
+
62
+ // Valores efetivos
63
+ /** Mensalidade base em reais (decimal), mesma convenção do contrato. */
64
+ base_amount: number;
65
+ due_day: number;
66
+ accepted_payment_methods: NexFinopsProposalPaymentMethod[];
67
+ terms?: string | null;
68
+ currency: 'BRL';
69
+
70
+ // Validade — data ISO `YYYY-MM-DD`, igual a `starts_at`/`ends_at` do contrato
71
+ valid_until: string;
72
+
73
+ // Rastreio
74
+ sent_at?: Date | null;
75
+ viewed_at?: Date | null;
76
+ accepted_at?: Date | null;
77
+
78
+ notes?: string | null;
79
+ }
80
+
81
+ // ── Projeção pública ──
82
+
83
+ /** O que o endpoint sem auth expõe. Sem ids internos, sem dado sensível. */
84
+ export interface INexFinopsProposalPublic {
85
+ short_code: string;
86
+ status: NexFinopsProposalStatus;
87
+ html_content: string;
88
+ base_amount: number;
89
+ due_day: number;
90
+ accepted_payment_methods: NexFinopsProposalPaymentMethod[];
91
+ terms: string | null;
92
+ valid_until: string;
93
+ /** Só nome de exibição — nunca e-mail, telefone ou documento completos. */
94
+ prefill_masked: { name: string | null };
95
+ }
96
+
97
+ // ── Transições de status ──
98
+
99
+ export const NEX_FINOPS_PROPOSAL_STATUS_TRANSITIONS: Record<
100
+ NexFinopsProposalStatus,
101
+ NexFinopsProposalStatus[]
102
+ > = {
103
+ draft: ['sent', 'canceled'],
104
+ sent: ['viewed', 'accepted', 'expired', 'canceled'],
105
+ viewed: ['accepted', 'expired', 'canceled'],
106
+ accepted: [],
107
+ expired: [],
108
+ canceled: [],
109
+ };
110
+
111
+ /**
112
+ * Status em que `valid_until` no passado deve ser lido como `expired`.
113
+ * `readonly string[]` para que `.includes(x)` aceite qualquer string sem cast.
114
+ */
115
+ export const NEX_FINOPS_PROPOSAL_EXPIRABLE_STATUSES: readonly string[] = ['draft', 'sent', 'viewed'];
116
+
117
+ /** Status em que a página pública deve mostrar a proposta. Os demais são 410. */
118
+ export const NEX_FINOPS_PROPOSAL_PUBLIC_VISIBLE_STATUSES: readonly string[] = [
119
+ 'sent',
120
+ 'viewed',
121
+ 'accepted',
122
+ ];
@@ -2,6 +2,7 @@ export * from "./fb_collections";
2
2
  export * from "./common";
3
3
  export * from "./common/taker";
4
4
  export * from "./common/contract";
5
+ export * from "./common/proposal";
5
6
  export * from "./common/billing";
6
7
  export * from "./providers";
7
8
  export * from "./providers/provider_fiscal_types";
@@ -19,6 +19,7 @@ __exportStar(require("./fb_collections"), exports);
19
19
  __exportStar(require("./common"), exports);
20
20
  __exportStar(require("./common/taker"), exports);
21
21
  __exportStar(require("./common/contract"), exports);
22
+ __exportStar(require("./common/proposal"), exports);
22
23
  __exportStar(require("./common/billing"), exports);
23
24
  __exportStar(require("./providers"), exports);
24
25
  __exportStar(require("./providers/provider_fiscal_types"), exports);