@greatapps/common 1.1.446 → 1.1.448
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/plans/services/plans.service.mjs +16 -11
- package/dist/modules/plans/services/plans.service.mjs.map +1 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs +31 -1
- package/dist/modules/subscriptions/types/subscription.type.mjs.map +1 -1
- package/package.json +1 -1
- package/src/modules/plans/services/plans.service.ts +48 -36
- package/src/modules/subscriptions/types/subscription.type.ts +30 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "server-only";
|
|
2
|
-
import { api,
|
|
2
|
+
import { api, getUserContext } from "@greatapps/common/server";
|
|
3
3
|
import { ApiError, buildQueryParams, PlanSchema } from "@greatapps/common";
|
|
4
4
|
import greatCache from "@greatapps/cache";
|
|
5
5
|
const PLANS_CACHE_TTL = 604800;
|
|
@@ -22,7 +22,11 @@ class PlansService {
|
|
|
22
22
|
* GET /{id_wl}/plans?active=true&search=client&sort=id:ASC
|
|
23
23
|
*/
|
|
24
24
|
async listPlans(params) {
|
|
25
|
-
const
|
|
25
|
+
const { id_account } = await getUserContext();
|
|
26
|
+
const cacheKey = this.buildCacheKey("plans", {
|
|
27
|
+
...params,
|
|
28
|
+
id_account
|
|
29
|
+
});
|
|
26
30
|
const cachedData = await this.cache.select(cacheKey);
|
|
27
31
|
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
28
32
|
const data2 = JSON.parse(cachedData.data);
|
|
@@ -31,10 +35,11 @@ class PlansService {
|
|
|
31
35
|
const query = buildQueryParams({
|
|
32
36
|
sort: params?.sort ?? "id:ASC",
|
|
33
37
|
active: params?.active,
|
|
34
|
-
search: params?.search
|
|
38
|
+
search: params?.search,
|
|
39
|
+
id_account
|
|
35
40
|
});
|
|
36
41
|
const url = `/plans${query ? `?${query}` : ""}`;
|
|
37
|
-
const response = await
|
|
42
|
+
const response = await api.apps.get(url);
|
|
38
43
|
if (response.status === 0) {
|
|
39
44
|
throw new ApiError(
|
|
40
45
|
response.message || "Erro ao listar planos",
|
|
@@ -52,14 +57,18 @@ class PlansService {
|
|
|
52
57
|
};
|
|
53
58
|
}
|
|
54
59
|
async findById(idPlan) {
|
|
55
|
-
const
|
|
60
|
+
const { id_account } = await getUserContext();
|
|
61
|
+
const cacheKey = this.buildCacheKey(`plan-${idPlan}`, {
|
|
62
|
+
id_account: String(id_account)
|
|
63
|
+
});
|
|
56
64
|
const cachedData = await this.cache.select(cacheKey);
|
|
57
65
|
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
58
66
|
const data = JSON.parse(cachedData.data);
|
|
59
67
|
return { data, success: true };
|
|
60
68
|
}
|
|
69
|
+
const query = buildQueryParams({ type: "client", id_account });
|
|
61
70
|
const response = await api.apps.get(
|
|
62
|
-
`/plans/${idPlan}
|
|
71
|
+
`/plans/${idPlan}?${query}`
|
|
63
72
|
);
|
|
64
73
|
if (response.status === 0) {
|
|
65
74
|
throw new ApiError(
|
|
@@ -69,11 +78,7 @@ class PlansService {
|
|
|
69
78
|
);
|
|
70
79
|
}
|
|
71
80
|
if (!response.data?.length) {
|
|
72
|
-
throw new ApiError(
|
|
73
|
-
"Plano n\xE3o encontrado",
|
|
74
|
-
"PLAN_NOT_FOUND",
|
|
75
|
-
404
|
|
76
|
-
);
|
|
81
|
+
throw new ApiError("Plano n\xE3o encontrado", "PLAN_NOT_FOUND", 404);
|
|
77
82
|
}
|
|
78
83
|
const plan = PlanSchema.parse(response.data[0]);
|
|
79
84
|
await this.cache.insert(cacheKey, JSON.stringify(plan), PLANS_CACHE_TTL);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/plans/services/plans.service.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/plans/services/plans.service.ts"],"sourcesContent":["import \"server-only\";\n\nimport { api, apiClient, getUserContext } from \"@greatapps/common/server\";\nimport { ApiError, buildQueryParams, PlanSchema } from \"@greatapps/common\";\nimport type {\n ApiPaginatedActionResult,\n PaginatedSuccessResult,\n Plan,\n SuccessResult,\n} from \"@greatapps/common\";\nimport greatCache from \"@greatapps/cache\";\n\nexport type ListPlansParams = {\n sort?: string;\n active?: boolean;\n search?: string;\n};\n\nconst PLANS_CACHE_TTL = 604800;\n\nclass PlansService {\n private cache = new greatCache({\n service: \"plans\",\n version: \"1.0.2\",\n domain: \"whitelabel-cache.greatapps.com.br\",\n ambient: process.env.NODE_ENV || \"development\",\n });\n\n private buildCacheKey(key: string, params?: Record<string, unknown>): string {\n const sort = params?.sort ?? \"id:ASC\";\n const active = params?.active ?? \"\";\n const search = params?.search ?? \"\";\n return `${key}-${sort}-${active}-${search}-v2`;\n }\n\n /**\n * Lista planos do whitelabel.\n * Exemplo:\n * GET /{id_wl}/plans?active=true&search=client&sort=id:ASC\n */\n async listPlans(\n params?: ListPlansParams,\n ): Promise<PaginatedSuccessResult<Plan>> {\n const { id_account } = await getUserContext();\n const cacheKey = this.buildCacheKey(\"plans\", {\n ...params,\n id_account,\n });\n\n const cachedData = await this.cache.select(cacheKey);\n\n if (cachedData.status == 1 && \"data\" in cachedData && cachedData.data) {\n const data = JSON.parse(cachedData.data) as Plan[];\n return { data, total: data.length, success: true };\n }\n\n const query = buildQueryParams({\n sort: params?.sort ?? \"id:ASC\",\n active: params?.active,\n search: params?.search,\n id_account: id_account,\n });\n const url = `/plans${query ? `?${query}` : \"\"}`;\n\n const response = await api.apps.get<ApiPaginatedActionResult<Plan[]>>(url);\n\n if (response.status === 0) {\n throw new ApiError(\n (response as { message?: string }).message || \"Erro ao listar planos\",\n \"LIST_PLANS_FAILED\",\n 400,\n );\n }\n\n const rawData = (response as { data?: unknown }).data;\n const data = Array.isArray(rawData)\n ? rawData.map((item) => PlanSchema.parse(item))\n : [];\n\n await this.cache.insert(cacheKey, JSON.stringify(data), PLANS_CACHE_TTL);\n\n return {\n data,\n total: response.total,\n success: true,\n } satisfies PaginatedSuccessResult<Plan>;\n }\n\n async findById(idPlan: number | string): Promise<SuccessResult<Plan>> {\n const { id_account } = await getUserContext();\n const cacheKey = this.buildCacheKey(`plan-${idPlan}`, {\n id_account: String(id_account),\n });\n\n const cachedData = await this.cache.select(cacheKey);\n\n if (cachedData.status == 1 && \"data\" in cachedData && cachedData.data) {\n const data = JSON.parse(cachedData.data) as Plan;\n return { data, success: true };\n }\n\n const query = buildQueryParams({ type: \"client\", id_account });\n\n const response = await api.apps.get<ApiPaginatedActionResult<Plan>>(\n `/plans/${idPlan}?${query}`,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao buscar plano\",\n \"FIND_PLAN_FAILED\",\n 400,\n );\n }\n\n if (!response.data?.length) {\n throw new ApiError(\"Plano não encontrado\", \"PLAN_NOT_FOUND\", 404);\n }\n\n const plan = PlanSchema.parse(response.data[0]);\n\n await this.cache.insert(cacheKey, JSON.stringify(plan), PLANS_CACHE_TTL);\n\n return {\n success: true,\n data: plan,\n };\n }\n}\n\nexport const plansService = new PlansService();\n"],"mappings":"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","names":["data"]}
|
|
@@ -48,7 +48,37 @@ const SubscriptionSchema = z.object({
|
|
|
48
48
|
card_name: z.string().nullable().optional(),
|
|
49
49
|
card_brand: z.string().nullable().optional(),
|
|
50
50
|
card_number: z.string().nullable().optional(),
|
|
51
|
-
items: z.array(SubscriptionItemSchema)
|
|
51
|
+
items: z.array(SubscriptionItemSchema),
|
|
52
|
+
pending_change: z.object({
|
|
53
|
+
schedule_id: z.string(),
|
|
54
|
+
schedule_status: z.string(),
|
|
55
|
+
kind: z.string(),
|
|
56
|
+
takes_effect_at: z.number(),
|
|
57
|
+
takes_effect_at_iso: z.string(),
|
|
58
|
+
new_plan: z.object({
|
|
59
|
+
id: z.number(),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
periodicity: z.number(),
|
|
62
|
+
value: z.number(),
|
|
63
|
+
value_gross: z.number()
|
|
64
|
+
}),
|
|
65
|
+
new_items: z.array(z.object({
|
|
66
|
+
price_id: z.string(),
|
|
67
|
+
id_addon: z.number().nullable(),
|
|
68
|
+
addon_name: z.string(),
|
|
69
|
+
quantity: z.number(),
|
|
70
|
+
unit_value: z.number(),
|
|
71
|
+
value: z.number(),
|
|
72
|
+
is_plan_base: z.boolean(),
|
|
73
|
+
is_ai_credit: z.boolean()
|
|
74
|
+
})),
|
|
75
|
+
new_discounts: z.array(z.unknown()),
|
|
76
|
+
changes: z.array(z.object({
|
|
77
|
+
type: z.string(),
|
|
78
|
+
from: z.unknown(),
|
|
79
|
+
to: z.unknown()
|
|
80
|
+
}))
|
|
81
|
+
}).nullable().optional()
|
|
52
82
|
});
|
|
53
83
|
export {
|
|
54
84
|
SubscriptionItemSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\n\r\nexport const SubscriptionItemSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string().optional(),\r\n value: z.number(),\r\n currency: z.string(),\r\n quantity: z.number(),\r\n payment_status: z.number(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean(),\r\n trial_ends_at: z.coerce.date().nullable().optional(),\r\n});\r\n\r\nexport type SubscriptionItem = z.infer<typeof SubscriptionItemSchema>;\r\n\r\nexport const SubscriptionSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_account: z.union([z.number(), z.string()]),\r\n id_card: z.union([z.number(), z.string()]).nullable(),\r\n id_coupon: z.union([z.number(), z.string()]).nullable(),\r\n type: z.string(),\r\n payment_method: z.number().nullable(),\r\n periodicity: z.coerce.number().nullable(),\r\n value: z.number().nullable(),\r\n id_product: z.number(),\r\n id_plan: z.number(),\r\n plan_name: z.string().nullable().optional(),\r\n id_gateway: z.union([z.number(), z.string()]).nullable(),\r\n gateway_account: z.string().nullable(),\r\n date_hiring: z.coerce.date().nullable(),\r\n date_due: z.coerce.date(),\r\n date_cancellation: z.coerce.date().nullable(),\r\n date_verification: z.coerce.date().nullable(),\r\n cancellation_reason: z.string().nullable(),\r\n cancellation_description: z.string().nullable(),\r\n active: z.boolean(),\r\n charged: z.boolean(),\r\n datetime_last_update_periodicity: z.coerce.date().nullable().optional(),\r\n card_name: z.string().nullable().optional(),\r\n card_brand: z.string().nullable().optional(),\r\n card_number: z.string().nullable().optional(),\r\n items: z.array(SubscriptionItemSchema),\r\n});\r\n\r\nexport type Subscription = z.infer<typeof SubscriptionSchema>;\r\n\r\nexport interface FindSubscriptionsParams {\r\n active?: boolean;\r\n trial?: boolean;\r\n date_start?: string;\r\n date_end?: string;\r\n date_hiring_start?: string;\r\n date_hiring_end?: string;\r\n limit?: number;\r\n}\r\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\n\r\nexport const SubscriptionItemSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string().optional(),\r\n value: z.number(),\r\n currency: z.string(),\r\n quantity: z.number(),\r\n payment_status: z.number(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean(),\r\n trial_ends_at: z.coerce.date().nullable().optional(),\r\n});\r\n\r\nexport type SubscriptionItem = z.infer<typeof SubscriptionItemSchema>;\r\n\r\nexport const SubscriptionSchema = z.object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_alt: z.coerce.date().nullable().optional(),\r\n datetime_del: z.coerce.date().nullable().optional(),\r\n datetime_add: z.coerce.date(),\r\n id_wl: z.number(),\r\n id_account: z.union([z.number(), z.string()]),\r\n id_card: z.union([z.number(), z.string()]).nullable(),\r\n id_coupon: z.union([z.number(), z.string()]).nullable(),\r\n type: z.string(),\r\n payment_method: z.number().nullable(),\r\n periodicity: z.coerce.number().nullable(),\r\n value: z.number().nullable(),\r\n id_product: z.number(),\r\n id_plan: z.number(),\r\n plan_name: z.string().nullable().optional(),\r\n id_gateway: z.union([z.number(), z.string()]).nullable(),\r\n gateway_account: z.string().nullable(),\r\n date_hiring: z.coerce.date().nullable(),\r\n date_due: z.coerce.date(),\r\n date_cancellation: z.coerce.date().nullable(),\r\n date_verification: z.coerce.date().nullable(),\r\n cancellation_reason: z.string().nullable(),\r\n cancellation_description: z.string().nullable(),\r\n active: z.boolean(),\r\n charged: z.boolean(),\r\n datetime_last_update_periodicity: z.coerce.date().nullable().optional(),\r\n card_name: z.string().nullable().optional(),\r\n card_brand: z.string().nullable().optional(),\r\n card_number: z.string().nullable().optional(),\r\n items: z.array(SubscriptionItemSchema),\r\n pending_change: z.object({\r\n schedule_id: z.string(),\r\n schedule_status: z.string(),\r\n kind: z.string(),\r\n takes_effect_at: z.number(),\r\n takes_effect_at_iso: z.string(),\r\n new_plan: z.object({\r\n id: z.number(),\r\n name: z.string(),\r\n periodicity: z.number(),\r\n value: z.number(),\r\n value_gross: z.number(),\r\n }),\r\n new_items: z.array(z.object({\r\n price_id: z.string(),\r\n id_addon: z.number().nullable(),\r\n addon_name: z.string(),\r\n quantity: z.number(),\r\n unit_value: z.number(),\r\n value: z.number(),\r\n is_plan_base: z.boolean(),\r\n is_ai_credit: z.boolean(),\r\n })),\r\n new_discounts: z.array(z.unknown()),\r\n changes: z.array(z.object({\r\n type: z.string(),\r\n from: z.unknown(),\r\n to: z.unknown(),\r\n })),\r\n }).nullable().optional(),\r\n});\r\n\r\nexport type Subscription = z.infer<typeof SubscriptionSchema>;\r\n\r\nexport interface FindSubscriptionsParams {\r\n active?: boolean;\r\n trial?: boolean;\r\n date_start?: string;\r\n date_end?: string;\r\n date_hiring_start?: string;\r\n date_hiring_end?: string;\r\n limit?: number;\r\n}\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { api, apiClient } from
|
|
4
|
-
import { ApiError, buildQueryParams, PlanSchema } from
|
|
5
|
-
import type {
|
|
6
|
-
|
|
1
|
+
import "server-only";
|
|
2
|
+
|
|
3
|
+
import { api, apiClient, getUserContext } from "@greatapps/common/server";
|
|
4
|
+
import { ApiError, buildQueryParams, PlanSchema } from "@greatapps/common";
|
|
5
|
+
import type {
|
|
6
|
+
ApiPaginatedActionResult,
|
|
7
|
+
PaginatedSuccessResult,
|
|
8
|
+
Plan,
|
|
9
|
+
SuccessResult,
|
|
10
|
+
} from "@greatapps/common";
|
|
11
|
+
import greatCache from "@greatapps/cache";
|
|
7
12
|
|
|
8
13
|
export type ListPlansParams = {
|
|
9
14
|
sort?: string;
|
|
@@ -15,16 +20,16 @@ const PLANS_CACHE_TTL = 604800;
|
|
|
15
20
|
|
|
16
21
|
class PlansService {
|
|
17
22
|
private cache = new greatCache({
|
|
18
|
-
service:
|
|
19
|
-
version:
|
|
20
|
-
domain:
|
|
21
|
-
ambient: process.env.NODE_ENV ||
|
|
23
|
+
service: "plans",
|
|
24
|
+
version: "1.0.2",
|
|
25
|
+
domain: "whitelabel-cache.greatapps.com.br",
|
|
26
|
+
ambient: process.env.NODE_ENV || "development",
|
|
22
27
|
});
|
|
23
28
|
|
|
24
|
-
private buildCacheKey(key: string, params?:
|
|
25
|
-
const sort = params?.sort ??
|
|
26
|
-
const active = params?.active ??
|
|
27
|
-
const search = params?.search ??
|
|
29
|
+
private buildCacheKey(key: string, params?: Record<string, unknown>): string {
|
|
30
|
+
const sort = params?.sort ?? "id:ASC";
|
|
31
|
+
const active = params?.active ?? "";
|
|
32
|
+
const search = params?.search ?? "";
|
|
28
33
|
return `${key}-${sort}-${active}-${search}-v2`;
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -33,30 +38,37 @@ class PlansService {
|
|
|
33
38
|
* Exemplo:
|
|
34
39
|
* GET /{id_wl}/plans?active=true&search=client&sort=id:ASC
|
|
35
40
|
*/
|
|
36
|
-
async listPlans(
|
|
37
|
-
|
|
41
|
+
async listPlans(
|
|
42
|
+
params?: ListPlansParams,
|
|
43
|
+
): Promise<PaginatedSuccessResult<Plan>> {
|
|
44
|
+
const { id_account } = await getUserContext();
|
|
45
|
+
const cacheKey = this.buildCacheKey("plans", {
|
|
46
|
+
...params,
|
|
47
|
+
id_account,
|
|
48
|
+
});
|
|
38
49
|
|
|
39
50
|
const cachedData = await this.cache.select(cacheKey);
|
|
40
51
|
|
|
41
|
-
if (cachedData.status == 1 &&
|
|
52
|
+
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
42
53
|
const data = JSON.parse(cachedData.data) as Plan[];
|
|
43
54
|
return { data, total: data.length, success: true };
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
const query = buildQueryParams({
|
|
47
|
-
sort: params?.sort ??
|
|
58
|
+
sort: params?.sort ?? "id:ASC",
|
|
48
59
|
active: params?.active,
|
|
49
60
|
search: params?.search,
|
|
61
|
+
id_account: id_account,
|
|
50
62
|
});
|
|
51
|
-
const url = `/plans${query ? `?${query}` :
|
|
63
|
+
const url = `/plans${query ? `?${query}` : ""}`;
|
|
52
64
|
|
|
53
|
-
const response = await
|
|
65
|
+
const response = await api.apps.get<ApiPaginatedActionResult<Plan[]>>(url);
|
|
54
66
|
|
|
55
67
|
if (response.status === 0) {
|
|
56
68
|
throw new ApiError(
|
|
57
|
-
(response as { message?: string }).message ||
|
|
58
|
-
|
|
59
|
-
400
|
|
69
|
+
(response as { message?: string }).message || "Erro ao listar planos",
|
|
70
|
+
"LIST_PLANS_FAILED",
|
|
71
|
+
400,
|
|
60
72
|
);
|
|
61
73
|
}
|
|
62
74
|
|
|
@@ -74,35 +86,35 @@ class PlansService {
|
|
|
74
86
|
} satisfies PaginatedSuccessResult<Plan>;
|
|
75
87
|
}
|
|
76
88
|
|
|
77
|
-
|
|
78
89
|
async findById(idPlan: number | string): Promise<SuccessResult<Plan>> {
|
|
79
|
-
const
|
|
90
|
+
const { id_account } = await getUserContext();
|
|
91
|
+
const cacheKey = this.buildCacheKey(`plan-${idPlan}`, {
|
|
92
|
+
id_account: String(id_account),
|
|
93
|
+
});
|
|
80
94
|
|
|
81
95
|
const cachedData = await this.cache.select(cacheKey);
|
|
82
|
-
|
|
83
|
-
if (cachedData.status == 1 &&
|
|
96
|
+
|
|
97
|
+
if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
|
|
84
98
|
const data = JSON.parse(cachedData.data) as Plan;
|
|
85
99
|
return { data, success: true };
|
|
86
100
|
}
|
|
87
101
|
|
|
102
|
+
const query = buildQueryParams({ type: "client", id_account });
|
|
103
|
+
|
|
88
104
|
const response = await api.apps.get<ApiPaginatedActionResult<Plan>>(
|
|
89
|
-
`/plans/${idPlan}
|
|
105
|
+
`/plans/${idPlan}?${query}`,
|
|
90
106
|
);
|
|
91
107
|
|
|
92
108
|
if (response.status === 0) {
|
|
93
109
|
throw new ApiError(
|
|
94
|
-
response.message ||
|
|
95
|
-
|
|
96
|
-
400
|
|
110
|
+
response.message || "Erro ao buscar plano",
|
|
111
|
+
"FIND_PLAN_FAILED",
|
|
112
|
+
400,
|
|
97
113
|
);
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
if (!response.data?.length) {
|
|
101
|
-
throw new ApiError(
|
|
102
|
-
'Plano não encontrado',
|
|
103
|
-
'PLAN_NOT_FOUND',
|
|
104
|
-
404
|
|
105
|
-
);
|
|
117
|
+
throw new ApiError("Plano não encontrado", "PLAN_NOT_FOUND", 404);
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
const plan = PlanSchema.parse(response.data[0]);
|
|
@@ -53,6 +53,36 @@ export const SubscriptionSchema = z.object({
|
|
|
53
53
|
card_brand: z.string().nullable().optional(),
|
|
54
54
|
card_number: z.string().nullable().optional(),
|
|
55
55
|
items: z.array(SubscriptionItemSchema),
|
|
56
|
+
pending_change: z.object({
|
|
57
|
+
schedule_id: z.string(),
|
|
58
|
+
schedule_status: z.string(),
|
|
59
|
+
kind: z.string(),
|
|
60
|
+
takes_effect_at: z.number(),
|
|
61
|
+
takes_effect_at_iso: z.string(),
|
|
62
|
+
new_plan: z.object({
|
|
63
|
+
id: z.number(),
|
|
64
|
+
name: z.string(),
|
|
65
|
+
periodicity: z.number(),
|
|
66
|
+
value: z.number(),
|
|
67
|
+
value_gross: z.number(),
|
|
68
|
+
}),
|
|
69
|
+
new_items: z.array(z.object({
|
|
70
|
+
price_id: z.string(),
|
|
71
|
+
id_addon: z.number().nullable(),
|
|
72
|
+
addon_name: z.string(),
|
|
73
|
+
quantity: z.number(),
|
|
74
|
+
unit_value: z.number(),
|
|
75
|
+
value: z.number(),
|
|
76
|
+
is_plan_base: z.boolean(),
|
|
77
|
+
is_ai_credit: z.boolean(),
|
|
78
|
+
})),
|
|
79
|
+
new_discounts: z.array(z.unknown()),
|
|
80
|
+
changes: z.array(z.object({
|
|
81
|
+
type: z.string(),
|
|
82
|
+
from: z.unknown(),
|
|
83
|
+
to: z.unknown(),
|
|
84
|
+
})),
|
|
85
|
+
}).nullable().optional(),
|
|
56
86
|
});
|
|
57
87
|
|
|
58
88
|
export type Subscription = z.infer<typeof SubscriptionSchema>;
|