sgp-sdk 1.1.3 → 2.0.0-beta.1

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 (87) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/COMPATIBILITY.md +151 -0
  3. package/MIGRATION.md +283 -0
  4. package/README.md +424 -225
  5. package/dist/address.d.ts +46 -0
  6. package/dist/annotation-selection.d.ts +32 -0
  7. package/dist/budget.d.ts +29 -0
  8. package/dist/classify.d.ts +15 -0
  9. package/dist/client.d.ts +662 -155
  10. package/dist/config.d.ts +115 -0
  11. package/dist/constants.d.ts +72 -0
  12. package/dist/effect.d.ts +22 -0
  13. package/dist/executor.d.ts +9 -0
  14. package/dist/exposure.d.ts +21 -0
  15. package/dist/guards.d.ts +2 -0
  16. package/dist/hooks.d.ts +16 -0
  17. package/dist/ids.d.ts +19 -0
  18. package/dist/index.d.ts +45 -47
  19. package/dist/index.js +2954 -1223
  20. package/dist/operation-sensitivity.d.ts +496 -0
  21. package/dist/operation.d.ts +139 -0
  22. package/dist/operations/catalogs-list-billing-profiles.d.ts +16 -0
  23. package/dist/operations/catalogs-list-nas.d.ts +25 -0
  24. package/dist/operations/catalogs-list-pops.d.ts +14 -0
  25. package/dist/operations/contracts-list-status-reasons.d.ts +15 -0
  26. package/dist/operations/contracts-list.d.ts +52 -0
  27. package/dist/operations/contracts-update-status.d.ts +41 -0
  28. package/dist/operations/contracts-update.d.ts +39 -0
  29. package/dist/operations/coverage-check.d.ts +42 -0
  30. package/dist/operations/crm-contracts-create-by-cpf-cnpj.d.ts +97 -0
  31. package/dist/operations/crm-contracts-create.d.ts +221 -0
  32. package/dist/operations/crm-contracts-list.d.ts +50 -0
  33. package/dist/operations/crm-customers-create.d.ts +155 -0
  34. package/dist/operations/crm-customers-update-status.d.ts +41 -0
  35. package/dist/operations/customers-list.d.ts +98 -0
  36. package/dist/{endpoints/ura/lookup-customer.d.ts → operations/customers-search.d.ts} +56 -46
  37. package/dist/operations/documents-add.d.ts +29 -0
  38. package/dist/operations/documents-list.d.ts +31 -0
  39. package/dist/operations/experimental-annotations-list.d.ts +67 -0
  40. package/dist/operations/invoices-list.d.ts +142 -0
  41. package/dist/operations/occurrences-create.d.ts +116 -0
  42. package/dist/operations/occurrences-list-methods.d.ts +14 -0
  43. package/dist/operations/occurrences-list-types.d.ts +20 -0
  44. package/dist/{endpoints/ura/list-plans.d.ts → operations/plans-list.d.ts} +33 -23
  45. package/dist/operations/pre-registrations-create.d.ts +253 -0
  46. package/dist/operations/pre-registrations-list-due-days.d.ts +15 -0
  47. package/dist/operations/pre-registrations-list-plans.d.ts +24 -0
  48. package/dist/operations/pre-registrations-list-sellers.d.ts +16 -0
  49. package/dist/operations/services-add-tv.d.ts +47 -0
  50. package/dist/operations/services-change-plan.d.ts +40 -0
  51. package/dist/operations/services-remove-tv.d.ts +29 -0
  52. package/dist/operations/work-orders-list-reasons.d.ts +20 -0
  53. package/dist/operations/work-orders-list.d.ts +81 -0
  54. package/dist/path.d.ts +13 -0
  55. package/dist/raw-request.d.ts +26 -0
  56. package/dist/request.d.ts +28 -0
  57. package/dist/result.d.ts +111 -43
  58. package/dist/retry.d.ts +34 -0
  59. package/dist/sensitivity.d.ts +89 -4
  60. package/dist/tolerant.d.ts +21 -0
  61. package/dist/validation.d.ts +3 -0
  62. package/package.json +6 -3
  63. package/dist/endpoint.d.ts +0 -66
  64. package/dist/endpoints/crm/address.d.ts +0 -20
  65. package/dist/endpoints/crm/create-contract.d.ts +0 -109
  66. package/dist/endpoints/crm/create-customer.d.ts +0 -65
  67. package/dist/endpoints/crm/update-customer-status.d.ts +0 -43
  68. package/dist/endpoints/os/list-occurrence-reasons.d.ts +0 -24
  69. package/dist/endpoints/os/list-occurrence-types.d.ts +0 -25
  70. package/dist/endpoints/precadastro/list-due-days.d.ts +0 -19
  71. package/dist/endpoints/precadastro/list-sellers.d.ts +0 -21
  72. package/dist/endpoints/suporte/add-customer-document.d.ts +0 -24
  73. package/dist/endpoints/suporte/list-customer-documents.d.ts +0 -25
  74. package/dist/endpoints/ura/check-coverage.d.ts +0 -46
  75. package/dist/endpoints/ura/list-clients.d.ts +0 -58
  76. package/dist/endpoints/ura/list-contracts.d.ts +0 -45
  77. package/dist/endpoints/ura/list-invoices.d.ts +0 -107
  78. package/dist/endpoints/ura/list-nas.d.ts +0 -29
  79. package/dist/endpoints/ura/list-occurrence-methods.d.ts +0 -19
  80. package/dist/endpoints/ura/list-payment-carriers.d.ts +0 -20
  81. package/dist/endpoints/ura/list-pops.d.ts +0 -19
  82. package/dist/endpoints/ura/list-service-orders.d.ts +0 -64
  83. package/dist/endpoints/ura/open-ticket.d.ts +0 -81
  84. package/dist/errors.d.ts +0 -59
  85. package/dist/schema/parse.d.ts +0 -19
  86. package/dist/schema/paths.d.ts +0 -38
  87. package/dist/transport.d.ts +0 -65
package/dist/client.d.ts CHANGED
@@ -1,217 +1,724 @@
1
- import { type CreateContractParams, type CreateContractResponse } from "./endpoints/crm/create-contract.js";
2
- import { type CreateCompanyCustomerParams, type CreateCustomerResponse, type CreateIndividualCustomerParams } from "./endpoints/crm/create-customer.js";
3
- import { type UpdateCustomerStatusParams, type UpdateCustomerStatusResponse } from "./endpoints/crm/update-customer-status.js";
4
- import { type ListOccurrenceReasonsResponse } from "./endpoints/os/list-occurrence-reasons.js";
5
- import { type ListOccurrenceTypesResponse } from "./endpoints/os/list-occurrence-types.js";
6
- import { type ListDueDaysResponse } from "./endpoints/precadastro/list-due-days.js";
7
- import { type ListSellersResponse } from "./endpoints/precadastro/list-sellers.js";
8
- import { type AddCustomerDocumentParams, type AddCustomerDocumentResponse } from "./endpoints/suporte/add-customer-document.js";
9
- import { type ListCustomerDocumentsResponse } from "./endpoints/suporte/list-customer-documents.js";
10
- import { type CheckCoverageParams, type CheckCoverageResponse } from "./endpoints/ura/check-coverage.js";
11
- import { type ListClientsParams, type ListClientsResponse } from "./endpoints/ura/list-clients.js";
12
- import { type ListContractsParams, type ListContractsResponse } from "./endpoints/ura/list-contracts.js";
13
- import { type ListInvoicesParams, type ListInvoicesResponse } from "./endpoints/ura/list-invoices.js";
14
- import { type ListNasResponse } from "./endpoints/ura/list-nas.js";
15
- import { type ListOccurrenceMethodsResponse } from "./endpoints/ura/list-occurrence-methods.js";
16
- import { type ListPaymentCarriersResponse } from "./endpoints/ura/list-payment-carriers.js";
17
- import { type ListPlansResponse } from "./endpoints/ura/list-plans.js";
18
- import { type ListPopsResponse } from "./endpoints/ura/list-pops.js";
19
- import { type ListServiceOrdersParams, type ListServiceOrdersResponse } from "./endpoints/ura/list-service-orders.js";
20
- import { type LookupCustomerParams, type LookupCustomerResponse } from "./endpoints/ura/lookup-customer.js";
21
- import { type OpenTicketParams, type OpenTicketResponse } from "./endpoints/ura/open-ticket.js";
22
- import type { SgpResult, SgpWriteResult } from "./result.js";
23
- import type { SgpClientConfig, SgpFile } from "./transport.js";
24
- /** Methods that hit the `/api/ura/` routes. All are reads, except `openTicket`: a write that returns an {@link SgpWriteResult}. */
25
- export interface UraClient {
1
+ import { type CallOptions, type ClientOptions } from "./config.js";
2
+ import { type CatalogsListBillingProfilesData } from "./operations/catalogs-list-billing-profiles.js";
3
+ import { type CatalogsListNasData } from "./operations/catalogs-list-nas.js";
4
+ import { type CatalogsListPopsData } from "./operations/catalogs-list-pops.js";
5
+ import { type ContractsListData, type ContractsListInput } from "./operations/contracts-list.js";
6
+ import { type ContractsListStatusReasonsData } from "./operations/contracts-list-status-reasons.js";
7
+ import { type ContractUpdateData, type ContractUpdateInput } from "./operations/contracts-update.js";
8
+ import { type ContractUpdateStatusData, type ContractUpdateStatusInput } from "./operations/contracts-update-status.js";
9
+ import { type CoverageCheckData, type CoverageCheckInput } from "./operations/coverage-check.js";
10
+ import { type CrmContractCreateData, type CrmContractCreateInput } from "./operations/crm-contracts-create.js";
11
+ import { type CrmContractCreateByCpfCnpjData, type CrmContractCreateByCpfCnpjInput } from "./operations/crm-contracts-create-by-cpf-cnpj.js";
12
+ import { type CrmContractsListData, type CrmContractsListInput } from "./operations/crm-contracts-list.js";
13
+ import { type CrmCustomerCreateData, type CrmCustomerCreateInput } from "./operations/crm-customers-create.js";
14
+ import { type CrmCustomerUpdateStatusData, type CrmCustomerUpdateStatusInput } from "./operations/crm-customers-update-status.js";
15
+ import { type CustomersListData, type CustomersListInput } from "./operations/customers-list.js";
16
+ import { type CustomersSearchData, type CustomersSearchInput } from "./operations/customers-search.js";
17
+ import { type DocumentAddInput } from "./operations/documents-add.js";
18
+ import { type DocumentsListData, type DocumentsListInput } from "./operations/documents-list.js";
19
+ import { type ExperimentalAnnotationsListData, type ExperimentalAnnotationsListInput } from "./operations/experimental-annotations-list.js";
20
+ import { type InvoicesListData, type InvoicesListInput } from "./operations/invoices-list.js";
21
+ import { type OccurrenceCreateData, type OccurrenceCreateInput } from "./operations/occurrences-create.js";
22
+ import { type OccurrencesListMethodsData } from "./operations/occurrences-list-methods.js";
23
+ import { type OccurrencesListTypesData } from "./operations/occurrences-list-types.js";
24
+ import { type PlansListData } from "./operations/plans-list.js";
25
+ import { type PreRegistrationCreateData, type PreRegistrationCreateInput } from "./operations/pre-registrations-create.js";
26
+ import { type PreRegistrationsListDueDaysData } from "./operations/pre-registrations-list-due-days.js";
27
+ import { type PreRegistrationsListPlansData } from "./operations/pre-registrations-list-plans.js";
28
+ import { type PreRegistrationsListSellersData } from "./operations/pre-registrations-list-sellers.js";
29
+ import { type ServiceAddTvData, type ServiceAddTvInput } from "./operations/services-add-tv.js";
30
+ import { type ServiceChangePlanData, type ServiceChangePlanInput } from "./operations/services-change-plan.js";
31
+ import { type ServiceRemoveTvData, type ServiceRemoveTvInput } from "./operations/services-remove-tv.js";
32
+ import { type WorkOrdersListData, type WorkOrdersListInput } from "./operations/work-orders-list.js";
33
+ import { type WorkOrdersListReasonsData } from "./operations/work-orders-list-reasons.js";
34
+ import { type RawRequestInput } from "./raw-request.js";
35
+ import type { SgpResult } from "./result.js";
36
+ /** Operations on catalogs of the provider's own setup (POPs, NAS, billing profiles). */
37
+ export interface CatalogsClient {
26
38
  /**
27
- * Lists clients, one page at a time: `POST /api/ura/clientes/`.
39
+ * Lists the POPs (points of presence): `POST /api/ura/pops/`, JSON, no input. The route is not
40
+ * paginated, so the result is SGP's own bare array: no page envelope, no total. Unknown fields
41
+ * reach `data` unchanged. Only the `id` of each POP must be a number (an element that is not an
42
+ * object fails the response too: `INVALID_RESPONSE`); any other field of the wrong type is left
43
+ * out of `data` and reported in `warnings` (the original stays in `response`). A read: the opt-in
44
+ * `maxRetries` may retry it.
45
+ */
46
+ listPops: (options?: CallOptions) => Promise<SgpResult<CatalogsListPopsData>>;
47
+ /**
48
+ * Lists the NAS (network access servers) and the POPs each one serves: `POST /api/ura/nas/list/`,
49
+ * JSON, no input. The route is not paginated, so the result is SGP's own bare array: no page
50
+ * envelope, no total. Unknown fields reach `data` unchanged at every level. Only the `id` of each
51
+ * NAS must be a number (an element that is not an object fails the response too:
52
+ * `INVALID_RESPONSE`); any other field of the wrong type is left out of `data` and reported in
53
+ * `warnings` (the original stays in `response`).
28
54
  *
29
- * Filter with `cliente_id`, `cpfcnpj` or `cliente_nome`; page with `offset` and `limit`.
55
+ * The IP address of a NAS (`endereco_ip`) is a secret: see `getSensitivity("catalogs.listNas")`
56
+ * and project with `pick` before logging or handing it on. A read: the opt-in `maxRetries` may
57
+ * retry it.
58
+ */
59
+ listNas: (options?: CallOptions) => Promise<SgpResult<CatalogsListNasData>>;
60
+ /**
61
+ * Lists the billing profiles (SGP "portadores", who issues and collects the invoices):
62
+ * `GET /api/ura/portador/`, credentials in the query string, no input. The route is not
63
+ * paginated, so the result is SGP's own bare array: no page envelope, no total. Unknown fields
64
+ * reach `data` unchanged. Only the `id` of each billing profile must be a number (an element that
65
+ * is not an object fails the response too: `INVALID_RESPONSE`); any other field of the wrong type
66
+ * is left out of `data` and reported in `warnings` (the original stays in `response`). The
67
+ * `portador` filter of `invoices.list` takes these ids. A read: the opt-in `maxRetries` may retry
68
+ * it.
30
69
  */
31
- listClients: (params?: ListClientsParams) => Promise<SgpResult<ListClientsResponse>>;
70
+ listBillingProfiles: (options?: CallOptions) => Promise<SgpResult<CatalogsListBillingProfilesData>>;
71
+ }
72
+ /** Operations on the CRM funnel's customers (SGP "clientes CRM"). */
73
+ export interface CrmCustomersClient {
32
74
  /**
33
- * Looks up a customer and its contracts: `POST /api/ura/consultacliente/`.
75
+ * Creates a CRM customer: `POST /api/crm/cliente/F` or `/J`, picked by `input.personType`, JSON
76
+ * with the address nested (`endereco`) and also as loose fields, as SGP reads both. Never retried.
77
+ *
78
+ * WARNING: SGP accepts a CPF that already belongs to a customer and creates ANOTHER customer with
79
+ * the same document (live: the duplicate was created and both customers were listed by `customers.list`). Unlike
80
+ * `preRegistrations.create`, which refuses an existing CPF (402), nothing here prevents a
81
+ * duplicate, and a duplicate breaks every lookup by document. Check the document first
82
+ * (`customers.search`, `customers.list`) and decide in your own code whether a second customer is
83
+ * acceptable. A CRM customer is an ordinary customer: its `cliente_id` is the `CustomerId` that
84
+ * `customers.list` shows.
34
85
  *
35
- * Requires at least one of `cpfcnpj`, `contrato`, `nome`, `login` or `telefone`. Each contract
36
- * carries secrets (Central and PPPoE credentials, Wi-Fi, MACs, payoff link) and personal data;
37
- * strip them with `omitSensitive` and the exported key tuples before logging or forwarding.
86
+ * A success carries the new `cliente_id` (a `CustomerId`, required: a 2xx without it is
87
+ * `INVALID_RESPONSE`) and SGP's `message`, which echoes the customer's name and document. Only
88
+ * `/F` was exercised; `/J` follows the vendor's documentation. Other person types (`E`, `EJ`) are
89
+ * reachable through `request()`.
90
+ *
91
+ * SGP's field validation (HTTP 400, `errors` as an object keyed by field, e.g. `nome` refused for
92
+ * containing digits) is `REJECTED` with effect `"none"`. Other failures carry `error.effect` by
93
+ * the usual rules: `"none"` only when the SDK can affirm nothing was applied (refused locally,
94
+ * cancelled before send, or SGP refused with a field/business error such as `errors` as an
95
+ * object, `error` or `detail`); `"unknown"` after a timeout, network failure, cancellation after
96
+ * send, an HTTP 5xx or 3xx, SGP's generic `errors` array, or a 2xx outside the contract. On
97
+ * `"unknown"`, search for the document before sending again: a second call may create a duplicate.
38
98
  */
39
- lookupCustomer: (params: LookupCustomerParams) => Promise<SgpResult<LookupCustomerResponse>>;
99
+ create: (input: CrmCustomerCreateInput, options?: CallOptions) => Promise<SgpResult<CrmCustomerCreateData>>;
40
100
  /**
41
- * Lists contract summaries: `POST /api/ura/listacontrato/`.
101
+ * Changes the status of a CRM customer: `POST /api/crm/cliente/{cliente_id}/status/` (trailing
102
+ * slash), JSON. Never retried. Status codes are in `CRM_STATUS` (6 is "Contrato realizado no
103
+ * SGP"), but any number is sent and SGP decides; only 6 was exercised.
42
104
  *
43
- * Filter with `contrato`, `plano`, `tipo` or `status`. Without any filter the response may
44
- * carry the whole contract base. Results contain personal data (name, CPF/CNPJ, e-mail, phone,
45
- * status reason); strip it with `omitSensitive` and the exported key tuples before logging or
46
- * forwarding.
105
+ * A success carries `cliente_id` and `novo_status.codigo`, both required, and SGP's `message`
106
+ * (which echoes the customer's name). A customer that already left the CRM (or a repeated status
107
+ * 6) answers HTTP 404 `{ "error": "Cadastro não encontrado" }`: `NOT_FOUND`, effect `"none"`
108
+ * (a 1.x capture). This route has no other known rejection: a customer that never
109
+ * was in the CRM answers with SGP's generic `errors` array, which stays `"unknown"`;
110
+ * field/business errors (`errors` as an object, `error`, `detail`) are `"none"`. On `"unknown"`,
111
+ * read the customer before sending again.
47
112
  */
48
- listContracts: (params?: ListContractsParams) => Promise<SgpResult<ListContractsResponse>>;
113
+ updateStatus: (input: CrmCustomerUpdateStatusInput, options?: CallOptions) => Promise<SgpResult<CrmCustomerUpdateStatusData>>;
114
+ }
115
+ /** Operations on the contracts of CRM customers. */
116
+ export interface CrmContractsClient {
49
117
  /**
50
- * Lists service orders (OS), one page at a time: `POST /api/ura/ordemservico/list/`.
118
+ * Creates a contract for a CRM customer, by customer id: `POST
119
+ * /api/crm/cliente/{cliente_id}/contratos/` (trailing slash), JSON with both addresses nested
120
+ * and the installation address also as loose fields. Never retried. It works only for a customer
121
+ * that is still in the CRM funnel: a definitive customer (such as one created by
122
+ * `preRegistrations.create` with `precadastro_ativar`) is refused.
123
+ *
124
+ * SGP's refusal of a customer outside the CRM, HTTP 400
125
+ * `{ errors: ["Ocorreu um erro: Não encontrado cliente CRM com ID <n>"] }`, is `REJECTED` with
126
+ * `error.reason === "CUSTOMER_NOT_IN_CRM"` and effect `"none"` (read-backs showed no contract
127
+ * added). Any other `errors` array is SGP's generic wrapper and stays `"unknown"`.
51
128
  *
52
- * Filter with `ordem_servico`, `status`, `pop`, `motivo` or `contrato`; page with `offset` and
53
- * `limit`. Results contain personal data (customer name, free-text content); strip it with
54
- * `omitSensitive` and the exported key tuples before logging or forwarding.
129
+ * `plano_id` is a `PlanId` from the URA catalog (`plans.list`). For an Internet service the
130
+ * vendor's documentation also requires `login`, `senha` and `modoaquisicao`, and SGP requires
131
+ * `nas` (a NAS name); it answers 400 with `errors` as an object, `"none"`, when one is missing.
132
+ * Only the missing-`nas` 400 was observed; the other three come from the vendor's documentation. `modoaquisicao` takes
133
+ * `ACQUISITION_MODE` (0 or 1): the vendor's documentation lists 1 and 2, but SGP refused 2 live.
134
+ *
135
+ * A success (HTTP 200) carries the new `clientecontrato` (the contract id, required), SGP's
136
+ * `message` and `cliente`, which echoes the customer's name and CPF (personal data: see
137
+ * `getSensitivity`). Other failures carry `error.effect` by the same
138
+ * rules as `crm.customers.create`. On `"unknown"`, read the customer's contracts before sending
139
+ * again: a second call may create a duplicate contract.
55
140
  */
56
- listServiceOrders: (params?: ListServiceOrdersParams) => Promise<SgpResult<ListServiceOrdersResponse>>;
57
- /** Lists the plan catalog: `GET /api/ura/consultaplano/`. Takes no parameters. */
58
- listPlans: () => Promise<SgpResult<ListPlansResponse>>;
59
- /** Lists the occurrence methods: `GET /api/ura/ocorrencia/metodo/list/`. Takes no parameters. */
60
- listOccurrenceMethods: () => Promise<SgpResult<ListOccurrenceMethodsResponse>>;
141
+ create: (input: CrmContractCreateInput, options?: CallOptions) => Promise<SgpResult<CrmContractCreateData>>;
61
142
  /**
62
- * Lists invoices (titulos), one page at a time: `POST /api/ura/titulos/`.
143
+ * Creates a contract for a CRM customer, by the customer's document: `POST
144
+ * /api/crm/cliente/contratos/?cpfcnpj=<document>` (trailing slash). The document goes in the
145
+ * QUERY string of the POST, as in the live capture; the body is the same JSON contract as
146
+ * `create` (both addresses nested, the installation one also loose) with the credentials, and
147
+ * has no `cliente_id`. Never retried.
148
+ *
149
+ * `cpfcnpj` is SGP's single field: the API decides whether it is a CPF or a CNPJ. Only a CPF was
150
+ * ever exercised; a CNPJ is accepted by the field's name and was never tried. Send it as you
151
+ * hold it (digits or formatted). It works only for a customer still in the CRM funnel.
63
152
  *
64
- * Filter with `contrato`, `cliente_id`, `cpfcnpj`, `titulo_id`, `status`, `portador` or the date
65
- * ranges; order with `ordenar` and `ordenar_ordem`; page with `offset` and `limit`. Results
66
- * contain personal data (customer name, CPF/CNPJ, statement text) and payment links and PIX
67
- * codes that may resolve to the debtor; strip them with `omitSensitive` and the exported key
68
- * tuples before logging or forwarding.
153
+ * SGP's refusal of a document that is not a CRM customer, HTTP 400
154
+ * `{ errors: ["Ocorreu um erro: Não encontrado cliente CRM com documento <formatted document>"] }`
155
+ * (the document comes back formatted), is `REJECTED` with `error.reason === "CUSTOMER_NOT_IN_CRM"`
156
+ * and effect `"none"` (the read-back showed no contract added). The matcher covers numeric
157
+ * documents (CPF or CNPJ digits, dots, dashes, slashes); an alphanumeric CNPJ, or any other `errors`
158
+ * array (SGP's generic wrapper), stays `"unknown"` without a reason.
159
+ *
160
+ * When several customers share a document (SGP allows duplicates, see `crm.customers.create`),
161
+ * which CRM customer receives the contract is unverified.
162
+ *
163
+ * NOT OBSERVED: no success was ever seen on this route, so NO input field reached a success here
164
+ * (the "Exercised" markers of `CrmContractCreateInput` come from the by-id route) (the only live call was that refusal). The
165
+ * success shape is assumed to be that of `create` (HTTP 200 with the new `clientecontrato`,
166
+ * required, SGP's `message` and `cliente`, which echoes the customer's name and is personal
167
+ * data); a 2xx without a numeric `clientecontrato` is `INVALID_RESPONSE` with effect `"unknown"`.
168
+ * Other failures carry `error.effect` by the same rules as `create`. On `"unknown"`, read the
169
+ * customer's contracts (`crm.contracts.list`) before sending again: a second call may create a
170
+ * duplicate contract.
69
171
  */
70
- listInvoices: (params?: ListInvoicesParams) => Promise<SgpResult<ListInvoicesResponse>>;
71
- /** Lists the POPs (points of presence): `POST /api/ura/pops/`. Takes no parameters. */
72
- listPops: () => Promise<SgpResult<ListPopsResponse>>;
172
+ createByCpfCnpj: (input: CrmContractCreateByCpfCnpjInput, options?: CallOptions) => Promise<SgpResult<CrmContractCreateByCpfCnpjData>>;
73
173
  /**
74
- * Lists the NAS (network access servers) and the POPs each serves: `POST /api/ura/nas/list/`.
75
- * Takes no parameters.
174
+ * Lists the contracts of a CRM customer, by the customer's document: `GET
175
+ * /api/crm/cliente/contratos/?cpfcnpj=<document>` (trailing slash), credentials in the query
176
+ * string. A repeatable read. `cpfcnpj` is SGP's single field: the API decides whether it is a CPF
177
+ * or a CNPJ; only a CPF was ever exercised. Send it as you hold it (digits or formatted). When
178
+ * several customers share the document (SGP allows duplicates), which one's contracts are
179
+ * listed is unverified.
180
+ *
181
+ * A success is SGP's own object: `cliente` and `cpf_cnpj` (personal data) and `contratos`, one
182
+ * summary per contract, an empty array when the CRM customer has none. Each contract must carry a
183
+ * numeric `cliente_contrato_id` and `contratos` must be an array, or the call is
184
+ * `INVALID_RESPONSE`; everything else is optional and tolerant (a field of the wrong type is
185
+ * dropped with a warning, and unknown keys reach `data` as received). `data_cadastro` and
186
+ * `data_status` stay `DD/MM/AAAA` strings. `endereco`, `motivo_status`, `vendedor` and each
187
+ * service's `login` (a PPPoE secret) are sensitive: see `getSensitivity`.
76
188
  *
77
- * `endereco_ip` is network infrastructure; strip it with `omitSensitive` and `nasSecretKeys`
78
- * before logging or forwarding.
189
+ * A document that is not a CRM customer answers HTTP 400
190
+ * `{ errors: ["Ocorreu um erro: Não encontrado cliente CRM com documento <formatted document>"] }`:
191
+ * `REJECTED`, with no `reason` and no `effect` (a read applies nothing).
79
192
  */
80
- listNas: () => Promise<SgpResult<ListNasResponse>>;
81
- /** Lists the payment carriers (portadores): `GET /api/ura/portador/`. Takes no parameters. */
82
- listPaymentCarriers: () => Promise<SgpResult<ListPaymentCarriersResponse>>;
193
+ list: (input: CrmContractsListInput, options?: CallOptions) => Promise<SgpResult<CrmContractsListData>>;
194
+ }
195
+ /** Operations of the CRM funnel (SGP "CRM"). */
196
+ export interface CrmClient {
197
+ /** Operations on CRM customers. */
198
+ customers: CrmCustomersClient;
199
+ /** Operations on the contracts of CRM customers. */
200
+ contracts: CrmContractsClient;
201
+ }
202
+ /** Operations on customers' documents (SGP "documentos" of the support area). */
203
+ export interface DocumentsClient {
83
204
  /**
84
- * Checks installation viability around a coordinate: `GET /api/ura/viabilidadeinstalacao`.
205
+ * Attaches a file to a customer: `PUT /api/suporte/cliente/{cliente_id}/documento/add/`
206
+ * (trailing slash), `multipart/form-data` with the file as the part `file` (and `descricao` as a
207
+ * text field when given). Never retried: a second call may attach the file twice.
85
208
  *
86
- * The SDK does not geocode: the consumer supplies `coordenada` (`"lat,lng"`), the map `gateway`
87
- * ID (from `/api/ura/listgatewaymapa`) and the `raio` in meters. The answer is keyed by the gateway's name and
88
- * holds the CTOs within the radius, or `"Localização inviável"` when there are none.
209
+ * A success is a 2xx with an EMPTY body: `data` is `null`, and nothing identifies the new
210
+ * document. Any other 2xx body is `INVALID_RESPONSE` with effect `"unknown"` (the upload may have
211
+ * been stored): read the customer's documents before sending again.
89
212
  *
90
- * A malformed gateway answer (an entry that is neither CTOs nor a message) is `SCHEMA_MISMATCH`.
213
+ * Failures carry `error.effect` by the same rules as `crm.customers.create`; this route has no
214
+ * known rejection. The file and its description are the customer's documents: personal data.
91
215
  */
92
- checkCoverage: (params: CheckCoverageParams) => Promise<SgpResult<CheckCoverageResponse>>;
216
+ add: (input: DocumentAddInput, options?: CallOptions) => Promise<SgpResult<null>>;
93
217
  /**
94
- * Opens a ticket on a contract: `POST /api/ura/chamado/`. Opens an occurrence and, unless
95
- * `desativa_os: 1`, a service order; `data_hora_agendamento` (`"AAAA-MM-DD HH:MM"`) schedules it.
218
+ * Lists the documents attached to a customer: `GET /api/suporte/cliente/{cliente_id}/documento/list/`
219
+ * (trailing slash), credentials in the query string. The route is not paginated, so the result is
220
+ * SGP's own bare array: no page envelope, no total. An empty array means the customer has no
221
+ * document. `cliente_id` is a `CustomerId` (never the id of a contract) and must be a positive
222
+ * integer, or the call is refused locally (`INVALID_INPUT`, nothing sent); the `cliente_id` of
223
+ * each row is a `CustomerId` too.
96
224
  *
97
- * Requires `contrato`. To schedule an installation, send `motivoos` with your instance's
98
- * installation reason code (see `os.listOccurrenceReasons`) and `data_hora_agendamento`. Success is `status` 1 with a `protocolo`; the response carries the
99
- * customer's name and CPF/CNPJ: strip them with `omitSensitive` and `ticketOpenedPersonalKeys`
100
- * before logging or forwarding. `contato_nome` and `contato_telefone` in the params are personal
101
- * data.
225
+ * Unknown fields reach `data` unchanged. Only the `id` and the `cliente_id` of each document must
226
+ * be numbers (an element that is not an object fails the response too: `INVALID_RESPONSE`); any
227
+ * other field of the wrong type is left out of `data` and reported in `warnings` (the original
228
+ * stays in `response`).
102
229
  *
103
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
230
+ * Each document carries the file name or link (`arquivo`), its description and the operator:
231
+ * personal data, see `getSensitivity("documents.list")` and project with `pick` before logging or
232
+ * handing it on. A read: the opt-in `maxRetries` may retry it.
104
233
  */
105
- openTicket: (params: OpenTicketParams) => Promise<SgpWriteResult<OpenTicketResponse>>;
234
+ list: (input: DocumentsListInput, options?: CallOptions) => Promise<SgpResult<DocumentsListData>>;
106
235
  }
107
- /** Methods that hit the `/api/os/` routes. */
108
- export interface OsClient {
109
- /** Lists the occurrence types of service orders (OS): `GET /api/os/ocorrencia/tipo/list/`. Takes no parameters. */
110
- listOccurrenceTypes: () => Promise<SgpResult<ListOccurrenceTypesResponse>>;
111
- /** Lists the occurrence reasons of service orders (OS): `GET /api/os/ocorrencia/motivo/list/`. Takes no parameters. */
112
- listOccurrenceReasons: () => Promise<SgpResult<ListOccurrenceReasonsResponse>>;
236
+ /** Operations on occurrences (SGP "ocorrências", the support tickets or "chamados"). */
237
+ export interface OccurrencesClient {
238
+ /**
239
+ * Opens an occurrence (a support ticket) for a contract: `POST /api/ura/chamado/` (trailing
240
+ * slash), JSON. Never retried: a second call opens a second ticket. Unless `desativa_os` is `1`,
241
+ * SGP opens a work order with it.
242
+ *
243
+ * A success returns `id` (the ID of the OCCURRENCE) and `protocolo` (its protocol number), both
244
+ * required. It never carries the ID of the work order: read it with `workOrders.list`. The work
245
+ * order's `ocorrencia` has the format of the `protocolo` (observed: a work order whose
246
+ * `ocorrencia` had that format), not of the occurrence `id`; that link is observed but not
247
+ * confirmed, so match on `protocolo` and verify the work order before relying on it. `motivoos` is the `codigo` of a reason of the work order, from
248
+ * `workOrders.listReasons` (each SGP instance has its own).
249
+ *
250
+ * SGP answers some refusals with HTTP 200 and `status: 0` (and a `msg`): that is `REJECTED` with
251
+ * effect `"unknown"`, since nothing says whether anything was created. Read the contract's
252
+ * occurrences before sending again. Other failures carry `error.effect` by the same rules as
253
+ * `crm.customers.create`.
254
+ */
255
+ create: (input: OccurrenceCreateInput, options?: CallOptions) => Promise<SgpResult<OccurrenceCreateData>>;
256
+ /**
257
+ * Lists the occurrence types: `GET /api/os/ocorrencia/tipo/list/`, credentials in the query
258
+ * string, no input. The route is not paginated, so the result is SGP's own bare array: no page
259
+ * envelope, no total. Each type has two identifiers, `id` and `codigo`, both numbers and kept
260
+ * apart as SGP sends them: `occurrences.create` takes the `codigo` as `ocorrenciatipo` (the
261
+ * vendor's collection says "Código"). Unknown fields
262
+ * reach `data` unchanged. Only `id` and `codigo` of each type must be numbers (an element that is
263
+ * not an object fails the response too: `INVALID_RESPONSE`); any other field of the wrong type is
264
+ * left out of `data` and reported in `warnings` (the original stays in `response`).
265
+ * `classificacoes` and `setores` were always empty in the captures: their content is untyped. A
266
+ * read: the opt-in `maxRetries` may retry it.
267
+ */
268
+ listTypes: (options?: CallOptions) => Promise<SgpResult<OccurrencesListTypesData>>;
269
+ /**
270
+ * Lists the occurrence methods: `GET /api/ura/ocorrencia/metodo/list/`, credentials in the query
271
+ * string, no input. The route is not paginated, so the result is SGP's own bare array: no page
272
+ * envelope, no total. Unknown fields reach `data` unchanged. Only the `codigo` of each method
273
+ * must be a number (an element that is not an object fails the response too:
274
+ * `INVALID_RESPONSE`); any other field of the wrong type is left out of `data` and reported in
275
+ * `warnings` (the original stays in `response`). A read: the opt-in `maxRetries` may retry it.
276
+ */
277
+ listMethods: (options?: CallOptions) => Promise<SgpResult<OccurrencesListMethodsData>>;
113
278
  }
114
- /** Methods that hit the `/api/precadastro/` routes. */
115
- export interface PrecadastroClient {
116
- /** Lists the due days offered at pre-registration: `POST /api/precadastro/vencimento/list`. Takes no parameters. */
117
- listDueDays: () => Promise<SgpResult<ListDueDaysResponse>>;
279
+ /** Operations on contracts (SGP "contratos"). */
280
+ export interface ContractsClient {
118
281
  /**
119
- * Lists the sellers (vendedores): `POST /api/precadastro/vendedor/list`. Takes no parameters.
282
+ * Lists contracts: `POST /api/ura/listacontrato/`, JSON; every filter is optional. The route is
283
+ * not paginated, so the result is SGP's own bare array with one summary per matching contract: no
284
+ * page envelope, no total. Without any filter SGP may answer with the whole contract base, so
285
+ * filter whenever you can. An empty array means no contract matched.
286
+ *
287
+ * Unknown fields reach `data` unchanged (the address SGP adds with `exibir_endereco` is one: it
288
+ * was never captured, so it is untyped and personal data; see `getSensitivity` and `pick`). Only
289
+ * each `id_contrato` and `id_cliente` must be numbers, and every element must be an object
290
+ * (`INVALID_RESPONSE` otherwise); any other field of the wrong type is left out of `data` and
291
+ * reported in `warnings` (the original stays in `response`).
120
292
  *
121
- * Used for `vendedor_id` when creating contracts (v1.1). Sellers are employees: name, CPF and
122
- * e-mail are personal data; strip them with `omitSensitive` and `sellerPersonalKeys` before
123
- * logging or forwarding.
293
+ * `plano` is a `PlanId` from `plans.list`, never an id of `preRegistrations.listPlans`. A read:
294
+ * the opt-in `maxRetries` may retry it.
124
295
  */
125
- listSellers: () => Promise<SgpResult<ListSellersResponse>>;
296
+ list: (input?: ContractsListInput, options?: CallOptions) => Promise<SgpResult<ContractsListData>>;
297
+ /**
298
+ * Changes the status of a contract: `POST /api/ura/contrato/status/edit/`, JSON. Never retried.
299
+ * Activating a contract starts its billing, so a status change is a billing event.
300
+ *
301
+ * SGP decides which transitions it allows; the SDK keeps no transition table. Evidence by
302
+ * transition: Suspenso to Ativo and Ativo to Suspenso returned 200 with the `resposta` body
303
+ * captured raw (`resposta.contrato_status` names the new status); Inativo to Ativo returned 200
304
+ * and a read-back confirmed it, but the body was not captured; Ativo to Inativo was refused with
305
+ * a 400 (the body is known from the support notes' prose, not from a capture; SGP's panel does
306
+ * not offer Inativo from Ativo). Status codes are in `CONTRACT_STATUS`, but any number is sent.
307
+ * `motivo` is the ID of a reason from the provider's own list: read it with
308
+ * `contracts.listStatusReasons`, never assume a value; it is optional, and omitted it is not
309
+ * sent (a call without it was never exercised).
310
+ *
311
+ * SGP's refusal, HTTP 400 `{ error: "Status de Contrato não alterado." }`, is `REJECTED` with
312
+ * `error.reason === "STATUS_NOT_CHANGED"` and effect `"none"`. Its body text is known from the
313
+ * support exchange only, not from a raw capture.
314
+ *
315
+ * Other failures carry `error.effect`: `"none"` only when the SDK can affirm nothing was applied
316
+ * (the input was refused locally, the call was cancelled before send, or SGP refused with a
317
+ * field/business error such as `errors` as an object, `error` or `detail`); `"unknown"` after a
318
+ * timeout, network failure, cancellation after send, an HTTP 5xx or 3xx, SGP's generic `errors`
319
+ * array, or a 2xx outside the contract (`INVALID_RESPONSE`). On `"unknown"`, read the contract
320
+ * (`contracts.list`) before sending again.
321
+ */
322
+ updateStatus: (input: ContractUpdateStatusInput, options?: CallOptions) => Promise<SgpResult<ContractUpdateStatusData>>;
323
+ /**
324
+ * Edits a contract: `POST /api/ura/contrato/edit/`, JSON. Never retried. Only `forma_cobranca`
325
+ * (the billing method, `BILLING_METHOD`) is accepted; changing it changes how the contract is
326
+ * billed. A success carries SGP's `resposta.alterados`, the list of fields SGP says it applied,
327
+ * returned as-is.
328
+ *
329
+ * Failures carry `error.effect` by the same rules as `contracts.updateStatus`; this route has no
330
+ * known rejection, so a 4xx is `"none"` only with an `errors` object, `error` or `detail` body.
331
+ * On `"unknown"`, read the contract before sending again.
332
+ */
333
+ update: (input: ContractUpdateInput, options?: CallOptions) => Promise<SgpResult<ContractUpdateData>>;
334
+ /**
335
+ * Lists the reasons the provider can register with a status change: `POST
336
+ * /api/ura/contrato/status/motivos/` (trailing slash), JSON, no input. Each provider has its own
337
+ * list, so read it before passing a `motivo` to `contracts.updateStatus` and never assume a
338
+ * value. The route is not paginated, so the result is SGP's own bare array of `{ id, motivo }`:
339
+ * no page envelope, no total. Unknown fields reach `data` unchanged. Only the `id` of each reason
340
+ * must be a number (an element that is not an object fails the response too:
341
+ * `INVALID_RESPONSE`); any other field of the wrong type is left out of `data` and reported in
342
+ * `warnings` (the original stays in `response`). A read: the opt-in `maxRetries` may retry it.
343
+ */
344
+ listStatusReasons: (options?: CallOptions) => Promise<SgpResult<ContractsListStatusReasonsData>>;
126
345
  }
127
- /** Methods that hit the `/api/crm/` routes. Writes: they return an {@link SgpWriteResult}. */
128
- export interface CrmClient {
346
+ /** Operations on installation coverage (SGP "viabilidade de instalação"). */
347
+ export interface CoverageClient {
348
+ /**
349
+ * Checks the viability of an installation around a coordinate: `GET /api/ura/viabilidadeinstalacao`
350
+ * (no trailing slash), params and credentials in the query string. `gateway`, `raio` (meters) and
351
+ * `coordenada` (`"lat,lng"`) are all required, or the call is refused locally (`INVALID_INPUT`,
352
+ * nothing sent). The SDK does not geocode: bring the coordinate yourself.
353
+ *
354
+ * The result keeps SGP's own shape: an array whose element is an object keyed by the gateway's
355
+ * own name (`SGPMaps`, `Geogrid`: data-defined), holding the CTOs within the radius (`lat`,
356
+ * `lng`, `distancia` in meters, `nome`, and `id` on Geogrid) or the message `"Localização
357
+ * inviável"` when there are none. Nothing is converted: Geogrid sends the numbers as text and
358
+ * they stay text, so check the type before computing. No page envelope.
359
+ *
360
+ * Unknown fields reach `data` unchanged. The structure must hold (the answer an array of objects,
361
+ * each gateway's answer a list of objects or a message, `INVALID_RESPONSE` otherwise); any field
362
+ * of a CTO of the wrong type is left out of `data` and reported in `warnings` (the original stays
363
+ * in `response`). The coordinate is personal data: see `getSensitivity("coverage.check")`. A
364
+ * read: the opt-in `maxRetries` may retry it.
365
+ */
366
+ check: (input: CoverageCheckInput, options?: CallOptions) => Promise<SgpResult<CoverageCheckData>>;
367
+ }
368
+ /** Operations on customers (SGP "clientes"). */
369
+ export interface CustomersClient {
129
370
  /**
130
- * Creates an individual (PF) customer: `POST /api/crm/cliente/F`.
371
+ * Lists one page of customers: `POST /api/ura/clientes/`. `paginacao` is SGP's own, `total`
372
+ * included; the SDK never computes it. Unknown fields reach `data` unchanged at every level.
373
+ * Only `paginacao.total`, `clientes` and the ids, name, document and type of each customer, plus
374
+ * the ids of contracts, services and plans, must have the expected type; an element of
375
+ * `clientes`, `contratos` or `servicos` that is not an object fails the response too
376
+ * (`INVALID_RESPONSE`). Any other field of the wrong type is left out of `data` and reported in
377
+ * `warnings` (`dropped` names the field that is absent; the original stays in `response`).
378
+ */
379
+ list: (input?: CustomersListInput, options?: CallOptions) => Promise<SgpResult<CustomersListData>>;
380
+ /**
381
+ * Searches customers by contract, document, name, PPPoE login or phone: `POST
382
+ * /api/ura/consultacliente/`, JSON. At least one criterion is required, or the call is refused
383
+ * locally (`INVALID_INPUT`, nothing sent). A text criterion (`cpfcnpj`, `nome`, `login`,
384
+ * `telefone`) cannot be an empty string, not even next to a valid criterion: that is parameter
385
+ * validation, not protection against a broad search (a string of spaces is not empty and goes to
386
+ * SGP as given). How criteria combine and how names and phones are matched is SGP's decision.
387
+ *
388
+ * It returns CANDIDATES and never picks one: `data.contratos` has one entry per matching
389
+ * contract, each carrying its customer's data flattened (`clienteId`, `razaoSocial`,
390
+ * `cpfCnpj`...). Any criterion other than `contrato` may match several contracts, of one customer
391
+ * or of different customers (the same document may belong to more than one customer), so decide
392
+ * between candidates yourself, by `clienteId` and `contratoId`. No match is a success with
393
+ * `contratos: []`. For a filtered, paginated list of customers with their contracts and services,
394
+ * use `customers.list`.
395
+ *
396
+ * Every candidate carries the service's Central and PPPoE credentials, Wi-Fi and the customer's
397
+ * identity and address: see `getSensitivity("customers.search")` and project with `pick` before
398
+ * logging or handing it on. Unknown fields reach `data` unchanged. Only `contratos`, and each
399
+ * candidate's `contratoId` and `clienteId`, must have the expected type (a candidate that is not
400
+ * an object fails the response too: `INVALID_RESPONSE`); any other field of the wrong type is left
401
+ * out of `data` and reported in `warnings` (the original stays in `response`). A read: the opt-in
402
+ * `maxRetries` may retry it.
403
+ */
404
+ search: (input: CustomersSearchInput, options?: CallOptions) => Promise<SgpResult<CustomersSearchData>>;
405
+ }
406
+ /** Annotations (SGP "anotações") of a customer. */
407
+ export interface ExperimentalAnnotationsClient {
408
+ /**
409
+ * EXPERIMENTAL: may change incompatibly in a minor release, without a major version.
410
+ *
411
+ * Lists the notes of a customer and/or a contract: `GET /api/ura/cliente/anotacao/list/`, query
412
+ * string. At least one of `cliente_id` and `contrato_id` is required (a positive safe integer);
413
+ * both together mean AND. Without a valid filter the call is refused locally (`INVALID_INPUT`,
414
+ * nothing sent), and a key other than those two is refused too, never forwarded.
415
+ *
416
+ * SGP ignores both filters and answers with the notes of other customers, so the SDK selects
417
+ * LOCALLY, over the one response it received, by each note's raw `cliente` and `clientecontrato`.
418
+ * A customer-only call keeps that customer's notes without a contract; a contract-only call keeps
419
+ * that contract's; no match is a success with `[]`, never a relaxed filter. Source order and
420
+ * duplicates are kept. A note that no definite mismatch excludes and whose requested identity is
421
+ * missing or not a number cannot be decided: the whole call is `INVALID_RESPONSE`
422
+ * (`error.issues` names `[].cliente` and/or `[].clientecontrato`), never a silent skip. A note of
423
+ * another customer is dropped before it is read, so its malformed fields do not matter.
424
+ *
425
+ * The selected notes are then read like any 2.0 response: `id`, `cliente`, `clientecontrato`
426
+ * (a number or `null`) and `anotacao` must have their type (`INVALID_RESPONSE` otherwise); any
427
+ * other known field of the wrong type is left out of `data` and reported in `warnings`, whose
428
+ * paths index the selected notes. Unknown fields of a selected note reach `data` unchanged, and
429
+ * each note also carries `raw`, a deep copy of that one record as SGP sent it (personal data like
430
+ * the note), so a field dropped from its typed position stays recoverable there. A selected note
431
+ * that embeds, at any depth, an identity of another customer (or of another contract when a
432
+ * contract was requested), or one that cannot be read, fails the call (`INVALID_RESPONSE`,
433
+ * `error.issues` `[].(nested).cliente` or `[].(nested).clientecontrato`). Identity keys are matched
434
+ * by pattern and letter case (`Cliente`, `cliente_id`, `clienteContrato`, `contratos`...), a number
435
+ * or a list of numbers is compared, and on a customer-only call another contract of the same
436
+ * customer is accepted only in an object that also names that customer.
437
+ *
438
+ * COMPLETENESS: returns the matching notes present in one SGP response; source completeness is
439
+ * not guaranteed while this method is experimental. The route documents no pagination, and an
440
+ * undocumented cap cannot be ruled out. The SDK sends one request, never pages, never truncates.
131
441
  *
132
- * Requires `nome`, `cpfcnpj` and `endereco`; the address is sent nested and as loose fields.
133
- * The response `message` carries the name and CPF; strip it with `omitSensitive` and
134
- * `customerCreatedPersonalKeys` before logging or forwarding.
442
+ * PRIVACY: the whole upstream body, other customers' notes included, enters this process's memory.
443
+ * The SDK never returns, caches or logs it: `response.body` is `{ kind: "withheld" }` whatever the
444
+ * status (a field dropped from `data` is recoverable from that note's `raw`, never from
445
+ * `response`), `error.sgp` keeps only strings, and no hook receives it. `request()` refuses this
446
+ * route (`ROUTE_NOT_ALLOWED`, nothing sent), so it cannot go around this method.
447
+ * A `fetch` or tracing layer you inject sees the body BEFORE the selection: it must not capture
448
+ * it. Local selection is not an authorization boundary: authorize the ids you pass, and run this
449
+ * only in a trusted server process. The note text (`anotacao`) and the staff member (`usuario`)
450
+ * are personal data, and the text may hold anything a person typed: see
451
+ * `getSensitivity("experimental.annotations.list")` and project with `pick` before logging or
452
+ * handing a note on. A read: the opt-in `maxRetries` may retry it, and each attempt downloads the
453
+ * whole response again.
454
+ */
455
+ list: (input: ExperimentalAnnotationsListInput, options?: CallOptions) => Promise<SgpResult<ExperimentalAnnotationsListData>>;
456
+ }
457
+ /** Operations that are not stable yet: they may change incompatibly in a minor release. */
458
+ export interface ExperimentalClient {
459
+ /** Customer annotations. */
460
+ annotations: ExperimentalAnnotationsClient;
461
+ }
462
+ /** Operations on invoices (SGP "títulos"). */
463
+ export interface InvoicesClient {
464
+ /**
465
+ * Lists one page of invoices: `POST /api/ura/titulos/`, JSON; every filter is optional. Returns
466
+ * ONE page with SGP's own `paginacao` as received: `offset` (index of the first invoice, from 0),
467
+ * `limit` (the page size SGP applied, which may differ from the requested one: SGP documents a
468
+ * maximum of 250), `parcial` (invoices on this page) and `total` (invoices matching the filters
469
+ * across all pages). The SDK never computes `total`: a page without a numeric `paginacao.total`
470
+ * is `INVALID_RESPONSE`. It never fetches the next page either: ask for it with `offset`.
471
+ *
472
+ * An empty page is a success with `titulos: []` (and, for a filter that matches nothing,
473
+ * `total: 0`). Unknown fields reach `data` unchanged at every level. Only `paginacao.total`,
474
+ * `titulos` and the `id` of each invoice must have the expected type (an element of `titulos` that
475
+ * is not an object fails the response too: `INVALID_RESPONSE`); any other field of the wrong type
476
+ * is left out of `data` and reported in `warnings` (the original stays in `response`).
135
477
  *
136
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
478
+ * Each invoice carries the customer's name and document, payment links and the PIX code: see
479
+ * `getSensitivity("invoices.list")` and project with `pick` before logging or handing it on. A
480
+ * read: the opt-in `maxRetries` may retry it.
137
481
  */
138
- createIndividualCustomer: (params: CreateIndividualCustomerParams) => Promise<SgpWriteResult<CreateCustomerResponse>>;
482
+ list: (input?: InvoicesListInput, options?: CallOptions) => Promise<SgpResult<InvoicesListData>>;
483
+ }
484
+ /** Operations on plans (SGP "planos"), the catalog of existing services and contracts. */
485
+ export interface PlansClient {
139
486
  /**
140
- * Creates a company (PJ) customer: `POST /api/crm/cliente/J`.
487
+ * Lists the plan catalog: `GET /api/ura/consultaplano/`, credentials in the query string. The
488
+ * route is not paginated, so the result keeps SGP's own shape (`planos` plus SGP's totals
489
+ * `total_planos` and `total_qtd_servicos`, as received), with no page envelope. Unknown fields
490
+ * reach `data` unchanged at every level. Only `planos` and the `id` of each plan must have the
491
+ * expected type (an element of `planos` that is not an object fails the response too:
492
+ * `INVALID_RESPONSE`); any other field of the wrong type is left out of `data` and reported in
493
+ * `warnings` (the original stays in `response`).
141
494
  *
142
- * Requires `nome`, `cpfcnpj` and `endereco`; the address is sent nested and as loose fields.
143
- * The response `message` carries the name and CNPJ; strip it with `omitSensitive` and
144
- * `customerCreatedPersonalKeys` before logging or forwarding.
495
+ * ID space: `planos[].id` is a `PlanId`, the identifier of the operations on existing services and
496
+ * contracts (the `plano` filter of `contracts.list`, `services.changePlan`, `services.addTv`,
497
+ * and the `servicos[].plano.id` of `customers.list`). It is NOT the id of
498
+ * `preRegistrations.listPlans` (a `PreRegistrationPlanId`), the catalog `preRegistrations.create`
499
+ * takes `plano_id` from: the same commercial plan may carry another id there. The two types are
500
+ * kept apart on purpose, in both directions.
145
501
  *
146
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
502
+ * A read: the opt-in `maxRetries` may retry it.
147
503
  */
148
- createCompanyCustomer: (params: CreateCompanyCustomerParams) => Promise<SgpWriteResult<CreateCustomerResponse>>;
504
+ list: (options?: CallOptions) => Promise<SgpResult<PlansListData>>;
505
+ }
506
+ /** Operations on pré-cadastros (pre-registrations). */
507
+ export interface PreRegistrationsClient {
149
508
  /**
150
- * Creates a contract on a CRM customer: `POST /api/crm/cliente/{cliente_id}/contratos/`.
509
+ * Creates a pré-cadastro: `POST /api/precadastro/F` or `/J`, picked by `input.personType`, sent as
510
+ * `multipart/form-data` without files. The address goes in SGP's own loose top-level fields
511
+ * (`logradouro`, `numero`, ...), not grouped. Never retried.
151
512
  *
152
- * Requires `pop_id`, `plano_id`, `portador_id`, `forma_cobranca_codigo` (`formaCobrancaCodigo`),
153
- * `vencimento_dia` and both addresses: `endereco_instalacao` and `endereco_cobranca`, sent
154
- * nested; the installation one also goes as loose fields. SGP requires `login` and `senha`
155
- * (PPPoE) for an internet service. The params carry secrets (`login`, `senha`, `central_login`,
156
- * `central_senha`): never log them. The response `cliente` is the customer's name; strip it with
157
- * `omitSensitive` and `contractCreatedPersonalKeys` before logging or forwarding.
513
+ * What it does in SGP: with `precadastro_ativar: 1` the pré-cadastro becomes a definitive
514
+ * customer, and a contract is created only when the plan and billing data are sufficient
515
+ * (`plano_id`, `pop_id`, `portador_id`, `vencimento_id`, `formacobranca_id`, ...). The pré-cadastro
516
+ * row itself keeps existing afterwards. A success carries only SGP's `message`: it holds no
517
+ * customer, contract or pré-cadastro ID, so look the customer up (`customers.list` by `cpfcnpj`)
518
+ * to follow up. `plano_id` is a `PreRegistrationPlanId`: it comes from `preRegistrations.listPlans`, never a `PlanId` of `plans.list`; `vencimento_id` from `preRegistrations.listDueDays` and `vendedor_id` from `preRegistrations.listSellers`.
158
519
  *
159
- * The loose address fields carry the installation address. A billing address different from the
160
- * installation one has not been verified live. `error.detail` is SGP's text and may echo submitted
161
- * values (e.g. `senha`): treat it as sensitive before logging.
520
+ * Failures carry `error.effect`: `"none"` only when the SDK can affirm nothing was applied (the
521
+ * input was refused locally, the call was cancelled before send, or SGP refused with a
522
+ * field/business error such as `errors` as an object, `error` or `detail`); `"unknown"` after a
523
+ * timeout, network failure, cancellation after send, an HTTP 5xx or 3xx, SGP's generic `errors`
524
+ * array, or a 2xx outside the contract (`INVALID_RESPONSE`). On `"unknown"`, check SGP before
525
+ * sending again: a second call may create a duplicate.
162
526
  *
163
- * `os_instalacao` opens the installation service order without a date; to schedule one, use
164
- * `ura.openTicket`. The boleto delivery methods and the invoice (nota fiscal) are not in the
165
- * API: they stay empty.
527
+ * An existing CPF is refused with HTTP 402 and `error.reason === "DOCUMENT_ALREADY_REGISTERED"`
528
+ * (`REJECTED`, effect `"none"`, observed live on `/F`).
166
529
  *
167
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
530
+ * Evidence: only `/F` was exercised; the 200 body `{ message }` is the vendor's, only the key
531
+ * `message` was seen live; `/J` follows the vendor's documentation.
168
532
  */
169
- createContract: (clienteId: number, params: CreateContractParams) => Promise<SgpWriteResult<CreateContractResponse>>;
533
+ create: (input: PreRegistrationCreateInput, options?: CallOptions) => Promise<SgpResult<PreRegistrationCreateData>>;
170
534
  /**
171
- * Sets the CRM status of a customer: `POST /api/crm/cliente/{cliente_id}/status/`.
535
+ * Lists the plans of the pré-cadastro catalog: `POST /api/precadastro/plano/list`
536
+ * (no trailing slash), sent as `multipart/form-data` without files and with no input. The route
537
+ * is not paginated, so the result is SGP's own bare array: no page envelope, no total. Unknown
538
+ * fields reach `data` unchanged at every level. Only the `id` of each plan must be a number (an
539
+ * element that is not an object fails the response too: `INVALID_RESPONSE`); any other field of
540
+ * the wrong type is left out of `data` and reported in `warnings` (the original stays in
541
+ * `response`). `gateway.id` and `gateway.gateway_id` are kept as SGP sends them, `""` or text or
542
+ * number.
172
543
  *
173
- * Set `crmStatus.contratoRealizadoNoSgp` after the contract, or SGP's screen keeps the customer
174
- * as a CRM customer and blocks contract status changes. The response `message` carries the
175
- * customer's name; strip it with `omitSensitive` and `customerStatusPersonalKeys` before
176
- * logging or forwarding.
544
+ * ID space: `id` is a `PreRegistrationPlanId`, the one `preRegistrations.create` takes as
545
+ * `plano_id`. It is NOT a `PlanId` of `plans.list`: the same commercial plan may carry another id
546
+ * there, and an id accepted by one route can be refused by the other. The two types are kept
547
+ * apart on purpose, in both directions. A read: the opt-in `maxRetries` may retry it.
548
+ */
549
+ listPlans: (options?: CallOptions) => Promise<SgpResult<PreRegistrationsListPlansData>>;
550
+ /**
551
+ * Lists the due days of the pré-cadastro: `POST /api/precadastro/vencimento/list` (no trailing
552
+ * slash), JSON, no input. The route is not paginated, so the result is SGP's own bare array: no
553
+ * page envelope, no total. Each entry pairs an `id` (what `preRegistrations.create` takes as
554
+ * `vencimento_id`) with the `dia` of the month it stands for: read it, never assume a value.
555
+ * Unknown fields reach `data` unchanged. Only the `id` of each entry must be a number (an element
556
+ * that is not an object fails the response too: `INVALID_RESPONSE`); any other field of the wrong
557
+ * type is left out of `data` and reported in `warnings` (the original stays in `response`). A
558
+ * read: the opt-in `maxRetries` may retry it.
559
+ */
560
+ listDueDays: (options?: CallOptions) => Promise<SgpResult<PreRegistrationsListDueDaysData>>;
561
+ /**
562
+ * Lists the sellers: `POST /api/precadastro/vendedor/list` (no trailing slash), JSON, no input.
563
+ * The route is not paginated, so the result is SGP's own bare array: no page envelope, no total.
564
+ * `id` is what `preRegistrations.create` takes as `vendedor_id`. Unknown fields reach `data`
565
+ * unchanged. Only the `id` of each seller must be a number (an element that is not an object
566
+ * fails the response too: `INVALID_RESPONSE`); any other field of the wrong type is left out of
567
+ * `data` and reported in `warnings` (the original stays in `response`).
177
568
  *
178
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
569
+ * Sellers are employees of the provider: name, CPF and e-mail are personal data, see
570
+ * `getSensitivity("preRegistrations.listSellers")` and project with `pick` before logging or
571
+ * handing it on. A read: the opt-in `maxRetries` may retry it.
179
572
  */
180
- updateCustomerStatus: (clienteId: number, params: UpdateCustomerStatusParams) => Promise<SgpWriteResult<UpdateCustomerStatusResponse>>;
573
+ listSellers: (options?: CallOptions) => Promise<SgpResult<PreRegistrationsListSellersData>>;
181
574
  }
182
- /** Methods that hit the `/api/suporte/` routes. */
183
- export interface SuporteClient {
575
+ /** Operations on work orders (SGP "ordens de serviço"). */
576
+ export interface WorkOrdersClient {
184
577
  /**
185
- * Attaches a document to a customer: `PUT /api/suporte/cliente/{cliente_id}/documento/add/`,
186
- * sent as multipart with the file in the `file` part.
578
+ * Lists one page of work orders: `POST /api/ura/ordemservico/list/`, JSON; every filter is
579
+ * optional. Returns ONE page with SGP's own `paginacao` as received: `offset` (index of the first
580
+ * work order, from 0), `limit` (the page size SGP applied, which may differ from the requested
581
+ * one), `parcial` (work orders on this page) and `total` (work orders matching the filters across
582
+ * all pages). The SDK never computes `total`: a page without a numeric `paginacao.total` is
583
+ * `INVALID_RESPONSE`. It never fetches the next page either: ask for it with `offset`.
187
584
  *
188
- * SGP answers 200 with an empty body and does not return the document ID: `data` is `null`. To
189
- * check the upload, use `listCustomerDocuments`. SGP converts images to `.jpeg`, so the stored
190
- * file name may differ from `file.filename`. `descricao` is personal data when it names the
191
- * customer.
585
+ * An empty page is a success with `ordens_servicos: []`. Unknown fields reach `data` unchanged at
586
+ * every level. Only `paginacao.total`, `ordens_servicos` and the `id` of each work order must have
587
+ * the expected type (an element that is not an object fails the response too:
588
+ * `INVALID_RESPONSE`); any other field of the wrong type is left out of `data` and reported in
589
+ * `warnings` (the original stays in `response`). The occurrence number (`ocorrencia`) is text and
590
+ * stays text.
192
591
  *
193
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
592
+ * Each work order carries the customer's name, free text and the people involved: see
593
+ * `getSensitivity("workOrders.list")` and project with `pick` before logging or handing it on. A
594
+ * read: the opt-in `maxRetries` may retry it.
194
595
  */
195
- addCustomerDocument: (clienteId: number, file: SgpFile, params?: AddCustomerDocumentParams) => Promise<SgpWriteResult<AddCustomerDocumentResponse>>;
596
+ list: (input?: WorkOrdersListInput, options?: CallOptions) => Promise<SgpResult<WorkOrdersListData>>;
196
597
  /**
197
- * Lists the documents attached to a customer: `GET /api/suporte/cliente/{cliente_id}/documento/list/`.
598
+ * Lists the occurrence reasons (the `motivo` of a work order): `GET /api/os/ocorrencia/motivo/list/`,
599
+ * credentials in the query string, no input. The route is not paginated, so the result is SGP's
600
+ * own bare array: no page envelope, no total. Each reason has two identifiers, `id` and `codigo`,
601
+ * both numbers and kept apart as SGP sends them: `occurrences.create` takes the `codigo` as
602
+ * `motivoos` (the vendor's collection says "Código"; live, `motivoos` 10 was the reason whose
603
+ * `codigo` is 10 and `id` 1). Unknown fields reach `data` unchanged. Only `id` and `codigo` of each reason must be
604
+ * numbers (an element that is not an object fails the response too: `INVALID_RESPONSE`); any
605
+ * other field of the wrong type is left out of `data` and reported in `warnings` (the original
606
+ * stays in `response`). `classificacoes` and `setores` were always empty in the captures: their
607
+ * content is untyped. A read: the opt-in `maxRetries` may retry it.
608
+ */
609
+ listReasons: (options?: CallOptions) => Promise<SgpResult<WorkOrdersListReasonsData>>;
610
+ }
611
+ /** Operations on services (SGP "serviços") of a contract. */
612
+ export interface ServicesClient {
613
+ /**
614
+ * Changes the plan of a service: `POST /api/suporte/service/update/{servico_id}/` (trailing
615
+ * slash), `multipart/form-data` without files, with `action` fixed to `change_plano`. Never
616
+ * retried. A plan change is a billing event.
198
617
  *
199
- * Each document carries the file name or link (`arquivo`), its description and the operator:
200
- * personal data; strip it with `omitSensitive` and `customerDocumentPersonalKeys` before logging
201
- * or forwarding.
618
+ * `plano_id` is a `PlanId` from the URA catalog (`plans.list`). `servico_tipo` is required; only `1`
619
+ * (`SERVICE_TYPE.internet`) was exercised against SGP, other values are sent as given and SGP
620
+ * decides. A success carries SGP's `msg` only, with no ID of the service or the plan: read the
621
+ * contract (`customers.list`) to confirm the new plan.
622
+ *
623
+ * Failures carry `error.effect`: `"none"` only when the SDK can affirm nothing was applied (the
624
+ * input was refused locally, including a `servico_id` that is not a positive safe integer, the
625
+ * call was cancelled before send, or SGP refused with a field/business error such as `errors` as
626
+ * an object, `error` or `detail`); `"unknown"` after a timeout, network failure, cancellation
627
+ * after send, an HTTP 5xx or 3xx, SGP's generic `errors` array, or a 2xx outside the contract
628
+ * (`INVALID_RESPONSE`). This route has no known rejection. On `"unknown"`, read the service
629
+ * before sending again.
202
630
  */
203
- listCustomerDocuments: (clienteId: number) => Promise<SgpResult<ListCustomerDocumentsResponse>>;
631
+ changePlan: (input: ServiceChangePlanInput, options?: CallOptions) => Promise<SgpResult<ServiceChangePlanData>>;
632
+ /**
633
+ * Adds a TV service to a contract: `POST /api/servico/tv` (no trailing slash),
634
+ * `multipart/form-data` without files. Never retried. Adding a service changes what the contract
635
+ * is billed for.
636
+ *
637
+ * `planobase_id` is a `PlanId` from the URA catalog (`plans.list`). SGP accepts only active contracts. A
638
+ * success (HTTP 201) returns the new `servico_id` (a number); `clientecontrato_id` is kept as the
639
+ * string SGP sends. Only `info_extra` was exercised among the optional fields; `tipo_equipamento`
640
+ * and `endereco_id` are documented by the vendor and never sent.
641
+ *
642
+ * SGP's refusal of a contract that is not active, HTTP 400
643
+ * `{ errors: ["clientecontrato_id: Só é possível adicionar serviços em contratos ativos."] }`, is
644
+ * `REJECTED` with `error.reason === "CONTRACT_NOT_ACTIVE"` and effect `"none"` (a read-back after
645
+ * the observed refusal showed nothing added on read-back; its raw body is reconstructed). Any other `errors` array is SGP's generic wrapper and
646
+ * stays `"unknown"`.
647
+ *
648
+ * Other failures carry `error.effect` by the same rules as `services.changePlan`. On
649
+ * `"unknown"`, read the contract's services before sending again: a second call may add a
650
+ * duplicate service.
651
+ */
652
+ addTv: (input: ServiceAddTvInput, options?: CallOptions) => Promise<SgpResult<ServiceAddTvData>>;
653
+ /**
654
+ * Removes a TV service: `DELETE /api/servico/tv/{servico_id}` (no trailing slash), with the
655
+ * contract in a `multipart/form-data` body (without files), as SGP expects. Never retried.
656
+ *
657
+ * A success returns SGP's `msg`, the removed `servico_id` and `clientecontrato_id` (kept as the
658
+ * string SGP sends). This route has no known rejection; failures carry `error.effect` by the same
659
+ * rules as `services.changePlan`. On `"unknown"`, read the contract's services before sending
660
+ * again.
661
+ */
662
+ removeTv: (input: ServiceRemoveTvInput, options?: CallOptions) => Promise<SgpResult<ServiceRemoveTvData>>;
204
663
  }
205
- /**
206
- * SGP client. Reads return an {@link SgpResult}, writes (`crm`, `ura.openTicket`,
207
- * `suporte.addCustomerDocument`) an {@link SgpWriteResult}; no method ever throws.
208
- */
664
+ /** SGP 2.0 client. */
209
665
  export interface SgpClient {
210
- ura: UraClient;
211
- os: OsClient;
212
- precadastro: PrecadastroClient;
666
+ /** Operations on catalogs (POPs, NAS, billing profiles). */
667
+ catalogs: CatalogsClient;
668
+ /** Operations on contracts. */
669
+ contracts: ContractsClient;
670
+ /** Operations on installation coverage. */
671
+ coverage: CoverageClient;
672
+ /** Operations of the CRM funnel. */
213
673
  crm: CrmClient;
214
- suporte: SuporteClient;
674
+ /** Operations on customers. */
675
+ customers: CustomersClient;
676
+ /** Operations on customers' documents. */
677
+ documents: DocumentsClient;
678
+ /**
679
+ * Operations that may change incompatibly in a minor release; SemVer holds for everything else.
680
+ */
681
+ experimental: ExperimentalClient;
682
+ /** Operations on invoices. */
683
+ invoices: InvoicesClient;
684
+ /** Operations on occurrences. */
685
+ occurrences: OccurrencesClient;
686
+ /** Operations on plans. */
687
+ plans: PlansClient;
688
+ /** Operations on pré-cadastros. */
689
+ preRegistrations: PreRegistrationsClient;
690
+ /**
691
+ * Raw call to a route no method covers yet. A developer tool: never expose it as an agent or
692
+ * MCP tool, and never build `path` or `body` from untrusted input.
693
+ *
694
+ * It uses the client's credentials, time budget, cancellation and hooks, and classifies by
695
+ * HTTP alone (the same status mapping as every method). Nothing else is interpreted: `ok: true`
696
+ * means SGP accepted the request at HTTP level (a 2xx), never that the business operation
697
+ * succeeded: SGP answers some refusals with a 200, so read `data` yourself. `data` is the body
698
+ * as received (parsed JSON, text, or `undefined` when empty), typed `unknown`; `response` is the
699
+ * full evidence.
700
+ *
701
+ * Destination: only a relative path under `/api/` of the configured instance is accepted (see
702
+ * {@link RawRequestInput.path}; a `;` is sent literally and stays on the same origin, under
703
+ * `/api/`); anything else is `INVALID_INPUT` with `effect: "none"` and `attempts: 0`, and
704
+ * nothing is sent. The annotations route is refused as `ROUTE_NOT_ALLOWED` (same effect and
705
+ * attempts; use `experimental.annotations.list`). Redirects are never followed: a 3xx is `INVALID_RESPONSE`.
706
+ * It is never retried, whatever `maxRetries` says.
707
+ *
708
+ * Effect: `"none"` only when the call was refused or cancelled before send. After a request was
709
+ * sent every failure is `"unknown"`, a 4xx included, and the HTTP verb is never taken as proof
710
+ * that a call only reads: check SGP before sending again.
711
+ *
712
+ * Sensitivity: the result declares no sensitive keys, so treat `data` and `response` as
713
+ * sensitive. The body is not redacted and may echo credentials or personal data (only header
714
+ * values are redacted); `toSafeLog` leaves it out. Log `toSafeLog(result)`, and send on only what `pick` names; an unknown key is
715
+ * never safe. Hooks get the method but never the path.
716
+ */
717
+ request: (input: RawRequestInput, options?: CallOptions) => Promise<SgpResult<unknown>>;
718
+ /** Operations on services. */
719
+ services: ServicesClient;
720
+ /** Operations on work orders. */
721
+ workOrders: WorkOrdersClient;
215
722
  }
216
- /** Creates an SGP client bound to `config`; `token` and `app` are sent on every request. */
217
- export declare const createSgpClient: (config: SgpClientConfig) => SgpClient;
723
+ /** Creates a client. Throws `InvalidConfigurationError` for an invalid configuration. */
724
+ export declare const createSgpClient: (options: ClientOptions) => SgpClient;