@greatapps/common 1.1.784 → 1.1.785

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 (106) hide show
  1. package/dist/components/layouts/AppMobileNavBar.mjs +5 -64
  2. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  3. package/dist/components/layouts/AppNavBar.mjs +0 -2
  4. package/dist/components/layouts/AppNavBar.mjs.map +1 -1
  5. package/dist/components/layouts/NavBar.mjs +52 -111
  6. package/dist/components/layouts/NavBar.mjs.map +1 -1
  7. package/dist/components/modals/cards/AddCardModal.mjs +3 -2
  8. package/dist/components/modals/cards/AddCardModal.mjs.map +1 -1
  9. package/dist/components/ui/form/PhoneInput.mjs +1 -1
  10. package/dist/components/ui/form/PhoneInput.mjs.map +1 -1
  11. package/dist/handlers.mjs +0 -2
  12. package/dist/handlers.mjs.map +1 -1
  13. package/dist/i18n/messages/en-us.mjs +1 -3
  14. package/dist/i18n/messages/en-us.mjs.map +1 -1
  15. package/dist/i18n/messages/es-es.mjs +1 -3
  16. package/dist/i18n/messages/es-es.mjs.map +1 -1
  17. package/dist/i18n/messages/pt-br.mjs +1 -3
  18. package/dist/i18n/messages/pt-br.mjs.map +1 -1
  19. package/dist/index.mjs +1 -9
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/infra/api/client.mjs +1 -5
  22. package/dist/infra/api/client.mjs.map +1 -1
  23. package/dist/infra/api/types.mjs +1 -1
  24. package/dist/infra/api/types.mjs.map +1 -1
  25. package/dist/infra/route/safe-route-handler.mjs +1 -4
  26. package/dist/infra/route/safe-route-handler.mjs.map +1 -1
  27. package/dist/modules/auth/utils/assert-account-not-frozen.mjs +5 -6
  28. package/dist/modules/auth/utils/assert-account-not-frozen.mjs.map +1 -1
  29. package/dist/modules/auth/utils/assert-management-subscription.mjs +14 -7
  30. package/dist/modules/auth/utils/assert-management-subscription.mjs.map +1 -1
  31. package/dist/modules/auth/utils/assert-paid-subscription.mjs +12 -7
  32. package/dist/modules/auth/utils/assert-paid-subscription.mjs.map +1 -1
  33. package/dist/modules/auth/utils/assert-subscription-addon.mjs +10 -2
  34. package/dist/modules/auth/utils/assert-subscription-addon.mjs.map +1 -1
  35. package/dist/modules/plans/hooks/use-plan-by-id.hook.mjs.map +1 -1
  36. package/dist/modules/subscriptions/actions/update-subscription-payment.action.mjs.map +1 -1
  37. package/dist/modules/subscriptions/constants/subscription.constants.mjs +0 -2
  38. package/dist/modules/subscriptions/constants/subscription.constants.mjs.map +1 -1
  39. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs +13 -2
  40. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  41. package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs +10 -2
  42. package/dist/modules/subscriptions/hooks/update-subscription-payment.hook.mjs.map +1 -1
  43. package/dist/modules/subscriptions/services/subscriptions.service.mjs +12 -27
  44. package/dist/modules/subscriptions/services/subscriptions.service.mjs.map +1 -1
  45. package/dist/modules/subscriptions/types/subscription.type.mjs.map +1 -1
  46. package/dist/modules/subscriptions/utils/has-active-paid-subscription.mjs +1 -1
  47. package/dist/modules/subscriptions/utils/has-active-paid-subscription.mjs.map +1 -1
  48. package/dist/modules/subscriptions/utils/has-paid-subscription.mjs +1 -1
  49. package/dist/modules/subscriptions/utils/has-paid-subscription.mjs.map +1 -1
  50. package/dist/server.mjs +0 -4
  51. package/dist/server.mjs.map +1 -1
  52. package/dist/store/useMdSidebarStore.mjs +4 -17
  53. package/dist/store/useMdSidebarStore.mjs.map +1 -1
  54. package/dist/utils/safeServerAction.mjs +1 -4
  55. package/dist/utils/safeServerAction.mjs.map +1 -1
  56. package/dist/utils/withAction.mjs +1 -2
  57. package/dist/utils/withAction.mjs.map +1 -1
  58. package/package.json +1 -1
  59. package/src/components/layouts/AppMobileNavBar.tsx +6 -90
  60. package/src/components/layouts/AppNavBar.tsx +1 -5
  61. package/src/components/layouts/NavBar.tsx +66 -160
  62. package/src/components/modals/cards/AddCardModal.tsx +15 -2
  63. package/src/components/ui/form/PhoneInput.tsx +1 -1
  64. package/src/handlers.ts +0 -1
  65. package/src/i18n/messages/en-us.ts +0 -2
  66. package/src/i18n/messages/es-es.ts +0 -2
  67. package/src/i18n/messages/pt-br.ts +0 -2
  68. package/src/index.ts +2 -7
  69. package/src/infra/api/client.ts +3 -11
  70. package/src/infra/api/types.ts +5 -7
  71. package/src/infra/route/safe-route-handler.ts +1 -4
  72. package/src/modules/auth/utils/assert-account-not-frozen.ts +6 -7
  73. package/src/modules/auth/utils/assert-management-subscription.ts +23 -15
  74. package/src/modules/auth/utils/assert-paid-subscription.ts +15 -7
  75. package/src/modules/auth/utils/assert-subscription-addon.ts +12 -2
  76. package/src/modules/plans/hooks/use-plan-by-id.hook.ts +1 -1
  77. package/src/modules/subscriptions/actions/update-subscription-payment.action.ts +6 -1
  78. package/src/modules/subscriptions/constants/subscription.constants.ts +0 -3
  79. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +17 -7
  80. package/src/modules/subscriptions/hooks/update-subscription-payment.hook.ts +21 -3
  81. package/src/modules/subscriptions/services/subscriptions.service.ts +46 -38
  82. package/src/modules/subscriptions/types/subscription.type.ts +27 -2
  83. package/src/modules/subscriptions/utils/has-active-paid-subscription.ts +2 -1
  84. package/src/modules/subscriptions/utils/has-paid-subscription.ts +2 -1
  85. package/src/server.ts +0 -2
  86. package/src/store/useMdSidebarStore.ts +5 -20
  87. package/src/utils/safeServerAction.ts +6 -4
  88. package/src/utils/withAction.ts +1 -2
  89. package/dist/components/layouts/GreatDomainIcon.mjs +0 -40
  90. package/dist/components/layouts/GreatDomainIcon.mjs.map +0 -1
  91. package/dist/modules/subscriptions/actions/get-current-subscription.action.mjs +0 -10
  92. package/dist/modules/subscriptions/actions/get-current-subscription.action.mjs.map +0 -1
  93. package/dist/modules/subscriptions/handlers/current-subscription.handler.mjs +0 -17
  94. package/dist/modules/subscriptions/handlers/current-subscription.handler.mjs.map +0 -1
  95. package/dist/modules/subscriptions/hooks/use-current-subscription.hook.mjs +0 -28
  96. package/dist/modules/subscriptions/hooks/use-current-subscription.hook.mjs.map +0 -1
  97. package/dist/modules/subscriptions/utils/group-subscriptions-by-product.mjs +0 -16
  98. package/dist/modules/subscriptions/utils/group-subscriptions-by-product.mjs.map +0 -1
  99. package/dist/modules/subscriptions/utils/read-current-subscription.mjs +0 -21
  100. package/dist/modules/subscriptions/utils/read-current-subscription.mjs.map +0 -1
  101. package/src/components/layouts/GreatDomainIcon.tsx +0 -43
  102. package/src/modules/subscriptions/actions/get-current-subscription.action.ts +0 -8
  103. package/src/modules/subscriptions/handlers/current-subscription.handler.ts +0 -16
  104. package/src/modules/subscriptions/hooks/use-current-subscription.hook.ts +0 -38
  105. package/src/modules/subscriptions/utils/group-subscriptions-by-product.ts +0 -23
  106. package/src/modules/subscriptions/utils/read-current-subscription.ts +0 -34
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/hooks/find-active-subscription.hook.ts"],"sourcesContent":["\"use client\";\n\nimport { useCurrentSubscription } from \"./use-current-subscription.hook\";\n\n/**\n * @deprecated Use `useCurrentSubscription`, mesma leitura (mesma chave de\n * cache, uma única requisição); só o nome muda para o vocabulário certo\n * (\"corrente\", não \"ativa\"). Sai na 1.1.784.\n */\nexport function useActiveSubscription() {\n return useCurrentSubscription();\n}\n"],"mappings":";AAEA,SAAS,8BAA8B;AAOhC,SAAS,wBAAwB;AACtC,SAAO,uBAAuB;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/hooks/find-active-subscription.hook.ts"],"sourcesContent":["\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { apiFetch } from \"../../../infra/http/api-fetch\";\nimport type { PaginatedSuccessResult } from \"../../../infra/api/types\";\nimport type { Subscription } from \"../types/subscription.type\";\nimport { SUBSCRIPTIONS_QUERY_KEY } from \"../constants/query-keys.constants\";\nimport { useAuthQueryKey } from \"../../../hooks/useAuthQueryKey\";\n\nexport function useActiveSubscription() {\n const queryKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY, \"active\"]);\n\n return useQuery({\n queryKey,\n queryFn: ({ signal }) =>\n apiFetch<PaginatedSuccessResult<Subscription>>('/api/subscriptions', {\n params: { limit: 1 },\n signal,\n }),\n staleTime: 10_000,\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAGzB,SAAS,+BAA+B;AACxC,SAAS,uBAAuB;AAEzB,SAAS,wBAAwB;AACtC,QAAM,WAAW,gBAAgB,CAAC,GAAG,yBAAyB,QAAQ,CAAC;AAEvE,SAAO,SAAS;AAAA,IACd;AAAA,IACA,SAAS,CAAC,EAAE,OAAO,MACjB,SAA+C,sBAAsB;AAAA,MACnE,QAAQ,EAAE,OAAO,EAAE;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,IACH,WAAW;AAAA,EACb,CAAC;AACH;","names":[]}
@@ -2,18 +2,26 @@
2
2
  import { useMutation, useQueryClient } from "@tanstack/react-query";
3
3
  import { withAction } from "../../../utils/withAction";
4
4
  import { updateSubscriptionPaymentAction } from "../actions/update-subscription-payment.action";
5
- import { SUBSCRIPTIONS_QUERY_KEY } from "../constants/query-keys.constants";
5
+ import { SUBSCRIPTIONS_QUERY_KEY, CHARGES_QUERY_KEY } from "../constants/query-keys.constants";
6
6
  import { useAuthQueryKey } from "../../../hooks/useAuthQueryKey";
7
+ import { CARDS_QUERY_KEY } from "../../cards/hooks/cards.hook";
7
8
  function useUpdateSubscriptionPayment() {
8
9
  const queryClient = useQueryClient();
9
10
  const subscriptionsKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY]);
11
+ const cardsKey = useAuthQueryKey([...CARDS_QUERY_KEY]);
12
+ const chargesKey = useAuthQueryKey([...CHARGES_QUERY_KEY]);
10
13
  return useMutation({
11
14
  mutationFn: ({
12
15
  subscriptionId,
13
16
  data
14
17
  }) => withAction(updateSubscriptionPaymentAction)(subscriptionId, data),
15
- onSuccess: () => {
18
+ /* `onSettled`, e não `onSuccess`, pelo mesmo motivo do irmão `updateSubscriptionPlan`: a troca
19
+ * é aplicada no backend ANTES do 3DS, então a falha de autenticação também precisa refletir na
20
+ * tela. */
21
+ onSettled: () => {
16
22
  queryClient.invalidateQueries({ queryKey: subscriptionsKey });
23
+ queryClient.invalidateQueries({ queryKey: cardsKey });
24
+ queryClient.invalidateQueries({ queryKey: chargesKey });
17
25
  }
18
26
  });
19
27
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/hooks/update-subscription-payment.hook.ts"],"sourcesContent":["'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { withAction } from '../../../utils/withAction';\nimport { updateSubscriptionPaymentAction } from '../actions/update-subscription-payment.action';\nimport { SUBSCRIPTIONS_QUERY_KEY } from '../constants/query-keys.constants';\nimport { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';\n\nexport function useUpdateSubscriptionPayment() {\n const queryClient = useQueryClient();\n const subscriptionsKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY]);\n\n return useMutation({\n mutationFn: ({\n subscriptionId,\n data,\n }: {\n subscriptionId: number | string;\n data: { id_card?: string; payment_method_id?: string; payment_method: number };\n }) => withAction(updateSubscriptionPaymentAction)(subscriptionId, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKey });\n },\n });\n}\n"],"mappings":";AAEA,SAAS,aAAa,sBAAsB;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,uCAAuC;AAChD,SAAS,+BAA+B;AACxC,SAAS,uBAAuB;AAEzB,SAAS,+BAA+B;AAC7C,QAAM,cAAc,eAAe;AACnC,QAAM,mBAAmB,gBAAgB,CAAC,GAAG,uBAAuB,CAAC;AAErE,SAAO,YAAY;AAAA,IACjB,YAAY,CAAC;AAAA,MACX;AAAA,MACA;AAAA,IACF,MAGM,WAAW,+BAA+B,EAAE,gBAAgB,IAAI;AAAA,IACtE,WAAW,MAAM;AACf,kBAAY,kBAAkB,EAAE,UAAU,iBAAiB,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/hooks/update-subscription-payment.hook.ts"],"sourcesContent":["'use client';\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { withAction } from '../../../utils/withAction';\nimport { updateSubscriptionPaymentAction } from '../actions/update-subscription-payment.action';\nimport { SUBSCRIPTIONS_QUERY_KEY, CHARGES_QUERY_KEY } from '../constants/query-keys.constants';\nimport { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';\nimport { CARDS_QUERY_KEY } from '../../cards/hooks/cards.hook';\n\nexport function useUpdateSubscriptionPayment() {\n const queryClient = useQueryClient();\n const subscriptionsKey = useAuthQueryKey([...SUBSCRIPTIONS_QUERY_KEY]);\n const cardsKey = useAuthQueryKey([...CARDS_QUERY_KEY]);\n const chargesKey = useAuthQueryKey([...CHARGES_QUERY_KEY]);\n\n return useMutation({\n mutationFn: ({\n subscriptionId,\n data,\n }: {\n subscriptionId: number | string;\n data: {\n id_card?: string;\n payment_method_id?: string;\n payment_method: number;\n charge_now?: boolean;\n };\n }) => withAction(updateSubscriptionPaymentAction)(subscriptionId, data),\n /* `onSettled`, e não `onSuccess`, pelo mesmo motivo do irmão `updateSubscriptionPlan`: a troca\n * é aplicada no backend ANTES do 3DS, então a falha de autenticação também precisa refletir na\n * tela. */\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey: subscriptionsKey });\n /* A troca reaponta o cartão padrão da conta na mesma operação, então sem esta invalidação o\n * selo \"padrão\" continuaria no cartão antigo depois de uma troca que já aconteceu. */\n queryClient.invalidateQueries({ queryKey: cardsKey });\n /* A operação passou a mutar um TERCEIRO estado: com `charge_now`, ela paga a fatura. A mesma\n * tela lê isso por `useCharges`, e com `refetchOnWindowFocus: false` nada refaz a busca —\n * a fatura recém-paga seguiria com selo \"pendente\" e botão \"Pagar\". */\n queryClient.invalidateQueries({ queryKey: chargesKey });\n },\n });\n}\n"],"mappings":";AAEA,SAAS,aAAa,sBAAsB;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,uCAAuC;AAChD,SAAS,yBAAyB,yBAAyB;AAC3D,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAEzB,SAAS,+BAA+B;AAC7C,QAAM,cAAc,eAAe;AACnC,QAAM,mBAAmB,gBAAgB,CAAC,GAAG,uBAAuB,CAAC;AACrE,QAAM,WAAW,gBAAgB,CAAC,GAAG,eAAe,CAAC;AACrD,QAAM,aAAa,gBAAgB,CAAC,GAAG,iBAAiB,CAAC;AAEzD,SAAO,YAAY;AAAA,IACjB,YAAY,CAAC;AAAA,MACX;AAAA,MACA;AAAA,IACF,MAQM,WAAW,+BAA+B,EAAE,gBAAgB,IAAI;AAAA;AAAA;AAAA;AAAA,IAItE,WAAW,MAAM;AACf,kBAAY,kBAAkB,EAAE,UAAU,iBAAiB,CAAC;AAG5D,kBAAY,kBAAkB,EAAE,UAAU,SAAS,CAAC;AAIpD,kBAAY,kBAAkB,EAAE,UAAU,WAAW,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -38,32 +38,6 @@ class SubscriptionsService {
38
38
  success: true
39
39
  };
40
40
  }
41
- /**
42
- * A assinatura corrente do plano da conta, pela regra única do backend
43
- * (`GET .../subscriptions/action/current`): contrato de domínio nunca é
44
- * corrente, encerrada é decidida por `active`. Sem `id_product`, paridade
45
- * com hoje (melhor rank entre todos os produtos, nunca item/domínio).
46
- */
47
- async getCurrentSubscription(params) {
48
- const { id_account } = await getUserContext();
49
- const query = buildQueryParams(
50
- params
51
- );
52
- const url = `/accounts/${id_account}/subscriptions/action/current${query ? `?${query}` : ""}`;
53
- const response = await api.apps.get(url);
54
- if (response.status === 0) {
55
- throw new ApiError(
56
- response.message || "Erro ao consultar assinatura corrente",
57
- "GET_CURRENT_SUBSCRIPTION_FAILED",
58
- 400
59
- );
60
- }
61
- const raw = response.data[0];
62
- return {
63
- success: true,
64
- data: raw ? SubscriptionSchema.parse(raw) : null
65
- };
66
- }
67
41
  async calculateSubscription(data) {
68
42
  const { id_account } = await getUserContext();
69
43
  const response = await api.apps.post(`/accounts/${id_account}/subscriptions/action/calculate`, data);
@@ -125,7 +99,18 @@ class SubscriptionsService {
125
99
  400
126
100
  );
127
101
  }
128
- return { success: true };
102
+ if (response.status === 2) {
103
+ return {
104
+ success: true,
105
+ applied: false,
106
+ ...response.client_secret ? { client_secret: response.client_secret } : {}
107
+ };
108
+ }
109
+ return {
110
+ success: true,
111
+ applied: true,
112
+ ...response.charge_now ? { charge_now: response.charge_now } : {}
113
+ };
129
114
  }
130
115
  async getFreezeNotice() {
131
116
  const { id_account } = await getUserContext();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/services/subscriptions.service.ts"],"sourcesContent":["import \"server-only\";\r\n\r\nimport { api } from \"../../../infra/api/client\";\r\nimport {\r\n ApiError,\r\n ApiActionResult,\r\n ApiPaginatedActionResult,\r\n PaginatedSuccessResult,\r\n SuccessResult,\r\n} from \"../../../infra/api/types\";\r\nimport { buildQueryParams } from \"../../../infra/utils/params\";\r\nimport { assertManagementPermission } from \"../../auth/utils/assert-management-permission\";\r\nimport { getUserContext } from \"../../auth/utils/get-user-context\";\r\nimport {\r\n Subscription,\r\n SubscriptionSchema,\r\n FindSubscriptionsParams,\r\n} from \"../types/subscription.type\";\r\nimport {\r\n type CalculateSubscriptionRequest,\r\n type CalculateSubscriptionResponse,\r\n type UpdateSubscriptionPlanRequest,\r\n CalculateSubscriptionResponseSchema,\r\n} from \"../types/calculate-subscription.type\";\r\nimport {\r\n SubscriptionPendingPixResponseSchema,\r\n type SubscriptionPendingPixResponse,\r\n} from \"../types/pix-pending.type\";\r\nimport type { FreezeNotice } from \"../types/freeze-notice.type\";\r\n\r\n/**\r\n * Timeout das mutations de assinatura que ESCREVEM (action/plan e action/payment).\r\n *\r\n * O default do ApiClient é 30s. Essas duas rotas caem no mesmo motor pesado do\r\n * backend (planEdit delega pra paymentEdit) — troca de método de pagamento, mandato\r\n * PIX recorrente Woovi, void-and-replace de fatura — e passam de 30s com alguma\r\n * frequência: em produção elas aparecem como `outcome=canceled` com wallTime ~29.9s.\r\n *\r\n * O problema não é o usuário ver \"Tempo excedido\": é que o abort MATA o worker no\r\n * meio da saga. Se o corte cai depois de criar o mandato Woovi e suprimir a fatura\r\n * de ciclo, sobra mandato órfão + fatura sem dunning, o usuário não recebe QR nenhum\r\n * e a próxima tentativa cria um segundo mandato. Deixar a request terminar converte\r\n * uma escrita parcial numa escrita completa.\r\n *\r\n * Não é a solução definitiva — a rota deveria ser assíncrona (202 + polling no\r\n * correlation_id). É o teto que dá folga enquanto isso.\r\n *\r\n * Só nas mutations: calculateSubscription é idempotente (não escreve nada), então\r\n * um timeout nela não deixa rastro e não precisa esperar mais.\r\n */\r\nconst SUBSCRIPTION_WRITE_TIMEOUT_MS = 60000;\r\n\r\nexport type UpdateSubscriptionPlanResponse =\r\n | Subscription\r\n | SubscriptionPendingPixResponse;\r\n\r\nclass SubscriptionsService {\r\n async listSubscriptions(\r\n params?: Partial<FindSubscriptionsParams>,\r\n ): Promise<PaginatedSuccessResult<Subscription>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const query = buildQueryParams(\r\n params as Record<string, string | boolean | undefined>,\r\n );\r\n const url = `/accounts/${id_account}/subscriptions${query ? `?${query}` : \"\"}`;\r\n\r\n const response =\r\n await api.apps.get<ApiPaginatedActionResult<Subscription>>(url);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao listar assinaturas\",\r\n \"LIST_SUBSCRIPTIONS_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n const data = response.data.map((item) => SubscriptionSchema.parse(item));\r\n\r\n return {\r\n data,\r\n total: response.total,\r\n success: true,\r\n } satisfies PaginatedSuccessResult<Subscription>;\r\n }\r\n\r\n /**\r\n * A assinatura corrente do plano da conta, pela regra única do backend\r\n * (`GET .../subscriptions/action/current`): contrato de domínio nunca é\r\n * corrente, encerrada é decidida por `active`. Sem `id_product`, paridade\r\n * com hoje (melhor rank entre todos os produtos, nunca item/domínio).\r\n */\r\n async getCurrentSubscription(\r\n params?: { id_product?: number },\r\n ): Promise<SuccessResult<Subscription | null>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const query = buildQueryParams(\r\n params as Record<string, string | number | undefined>,\r\n );\r\n const url = `/accounts/${id_account}/subscriptions/action/current${query ? `?${query}` : \"\"}`;\r\n\r\n const response = await api.apps.get<ApiPaginatedActionResult<Subscription>>(url);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao consultar assinatura corrente\",\r\n \"GET_CURRENT_SUBSCRIPTION_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n const raw = response.data[0];\r\n\r\n return {\r\n success: true,\r\n data: raw ? SubscriptionSchema.parse(raw) : null,\r\n };\r\n }\r\n\r\n async calculateSubscription(\r\n data: CalculateSubscriptionRequest,\r\n ): Promise<SuccessResult<CalculateSubscriptionResponse>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.post<\r\n ApiActionResult<CalculateSubscriptionResponse>\r\n >(`/accounts/${id_account}/subscriptions/action/calculate`, data);\r\n\r\n console.log(\"Calculate subscription response:\", {\r\n response,\r\n data: JSON.stringify(data, null, 2),\r\n });\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao calcular assinatura\",\r\n \"CALCULATE_SUBSCRIPTION_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n data: CalculateSubscriptionResponseSchema.parse(response.data),\r\n };\r\n }\r\n\r\n async updateSubscriptionPlan(\r\n subscriptionId: number | string,\r\n data: UpdateSubscriptionPlanRequest,\r\n ): Promise<\r\n SuccessResult<UpdateSubscriptionPlanResponse | null> & { client_secret?: string }\r\n > {\r\n await assertManagementPermission('manage_subscriptions');\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.put<\r\n ApiActionResult<UpdateSubscriptionPlanResponse | UpdateSubscriptionPlanResponse[]> & {\r\n client_secret?: string;\r\n }\r\n >(\r\n `/accounts/${id_account}/subscriptions/${subscriptionId}/action/plan`,\r\n data,\r\n { timeout: SUBSCRIPTION_WRITE_TIMEOUT_MS },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao atualizar plano\",\r\n \"UPDATE_SUBSCRIPTION_PLAN_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n const raw = Array.isArray(response.data) ? response.data[0] : response.data;\r\n\r\n // Preserva resposta pix-pending (id: null, pending: true, pix: {...})\r\n // pra clientes poderem rotear o user pra fluxo dedicado de pix em vez\r\n // de tratar como subscription comum. Caso contrário, parseia como\r\n // Subscription (compatível com o comportamento antigo de devolver { id }).\r\n let parsed: UpdateSubscriptionPlanResponse | null = null;\r\n if (raw) {\r\n const pixResult = SubscriptionPendingPixResponseSchema.safeParse(raw);\r\n parsed = pixResult.success ? pixResult.data : SubscriptionSchema.parse(raw);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: parsed,\r\n ...(response.client_secret ? { client_secret: response.client_secret } : {}),\r\n };\r\n }\r\n\r\n async updateSubscriptionPayment(\r\n subscriptionId: number | string,\r\n data: { id_card?: string; payment_method_id?: string; payment_method: number },\r\n ): Promise<SuccessResult<void>> {\r\n await assertManagementPermission(\"manage_subscriptions\");\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.put<ApiActionResult<void>>(\r\n `/accounts/${id_account}/subscriptions/${subscriptionId}/action/payment`,\r\n data,\r\n { timeout: SUBSCRIPTION_WRITE_TIMEOUT_MS },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao atualizar método de pagamento\",\r\n \"UPDATE_SUBSCRIPTION_PAYMENT_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return { success: true };\r\n }\r\n\r\n async getFreezeNotice(): Promise<FreezeNotice> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.get<ApiActionResult<FreezeNotice>>(\r\n `/accounts/${id_account}/notices/freeze`,\r\n );\r\n\r\n if (response.status === 0 || !response.data) {\r\n throw new ApiError(\r\n (response.status === 0 ? response.message : \"\") ||\r\n \"Erro ao consultar aviso de congelamento\",\r\n \"GET_FREEZE_NOTICE_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return response.data;\r\n }\r\n\r\n async ackFreezeNotice(cycle: string): Promise<SuccessResult<void>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.post<ApiActionResult<void>>(\r\n `/accounts/${id_account}/notices/freeze/ack`,\r\n { cycle },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao confirmar aviso de congelamento\",\r\n \"ACK_FREEZE_NOTICE_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return { success: true };\r\n }\r\n}\r\n\r\nexport const subscriptionsService = new SubscriptionsService();\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/services/subscriptions.service.ts"],"sourcesContent":["import \"server-only\";\r\n\r\nimport { api } from \"../../../infra/api/client\";\r\nimport {\r\n ApiError,\r\n ApiActionResult,\r\n ApiPaginatedActionResult,\r\n PaginatedSuccessResult,\r\n SuccessResult,\r\n} from \"../../../infra/api/types\";\r\nimport { buildQueryParams } from \"../../../infra/utils/params\";\r\nimport { assertManagementPermission } from \"../../auth/utils/assert-management-permission\";\r\nimport { getUserContext } from \"../../auth/utils/get-user-context\";\r\nimport {\r\n Subscription,\r\n SubscriptionSchema,\r\n FindSubscriptionsParams,\r\n type ChargeNowResult,\r\n} from \"../types/subscription.type\";\r\nimport {\r\n type CalculateSubscriptionRequest,\r\n type CalculateSubscriptionResponse,\r\n type UpdateSubscriptionPlanRequest,\r\n CalculateSubscriptionResponseSchema,\r\n} from \"../types/calculate-subscription.type\";\r\nimport {\r\n SubscriptionPendingPixResponseSchema,\r\n type SubscriptionPendingPixResponse,\r\n} from \"../types/pix-pending.type\";\r\nimport type { FreezeNotice } from \"../types/freeze-notice.type\";\r\n\r\n/**\r\n * Timeout das mutations de assinatura que ESCREVEM (action/plan e action/payment).\r\n *\r\n * O default do ApiClient é 30s. Essas duas rotas caem no mesmo motor pesado do\r\n * backend (planEdit delega pra paymentEdit) — troca de método de pagamento, mandato\r\n * PIX recorrente Woovi, void-and-replace de fatura — e passam de 30s com alguma\r\n * frequência: em produção elas aparecem como `outcome=canceled` com wallTime ~29.9s.\r\n *\r\n * O problema não é o usuário ver \"Tempo excedido\": é que o abort MATA o worker no\r\n * meio da saga. Se o corte cai depois de criar o mandato Woovi e suprimir a fatura\r\n * de ciclo, sobra mandato órfão + fatura sem dunning, o usuário não recebe QR nenhum\r\n * e a próxima tentativa cria um segundo mandato. Deixar a request terminar converte\r\n * uma escrita parcial numa escrita completa.\r\n *\r\n * Não é a solução definitiva — a rota deveria ser assíncrona (202 + polling no\r\n * correlation_id). É o teto que dá folga enquanto isso.\r\n *\r\n * Só nas mutations: calculateSubscription é idempotente (não escreve nada), então\r\n * um timeout nela não deixa rastro e não precisa esperar mais.\r\n */\r\nconst SUBSCRIPTION_WRITE_TIMEOUT_MS = 60000;\r\n\r\nexport type UpdateSubscriptionPlanResponse =\r\n | Subscription\r\n | SubscriptionPendingPixResponse;\r\n\r\nclass SubscriptionsService {\r\n async listSubscriptions(\r\n params?: Partial<FindSubscriptionsParams>,\r\n ): Promise<PaginatedSuccessResult<Subscription>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const query = buildQueryParams(\r\n params as Record<string, string | boolean | undefined>,\r\n );\r\n const url = `/accounts/${id_account}/subscriptions${query ? `?${query}` : \"\"}`;\r\n\r\n const response =\r\n await api.apps.get<ApiPaginatedActionResult<Subscription>>(url);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao listar assinaturas\",\r\n \"LIST_SUBSCRIPTIONS_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n const data = response.data.map((item) => SubscriptionSchema.parse(item));\r\n\r\n return {\r\n data,\r\n total: response.total,\r\n success: true,\r\n } satisfies PaginatedSuccessResult<Subscription>;\r\n }\r\n\r\n async calculateSubscription(\r\n data: CalculateSubscriptionRequest,\r\n ): Promise<SuccessResult<CalculateSubscriptionResponse>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.post<\r\n ApiActionResult<CalculateSubscriptionResponse>\r\n >(`/accounts/${id_account}/subscriptions/action/calculate`, data);\r\n\r\n console.log(\"Calculate subscription response:\", {\r\n response,\r\n data: JSON.stringify(data, null, 2),\r\n });\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao calcular assinatura\",\r\n \"CALCULATE_SUBSCRIPTION_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n data: CalculateSubscriptionResponseSchema.parse(response.data),\r\n };\r\n }\r\n\r\n async updateSubscriptionPlan(\r\n subscriptionId: number | string,\r\n data: UpdateSubscriptionPlanRequest,\r\n ): Promise<\r\n SuccessResult<UpdateSubscriptionPlanResponse | null> & { client_secret?: string }\r\n > {\r\n await assertManagementPermission('manage_subscriptions');\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.put<\r\n ApiActionResult<UpdateSubscriptionPlanResponse | UpdateSubscriptionPlanResponse[]> & {\r\n client_secret?: string;\r\n }\r\n >(\r\n `/accounts/${id_account}/subscriptions/${subscriptionId}/action/plan`,\r\n data,\r\n { timeout: SUBSCRIPTION_WRITE_TIMEOUT_MS },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao atualizar plano\",\r\n \"UPDATE_SUBSCRIPTION_PLAN_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n const raw = Array.isArray(response.data) ? response.data[0] : response.data;\r\n\r\n // Preserva resposta pix-pending (id: null, pending: true, pix: {...})\r\n // pra clientes poderem rotear o user pra fluxo dedicado de pix em vez\r\n // de tratar como subscription comum. Caso contrário, parseia como\r\n // Subscription (compatível com o comportamento antigo de devolver { id }).\r\n let parsed: UpdateSubscriptionPlanResponse | null = null;\r\n if (raw) {\r\n const pixResult = SubscriptionPendingPixResponseSchema.safeParse(raw);\r\n parsed = pixResult.success ? pixResult.data : SubscriptionSchema.parse(raw);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: parsed,\r\n ...(response.client_secret ? { client_secret: response.client_secret } : {}),\r\n };\r\n }\r\n\r\n async updateSubscriptionPayment(\r\n subscriptionId: number | string,\r\n data: {\r\n id_card?: string;\r\n payment_method_id?: string;\r\n payment_method: number;\r\n charge_now?: boolean;\r\n },\r\n ): Promise<\r\n SuccessResult<void> & {\r\n applied: boolean;\r\n client_secret?: string;\r\n charge_now?: ChargeNowResult;\r\n }\r\n > {\r\n await assertManagementPermission(\"manage_subscriptions\");\r\n const { id_account } = await getUserContext();\r\n\r\n /* O `status: 2` do guard de 3DS pendente não cabe em `ApiActionResult`, que só conhece 0 e 1.\r\n * Declarar o terceiro estado aqui é o que permite tratá-lo — sem isso o TypeScript apaga o\r\n * ramo como inalcançável e o caso volta a atravessar como sucesso. */\r\n const response = await api.apps.put<\r\n (ApiActionResult<void> | { status: 2; message?: string }) & {\r\n charge_now?: ChargeNowResult;\r\n client_secret?: string;\r\n }\r\n >(\r\n `/accounts/${id_account}/subscriptions/${subscriptionId}/action/payment`,\r\n data,\r\n { timeout: SUBSCRIPTION_WRITE_TIMEOUT_MS },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao atualizar método de pagamento\",\r\n \"UPDATE_SUBSCRIPTION_PAYMENT_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n /* `status: 2` NÃO é sucesso: o guard de 3DS pendente do paymentEdit devolve esse status sem\r\n * aplicar a troca, e como só o `status === 0` era tratado como erro, a chamada caía no\r\n * `success: true` e a tela dizia \"sua assinatura passou a ser cobrada neste cartão\" para uma\r\n * troca que não aconteceu — descartando junto o `client_secret` que resolveria a pendência.\r\n *\r\n * Por isso o retorno carrega `applied`: quem chama precisa poder distinguir \"trocou\" de\r\n * \"não trocou, conclua o pagamento pendente primeiro\". */\r\n if (response.status === 2) {\r\n return {\r\n success: true,\r\n applied: false,\r\n ...(response.client_secret ? { client_secret: response.client_secret } : {}),\r\n };\r\n }\r\n\r\n /* O desfecho da cobrança imediata precisa atravessar: descartá-lo (como este método fazia com\r\n * o corpo inteiro) apagaria tanto a recusa quanto o `client_secret` do 3DS, e a tela\r\n * anunciaria \"tudo certo\" para uma fatura que continua em aberto. */\r\n return {\r\n success: true,\r\n applied: true,\r\n ...(response.charge_now ? { charge_now: response.charge_now } : {}),\r\n };\r\n }\r\n\r\n async getFreezeNotice(): Promise<FreezeNotice> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.get<ApiActionResult<FreezeNotice>>(\r\n `/accounts/${id_account}/notices/freeze`,\r\n );\r\n\r\n if (response.status === 0 || !response.data) {\r\n throw new ApiError(\r\n (response.status === 0 ? response.message : \"\") ||\r\n \"Erro ao consultar aviso de congelamento\",\r\n \"GET_FREEZE_NOTICE_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return response.data;\r\n }\r\n\r\n async ackFreezeNotice(cycle: string): Promise<SuccessResult<void>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const response = await api.apps.post<ApiActionResult<void>>(\r\n `/accounts/${id_account}/notices/freeze/ack`,\r\n { cycle },\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao confirmar aviso de congelamento\",\r\n \"ACK_FREEZE_NOTICE_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return { success: true };\r\n }\r\n}\r\n\r\nexport const subscriptionsService = new SubscriptionsService();\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\nimport { calendarDateSchema } from '../../../infra/utils/date';\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().nullable(),\r\n currency: z.string(),\r\n quantity: z.number().nullable().transform((v) => v ?? 0),\r\n payment_status: z.number().nullable(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean().nullable(),\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().nullable(),\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: calendarDateSchema().nullable(),\r\n date_due: calendarDateSchema().nullable(),\r\n date_cancellation: calendarDateSchema().nullable(),\r\n date_verification: calendarDateSchema().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 card: z.object({\r\n id_card: z.union([z.number(), z.string()]).nullable().optional(),\r\n brand: z.string().nullable().optional(),\r\n expires_at: z.string().nullable().optional(),\r\n last4: z.string().nullable().optional(),\r\n name: z.string().nullable().optional(),\r\n }).nullable().optional(),\r\n /* payment_retry: tentativas de cobrança no cartão (Stripe Smart Retries / dunning),\r\n * lidas ao vivo do latest_invoice. null para boleto/pix (sem retries). Ver gapps-r3-api #229. */\r\n payment_retry: z.object({\r\n attempt_count: z.number(),\r\n next_attempt_at: z.string().nullable(),\r\n invoice_status: z.string().nullable(),\r\n }).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().nullable(),\r\n takes_effect_at_iso: z.string().nullable(),\r\n new_plan: z.object({\r\n id: z.number(),\r\n name: z.string(),\r\n periodicity: z.number().nullable(),\r\n value: z.number(),\r\n value_gross: z.number(),\r\n }).nullable(),\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().nullable(),\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_limits: z.record(z.string(), z.number()).nullable().optional(),\r\n new_discounts: z.array(z.unknown()),\r\n changes: z.array(z.object({\r\n type: z.string(),\r\n id_addon: z.number().nullable().optional(),\r\n addon_name: z.string().nullable().optional(),\r\n quantity: z.number().optional(),\r\n from: z.unknown().optional(),\r\n to: z.unknown().optional(),\r\n })),\r\n }).nullable().optional(),\r\n metadata: z.record(z.string(), z.unknown()).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 page?: number;\r\n id_product?: number;\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/types/subscription.type.ts"],"sourcesContent":["import z from 'zod';\r\nimport { calendarDateSchema } from '../../../infra/utils/date';\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().nullable(),\r\n currency: z.string(),\r\n quantity: z.number().nullable().transform((v) => v ?? 0),\r\n payment_status: z.number().nullable(),\r\n id_charge: z.union([z.number(), z.string()]).nullable(),\r\n trial: z.boolean().nullable(),\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().nullable(),\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: calendarDateSchema().nullable(),\r\n date_due: calendarDateSchema().nullable(),\r\n date_cancellation: calendarDateSchema().nullable(),\r\n date_verification: calendarDateSchema().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 card: z.object({\r\n id_card: z.union([z.number(), z.string()]).nullable().optional(),\r\n brand: z.string().nullable().optional(),\r\n expires_at: z.string().nullable().optional(),\r\n last4: z.string().nullable().optional(),\r\n name: z.string().nullable().optional(),\r\n }).nullable().optional(),\r\n /* payment_retry: tentativas de cobrança no cartão (Stripe Smart Retries / dunning),\r\n * lidas ao vivo do latest_invoice. null para boleto/pix (sem retries). Ver gapps-r3-api #229. */\r\n payment_retry: z.object({\r\n attempt_count: z.number(),\r\n next_attempt_at: z.string().nullable(),\r\n invoice_status: z.string().nullable(),\r\n }).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().nullable(),\r\n takes_effect_at_iso: z.string().nullable(),\r\n new_plan: z.object({\r\n id: z.number(),\r\n name: z.string(),\r\n periodicity: z.number().nullable(),\r\n value: z.number(),\r\n value_gross: z.number(),\r\n }).nullable(),\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().nullable(),\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_limits: z.record(z.string(), z.number()).nullable().optional(),\r\n new_discounts: z.array(z.unknown()),\r\n changes: z.array(z.object({\r\n type: z.string(),\r\n id_addon: z.number().nullable().optional(),\r\n addon_name: z.string().nullable().optional(),\r\n quantity: z.number().optional(),\r\n from: z.unknown().optional(),\r\n to: z.unknown().optional(),\r\n })),\r\n }).nullable().optional(),\r\n metadata: z.record(z.string(), z.unknown()).optional(),\r\n});\r\n\r\nexport type Subscription = z.infer<typeof SubscriptionSchema>;\r\n\r\n/* Desfecho da cobrança imediata pedida com `charge_now` na troca de forma de pagamento\r\n * (gapps-r3-api, PUT subscriptions/:id/action/payment).\r\n *\r\n * Vem separado do `status` da resposta de propósito: quando isto chega, a troca JÁ está firmada\r\n * no banco e na Stripe. Uma cobrança recusada aqui não desfaz a troca — o dunning da Stripe segue\r\n * armado no cartão novo —, então a tela precisa contar as duas coisas em separado.\r\n *\r\n * `outcome` é a ÚNICA fonte da verdade sobre o que aconteceu, e a tela deve falar só a partir dele.\r\n * Substituiu um par de booleanos (`attempted`/`paid`) que não distinguia recusa de 3DS pendente: a\r\n * tela lia `paid: false` depois de um desafio bem-sucedido e anunciava falha para um pagamento que\r\n * tinha acabado de completar.\r\n *\r\n * `amount` vem em centavos, na `currency` da fatura, e é o valor REALMENTE cobrado — não uma\r\n * previsão feita antes da chamada. */\r\nexport interface ChargeNowResult {\r\n outcome: 'charged' | 'requires_action' | 'declined' | 'none';\r\n invoice_id?: string;\r\n amount?: number | null;\r\n currency?: string | null;\r\n client_secret?: string;\r\n /* Presente em `declined`: a razão que o emissor deu. */\r\n message?: string;\r\n /* Presente em `none`: por que não houve o que cobrar (`sem_fatura_de_ciclo_aberta`,\r\n * `deteccao_falhou`, `sem_contexto_de_cobranca`). */\r\n reason?: string;\r\n}\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":[]}
@@ -1,6 +1,6 @@
1
1
  import { toCalendarDate, daysBetween } from "../../../infra/utils/date";
2
2
  import { getSubscriptionCancellationState } from "./get-subscription-cancellation-state";
3
- import { FREE_PLAN_ID } from "../constants/subscription.constants";
3
+ const FREE_PLAN_ID = 5;
4
4
  function isOverdue(subscription) {
5
5
  const retry = subscription.payment_retry;
6
6
  if (retry && retry.invoice_status === "open" && retry.attempt_count > 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/utils/has-active-paid-subscription.ts"],"sourcesContent":["import { toCalendarDate, daysBetween } from \"../../../infra/utils/date\";\nimport { getSubscriptionCancellationState } from \"./get-subscription-cancellation-state\";\nimport { FREE_PLAN_ID } from \"../constants/subscription.constants\";\nimport type { Subscription } from \"../types/subscription.type\";\n\ntype SubscriptionSnapshot = Pick<\n Subscription,\n | \"type\"\n | \"active\"\n | \"id_plan\"\n | \"date_due\"\n | \"date_cancellation\"\n | \"payment_retry\"\n>;\n\n/**\n * Fatura vencida e não paga. Mesmos sinais do SubscriptionBanner:\n * - cartão: dunning do Stripe (Smart Retries) — `invoice_status === 'open'`\n * com tentativa já feita.\n * - boleto/pix (sem retries): `date_due` no passado, ou seja a renovação não\n * foi paga.\n */\nfunction isOverdue(subscription: SubscriptionSnapshot): boolean {\n const retry = subscription.payment_retry;\n if (retry && retry.invoice_status === \"open\" && retry.attempt_count > 0) {\n return true;\n }\n\n const dueDate = toCalendarDate(subscription.date_due);\n const today = toCalendarDate(new Date());\n if (!dueDate || !today) return false;\n\n return daysBetween(dueDate, today) > 0;\n}\n\n/**\n * A conta já tem assinatura paga vigente — contratar outra viraria cobrança\n * duplicada (ver Asana ID-4743). O caminho correto pra ela é trocar de plano\n * ou reativar, não passar pelo checkout de novo.\n *\n * Retorna `false` (ou seja, PODE contratar) para quem legitimamente precisa do\n * checkout mesmo já tendo uma linha de assinatura:\n * - sem assinatura;\n * - `active === false` (baixada, inclusive por falha de pagamento);\n * - free (`type` ou plano legado 5) e trial — são justamente os que fazem upgrade;\n * - cancelada cujo período já terminou (`getSubscriptionCancellationState`);\n * - em atraso — precisa contratar pra regularizar.\n *\n * Cancelamento ainda dentro do período (`pending`) conta como vigente e\n * bloqueia: o serviço continua ativo e pago, e o caminho é reativar.\n */\nexport function hasActivePaidSubscription(\n subscription: SubscriptionSnapshot | undefined | null,\n): boolean {\n if (!subscription) return false;\n if (!subscription.active) return false;\n if (subscription.type === \"free\" || subscription.id_plan === FREE_PLAN_ID) {\n return false;\n }\n if (subscription.type === \"trial\") return false;\n if (getSubscriptionCancellationState(subscription) === \"cancelled\") {\n return false;\n }\n if (isOverdue(subscription)) return false;\n\n return true;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB,mBAAmB;AAC5C,SAAS,wCAAwC;AACjD,SAAS,oBAAoB;AAoB7B,SAAS,UAAU,cAA6C;AAC9D,QAAM,QAAQ,aAAa;AAC3B,MAAI,SAAS,MAAM,mBAAmB,UAAU,MAAM,gBAAgB,GAAG;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,aAAa,QAAQ;AACpD,QAAM,QAAQ,eAAe,oBAAI,KAAK,CAAC;AACvC,MAAI,CAAC,WAAW,CAAC,MAAO,QAAO;AAE/B,SAAO,YAAY,SAAS,KAAK,IAAI;AACvC;AAkBO,SAAS,0BACd,cACS;AACT,MAAI,CAAC,aAAc,QAAO;AAC1B,MAAI,CAAC,aAAa,OAAQ,QAAO;AACjC,MAAI,aAAa,SAAS,UAAU,aAAa,YAAY,cAAc;AACzE,WAAO;AAAA,EACT;AACA,MAAI,aAAa,SAAS,QAAS,QAAO;AAC1C,MAAI,iCAAiC,YAAY,MAAM,aAAa;AAClE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,YAAY,EAAG,QAAO;AAEpC,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/utils/has-active-paid-subscription.ts"],"sourcesContent":["import { toCalendarDate, daysBetween } from \"../../../infra/utils/date\";\nimport { getSubscriptionCancellationState } from \"./get-subscription-cancellation-state\";\nimport type { Subscription } from \"../types/subscription.type\";\n\nconst FREE_PLAN_ID = 5;\n\ntype SubscriptionSnapshot = Pick<\n Subscription,\n | \"type\"\n | \"active\"\n | \"id_plan\"\n | \"date_due\"\n | \"date_cancellation\"\n | \"payment_retry\"\n>;\n\n/**\n * Fatura vencida e não paga. Mesmos sinais do SubscriptionBanner:\n * - cartão: dunning do Stripe (Smart Retries) — `invoice_status === 'open'`\n * com tentativa já feita.\n * - boleto/pix (sem retries): `date_due` no passado, ou seja a renovação não\n * foi paga.\n */\nfunction isOverdue(subscription: SubscriptionSnapshot): boolean {\n const retry = subscription.payment_retry;\n if (retry && retry.invoice_status === \"open\" && retry.attempt_count > 0) {\n return true;\n }\n\n const dueDate = toCalendarDate(subscription.date_due);\n const today = toCalendarDate(new Date());\n if (!dueDate || !today) return false;\n\n return daysBetween(dueDate, today) > 0;\n}\n\n/**\n * A conta já tem assinatura paga vigente — contratar outra viraria cobrança\n * duplicada (ver Asana ID-4743). O caminho correto pra ela é trocar de plano\n * ou reativar, não passar pelo checkout de novo.\n *\n * Retorna `false` (ou seja, PODE contratar) para quem legitimamente precisa do\n * checkout mesmo já tendo uma linha de assinatura:\n * - sem assinatura;\n * - `active === false` (baixada, inclusive por falha de pagamento);\n * - free (`type` ou plano legado 5) e trial — são justamente os que fazem upgrade;\n * - cancelada cujo período já terminou (`getSubscriptionCancellationState`);\n * - em atraso — precisa contratar pra regularizar.\n *\n * Cancelamento ainda dentro do período (`pending`) conta como vigente e\n * bloqueia: o serviço continua ativo e pago, e o caminho é reativar.\n */\nexport function hasActivePaidSubscription(\n subscription: SubscriptionSnapshot | undefined | null,\n): boolean {\n if (!subscription) return false;\n if (!subscription.active) return false;\n if (subscription.type === \"free\" || subscription.id_plan === FREE_PLAN_ID) {\n return false;\n }\n if (subscription.type === \"trial\") return false;\n if (getSubscriptionCancellationState(subscription) === \"cancelled\") {\n return false;\n }\n if (isOverdue(subscription)) return false;\n\n return true;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB,mBAAmB;AAC5C,SAAS,wCAAwC;AAGjD,MAAM,eAAe;AAmBrB,SAAS,UAAU,cAA6C;AAC9D,QAAM,QAAQ,aAAa;AAC3B,MAAI,SAAS,MAAM,mBAAmB,UAAU,MAAM,gBAAgB,GAAG;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,aAAa,QAAQ;AACpD,QAAM,QAAQ,eAAe,oBAAI,KAAK,CAAC;AACvC,MAAI,CAAC,WAAW,CAAC,MAAO,QAAO;AAE/B,SAAO,YAAY,SAAS,KAAK,IAAI;AACvC;AAkBO,SAAS,0BACd,cACS;AACT,MAAI,CAAC,aAAc,QAAO;AAC1B,MAAI,CAAC,aAAa,OAAQ,QAAO;AACjC,MAAI,aAAa,SAAS,UAAU,aAAa,YAAY,cAAc;AACzE,WAAO;AAAA,EACT;AACA,MAAI,aAAa,SAAS,QAAS,QAAO;AAC1C,MAAI,iCAAiC,YAAY,MAAM,aAAa;AAClE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,YAAY,EAAG,QAAO;AAEpC,SAAO;AACT;","names":[]}
@@ -1,4 +1,4 @@
1
- import { FREE_PLAN_ID } from "../constants/subscription.constants";
1
+ const FREE_PLAN_ID = 5;
2
2
  function hasPaidSubscription(subscription) {
3
3
  if (!subscription) return false;
4
4
  if (subscription.type === "free" || subscription.id_plan === FREE_PLAN_ID) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/subscriptions/utils/has-paid-subscription.ts"],"sourcesContent":["import type { Subscription } from '../types/subscription.type';\nimport { FREE_PLAN_ID } from '../constants/subscription.constants';\n\ntype PaidSubscriptionSnapshot = Pick<Subscription, 'type' | 'id_plan' | 'charged'>;\n\n/**\n * A conta já teve pagamento confirmado numa assinatura paga.\n *\n * Diferente de `hasActivePaidSubscription`, aqui NÃO importa se a assinatura\n * segue vigente: quem pagou e depois cancelou/atrasou continua precisando de\n * nota fiscal do que já foi cobrado. Por isso o sinal é `charged` (marcado pelo\n * backend no `bill_paid`), e não `active`/`date_due`.\n *\n * Free e trial ficam de fora — nunca houve cobrança a documentar.\n */\nexport function hasPaidSubscription(\n subscription: PaidSubscriptionSnapshot | undefined | null,\n): boolean {\n if (!subscription) return false;\n if (subscription.type === 'free' || subscription.id_plan === FREE_PLAN_ID) {\n return false;\n }\n if (subscription.type === 'trial') return false;\n\n return subscription.charged === true;\n}\n"],"mappings":"AACA,SAAS,oBAAoB;AActB,SAAS,oBACd,cACS;AACT,MAAI,CAAC,aAAc,QAAO;AAC1B,MAAI,aAAa,SAAS,UAAU,aAAa,YAAY,cAAc;AACzE,WAAO;AAAA,EACT;AACA,MAAI,aAAa,SAAS,QAAS,QAAO;AAE1C,SAAO,aAAa,YAAY;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/subscriptions/utils/has-paid-subscription.ts"],"sourcesContent":["import type { Subscription } from '../types/subscription.type';\n\nconst FREE_PLAN_ID = 5;\n\ntype PaidSubscriptionSnapshot = Pick<Subscription, 'type' | 'id_plan' | 'charged'>;\n\n/**\n * A conta já teve pagamento confirmado numa assinatura paga.\n *\n * Diferente de `hasActivePaidSubscription`, aqui NÃO importa se a assinatura\n * segue vigente: quem pagou e depois cancelou/atrasou continua precisando de\n * nota fiscal do que já foi cobrado. Por isso o sinal é `charged` (marcado pelo\n * backend no `bill_paid`), e não `active`/`date_due`.\n *\n * Free e trial ficam de fora — nunca houve cobrança a documentar.\n */\nexport function hasPaidSubscription(\n subscription: PaidSubscriptionSnapshot | undefined | null,\n): boolean {\n if (!subscription) return false;\n if (subscription.type === 'free' || subscription.id_plan === FREE_PLAN_ID) {\n return false;\n }\n if (subscription.type === 'trial') return false;\n\n return subscription.charged === true;\n}\n"],"mappings":"AAEA,MAAM,eAAe;AAcd,SAAS,oBACd,cACS;AACT,MAAI,CAAC,aAAc,QAAO;AAC1B,MAAI,aAAa,SAAS,UAAU,aAAa,YAAY,cAAc;AACzE,WAAO;AAAA,EACT;AACA,MAAI,aAAa,SAAS,QAAS,QAAO;AAE1C,SAAO,aAAa,YAAY;AAClC;","names":[]}
package/dist/server.mjs CHANGED
@@ -22,8 +22,6 @@ import { findUserById } from "./modules/users/action/find-user-by-id.action";
22
22
  import { findCurrentAccount } from "./modules/accounts/actions/find-current-account.action";
23
23
  import { getAccountTokenAction } from "./modules/accounts/actions/get-account-token.action";
24
24
  import { listSubscriptionsAction } from "./modules/subscriptions/actions/list-subscriptions.action";
25
- import { getCurrentSubscriptionAction } from "./modules/subscriptions/actions/get-current-subscription.action";
26
- import { readCurrentSubscription } from "./modules/subscriptions/utils/read-current-subscription";
27
25
  import { ackFreezeNoticeAction } from "./modules/subscriptions/actions/ack-freeze-notice.action";
28
26
  import { calculateSubscriptionAction } from "./modules/subscriptions/actions/calculate-subscription.action";
29
27
  import { updateSubscriptionPlanAction } from "./modules/subscriptions/actions/update-subscription-plan.action";
@@ -112,7 +110,6 @@ export {
112
110
  generateTwoFactorAction,
113
111
  getAccountTokenAction,
114
112
  getClientInfoFromRequest,
115
- getCurrentSubscriptionAction,
116
113
  getUserContext,
117
114
  hasActivePaidSubscription,
118
115
  hasSubscriptionExpired,
@@ -126,7 +123,6 @@ export {
126
123
  processImageAction,
127
124
  projectUsersService,
128
125
  projectsService,
129
- readCurrentSubscription,
130
126
  removeProjectUserAction,
131
127
  requestEmailChangeAction,
132
128
  requestPhoneChangeAction,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { assertAccountNotFrozen } from './modules/auth/utils/assert-account-not-frozen';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { getCurrentSubscriptionAction } from './modules/subscriptions/actions/get-current-subscription.action';\r\nexport { readCurrentSubscription } from './modules/subscriptions/utils/read-current-subscription';\r\nexport { ackFreezeNoticeAction } from './modules/subscriptions/actions/ack-freeze-notice.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { hasActivePaidSubscription } from './modules/subscriptions/utils/has-active-paid-subscription';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n updateBillingDataAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { resolveLocale } from './i18n/resolve-locale';\r\nexport type { ResolveLocaleOptions } from './i18n/resolve-locale';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAG1C,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { assertAccountNotFrozen } from './modules/auth/utils/assert-account-not-frozen';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { ackFreezeNoticeAction } from './modules/subscriptions/actions/ack-freeze-notice.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { hasActivePaidSubscription } from './modules/subscriptions/utils/has-active-paid-subscription';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n updateBillingDataAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { resolveLocale } from './i18n/resolve-locale';\r\nexport type { ResolveLocaleOptions } from './i18n/resolve-locale';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,6BAA6B;AACtC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAG1C,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
@@ -1,10 +1,11 @@
1
1
  import { create } from "zustand";
2
- import { useEffect } from "react";
3
2
  import { readStorage, writeStorage } from "../utils/browser/safe-storage";
4
3
  const STORAGE_KEY = "md-sidebar-expanded";
4
+ function getInitialState() {
5
+ return readStorage(STORAGE_KEY) === "true";
6
+ }
5
7
  const useMdSidebarStore = create((set) => ({
6
- isExpanded: false,
7
- _hydrated: false,
8
+ isExpanded: getInitialState(),
8
9
  toggle: () => set((state) => {
9
10
  const next = !state.isExpanded;
10
11
  writeStorage(STORAGE_KEY, String(next));
@@ -17,23 +18,9 @@ const useMdSidebarStore = create((set) => ({
17
18
  collapse: () => {
18
19
  writeStorage(STORAGE_KEY, "false");
19
20
  return set({ isExpanded: false });
20
- },
21
- _hydrate: () => {
22
- const value = readStorage(STORAGE_KEY) === "true";
23
- set({ isExpanded: value, _hydrated: true });
24
21
  }
25
22
  }));
26
- function useMdSidebarHydration() {
27
- const hydrate = useMdSidebarStore((s) => s._hydrate);
28
- const hydrated = useMdSidebarStore((s) => s._hydrated);
29
- useEffect(() => {
30
- if (!hydrated) {
31
- hydrate();
32
- }
33
- }, [hydrate, hydrated]);
34
- }
35
23
  export {
36
- useMdSidebarHydration,
37
24
  useMdSidebarStore
38
25
  };
39
26
  //# sourceMappingURL=useMdSidebarStore.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/store/useMdSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport { useEffect } from \"react\";\nimport { readStorage, writeStorage } from \"../utils/browser/safe-storage\";\n\nconst STORAGE_KEY = \"md-sidebar-expanded\";\n\ntype MdSidebarStore = {\n isExpanded: boolean;\n _hydrated: boolean;\n toggle: () => void;\n expand: () => void;\n collapse: () => void;\n _hydrate: () => void;\n};\n\nexport const useMdSidebarStore = create<MdSidebarStore>((set) => ({\n isExpanded: false,\n _hydrated: false,\n toggle: () => set((state) => {\n const next = !state.isExpanded;\n writeStorage(STORAGE_KEY, String(next));\n return { isExpanded: next };\n }),\n expand: () => {\n writeStorage(STORAGE_KEY, \"true\");\n return set({ isExpanded: true });\n },\n collapse: () => {\n writeStorage(STORAGE_KEY, \"false\");\n return set({ isExpanded: false });\n },\n _hydrate: () => {\n const value = readStorage(STORAGE_KEY) === \"true\";\n set({ isExpanded: value, _hydrated: true });\n },\n}));\n\nexport function useMdSidebarHydration() {\n const hydrate = useMdSidebarStore((s) => s._hydrate);\n const hydrated = useMdSidebarStore((s) => s._hydrated);\n\n useEffect(() => {\n if (!hydrated) {\n hydrate();\n }\n }, [hydrate, hydrated]);\n}\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,aAAa,oBAAoB;AAE1C,MAAM,cAAc;AAWb,MAAM,oBAAoB,OAAuB,CAAC,SAAS;AAAA,EAC9D,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,QAAQ,MAAM,IAAI,CAAC,UAAU;AACzB,UAAM,OAAO,CAAC,MAAM;AACpB,iBAAa,aAAa,OAAO,IAAI,CAAC;AACtC,WAAO,EAAE,YAAY,KAAK;AAAA,EAC9B,CAAC;AAAA,EACD,QAAQ,MAAM;AACV,iBAAa,aAAa,MAAM;AAChC,WAAO,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,UAAU,MAAM;AACZ,iBAAa,aAAa,OAAO;AACjC,WAAO,IAAI,EAAE,YAAY,MAAM,CAAC;AAAA,EACpC;AAAA,EACA,UAAU,MAAM;AACZ,UAAM,QAAQ,YAAY,WAAW,MAAM;AAC3C,QAAI,EAAE,YAAY,OAAO,WAAW,KAAK,CAAC;AAAA,EAC9C;AACJ,EAAE;AAEK,SAAS,wBAAwB;AACpC,QAAM,UAAU,kBAAkB,CAAC,MAAM,EAAE,QAAQ;AACnD,QAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,SAAS;AAErD,YAAU,MAAM;AACZ,QAAI,CAAC,UAAU;AACX,cAAQ;AAAA,IACZ;AAAA,EACJ,GAAG,CAAC,SAAS,QAAQ,CAAC;AAC1B;","names":[]}
1
+ {"version":3,"sources":["../../src/store/useMdSidebarStore.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport { readStorage, writeStorage } from \"../utils/browser/safe-storage\";\n\nconst STORAGE_KEY = \"md-sidebar-expanded\";\n\nfunction getInitialState(): boolean {\n return readStorage(STORAGE_KEY) === \"true\";\n}\n\ntype MdSidebarStore = {\n isExpanded: boolean;\n toggle: () => void;\n expand: () => void;\n collapse: () => void;\n};\n\nexport const useMdSidebarStore = create<MdSidebarStore>((set) => ({\n isExpanded: getInitialState(),\n toggle: () => set((state) => {\n const next = !state.isExpanded;\n writeStorage(STORAGE_KEY, String(next));\n return { isExpanded: next };\n }),\n expand: () => {\n writeStorage(STORAGE_KEY, \"true\");\n return set({ isExpanded: true });\n },\n collapse: () => {\n writeStorage(STORAGE_KEY, \"false\");\n return set({ isExpanded: false });\n },\n}));\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,aAAa,oBAAoB;AAE1C,MAAM,cAAc;AAEpB,SAAS,kBAA2B;AAChC,SAAO,YAAY,WAAW,MAAM;AACxC;AASO,MAAM,oBAAoB,OAAuB,CAAC,SAAS;AAAA,EAC9D,YAAY,gBAAgB;AAAA,EAC5B,QAAQ,MAAM,IAAI,CAAC,UAAU;AACzB,UAAM,OAAO,CAAC,MAAM;AACpB,iBAAa,aAAa,OAAO,IAAI,CAAC;AACtC,WAAO,EAAE,YAAY,KAAK;AAAA,EAC9B,CAAC;AAAA,EACD,QAAQ,MAAM;AACV,iBAAa,aAAa,MAAM;AAChC,WAAO,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,UAAU,MAAM;AACZ,iBAAa,aAAa,OAAO;AACjC,WAAO,IAAI,EAAE,YAAY,MAAM,CAAC;AAAA,EACpC;AACJ,EAAE;","names":[]}
@@ -6,10 +6,7 @@ async function safeServerAction(fn) {
6
6
  return { success: true, data };
7
7
  } catch (error) {
8
8
  if (isRedirectError(error)) throw error;
9
- if (error instanceof ApiError) {
10
- return { success: false, error: error.message, code: error.code, statusCode: error.statusCode };
11
- }
12
- const message = error instanceof Error ? error.message : "Erro desconhecido";
9
+ const message = error instanceof ApiError ? error.message : error instanceof Error ? error.message : "Erro desconhecido";
13
10
  return { success: false, error: message };
14
11
  }
15
12
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/safeServerAction.ts"],"sourcesContent":["import { isRedirectError } from 'next/dist/client/components/redirect-error';\nimport { ApiError } from '../infra/api/types';\nimport type { ActionResult } from '../infra/api/types';\n\nexport async function safeServerAction<T>(\n fn: () => Promise<T>\n): Promise<ActionResult<T>> {\n try {\n const data = await fn();\n return { success: true, data };\n } catch (error) {\n if (isRedirectError(error)) throw error;\n if (error instanceof ApiError) {\n return { success: false, error: error.message, code: error.code, statusCode: error.statusCode };\n }\n const message = error instanceof Error ? error.message : 'Erro desconhecido';\n return { success: false, error: message };\n }\n}\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AAGzB,eAAsB,iBACpB,IAC0B;AAC1B,MAAI;AACF,UAAM,OAAO,MAAM,GAAG;AACtB,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B,SAAS,OAAO;AACd,QAAI,gBAAgB,KAAK,EAAG,OAAM;AAClC,QAAI,iBAAiB,UAAU;AAC7B,aAAO,EAAE,SAAS,OAAO,OAAO,MAAM,SAAS,MAAM,MAAM,MAAM,YAAY,MAAM,WAAW;AAAA,IAChG;AACA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,EAC1C;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/safeServerAction.ts"],"sourcesContent":["import { isRedirectError } from 'next/dist/client/components/redirect-error';\nimport { ApiError } from '../infra/api/types';\nimport type { ActionResult } from '../infra/api/types';\n\nexport async function safeServerAction<T>(\n fn: () => Promise<T>\n): Promise<ActionResult<T>> {\n try {\n const data = await fn();\n return { success: true, data };\n } catch (error) {\n if (isRedirectError(error)) throw error;\n const message =\n error instanceof ApiError\n ? error.message\n : error instanceof Error\n ? error.message\n : 'Erro desconhecido';\n return { success: false, error: message };\n }\n}\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AAGzB,eAAsB,iBACpB,IAC0B;AAC1B,MAAI;AACF,UAAM,OAAO,MAAM,GAAG;AACtB,WAAO,EAAE,SAAS,MAAM,KAAK;AAAA,EAC/B,SAAS,OAAO;AACd,QAAI,gBAAgB,KAAK,EAAG,OAAM;AAClC,UAAM,UACJ,iBAAiB,WACb,MAAM,UACN,iBAAiB,QACf,MAAM,UACN;AACR,WAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,EAC1C;AACF;","names":[]}
@@ -1,9 +1,8 @@
1
- import { ApiError } from "../infra/api/types";
2
1
  function withAction(action) {
3
2
  return async (...args) => {
4
3
  const result = await action(...args);
5
4
  if (!result.success) {
6
- throw new ApiError(result.error, result.code, result.statusCode);
5
+ throw new Error(result.error ?? "Erro desconhecido");
7
6
  }
8
7
  return result.data;
9
8
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/withAction.ts"],"sourcesContent":["import { ApiError } from '../infra/api/types';\nimport type { ActionResult } from '../infra/api/types';\n\nexport function withAction<TArgs extends any[], TData>(\n action: (...args: TArgs) => Promise<ActionResult<TData>>\n): (...args: TArgs) => Promise<TData> {\n return async (...args) => {\n const result = await action(...args);\n if (!result.success) {\n throw new ApiError(result.error, result.code, result.statusCode);\n }\n return result.data as TData;\n };\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AAGlB,SAAS,WACd,QACoC;AACpC,SAAO,UAAU,SAAS;AACxB,UAAM,SAAS,MAAM,OAAO,GAAG,IAAI;AACnC,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,SAAS,OAAO,OAAO,OAAO,MAAM,OAAO,UAAU;AAAA,IACjE;AACA,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/withAction.ts"],"sourcesContent":["import type { ActionResult } from '../infra/api/types';\n\nexport function withAction<TArgs extends any[], TData>(\n action: (...args: TArgs) => Promise<ActionResult<TData>>\n): (...args: TArgs) => Promise<TData> {\n return async (...args) => {\n const result = await action(...args);\n if (!result.success) {\n throw new Error(result.error ?? 'Erro desconhecido');\n }\n return result.data as TData;\n };\n}\n"],"mappings":"AAEO,SAAS,WACd,QACoC;AACpC,SAAO,UAAU,SAAS;AACxB,UAAM,SAAS,MAAM,OAAO,GAAG,IAAI;AACnC,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,MAAM,OAAO,SAAS,mBAAmB;AAAA,IACrD;AACA,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.784",
3
+ "version": "1.1.785",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -2,10 +2,8 @@
2
2
 
3
3
  import { ReactNode } from "react";
4
4
  import Image from "next/image";
5
- import { useTranslations } from "next-intl";
6
5
  import { IconMenu2, IconX } from "@tabler/icons-react";
7
6
  import { ProfilePopover } from "./ProfilePopover";
8
- import { GreatDomainIcon } from "./GreatDomainIcon";
9
7
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
10
8
  import { useMobileNavbarSheet } from "../../store/useMobileNavbarSheet";
11
9
  import {
@@ -17,13 +15,11 @@ import type { ProfileMenuItem } from "./ProfilePopover";
17
15
 
18
16
  export interface AppMobileNavBarProps {
19
17
  /** Which app is currently active — controls which icon gets the indicator */
20
- activeApp?: "gapps" | "gpages" | "gdomain";
18
+ activeApp?: "gapps" | "gpages";
21
19
  /** Called when the GreatApps logo is clicked */
22
20
  onLogoClick?: () => void;
23
21
  /** Called when the app icon (e.g. GreatPages) is clicked */
24
22
  onAppIconClick?: () => void;
25
- /** Called when the GreatDomain icon is clicked; without it the icon is not rendered (app flag) */
26
- onDomainIconClick?: () => void;
27
23
  /** Extra slot rendered after the app icon (e.g. project selector) */
28
24
  extraLeftSlot?: ReactNode;
29
25
  menuItems?: ProfileMenuItem[];
@@ -34,12 +30,10 @@ export function AppMobileNavBar({
34
30
  activeApp,
35
31
  onLogoClick,
36
32
  onAppIconClick,
37
- onDomainIconClick,
38
33
  extraLeftSlot,
39
34
  menuItems = [],
40
35
  showMenuToggle = true,
41
36
  }: AppMobileNavBarProps) {
42
- const translate = useTranslations();
43
37
  const { isOpen, toggle } = useMobileNavbarSheet();
44
38
  const { whitelabel } = useWhitelabel();
45
39
  const isDefaultWl = useIsDefaultWhitelabel();
@@ -48,7 +42,6 @@ export function AppMobileNavBar({
48
42
 
49
43
  const isGappsActive = activeApp === "gapps";
50
44
  const isGpagesActive = activeApp === "gpages";
51
- const isGdomainActive = activeApp === "gdomain";
52
45
 
53
46
  const wlIcon = whitelabel?.secondary_logo ? (
54
47
  <Image
@@ -87,9 +80,9 @@ export function AppMobileNavBar({
87
80
 
88
81
  return (
89
82
  <div className="fixed top-0 left-0 right-0 flex md:hidden items-center justify-between p-4 bg-white z-50 border-b border-gray-200">
90
- <div className="flex items-center gap-1.5 min-w-0">
83
+ <div className="flex items-center gap-1.5">
91
84
  {/* GreatApps logo */}
92
- <div className="relative shrink-0">
85
+ <div className="relative">
93
86
  <Tooltip>
94
87
  <TooltipTrigger asChild>
95
88
  <div
@@ -126,7 +119,7 @@ export function AppMobileNavBar({
126
119
  </div>
127
120
 
128
121
  {/* GreatPages icon */}
129
- <div className="relative shrink-0">
122
+ <div className="relative">
130
123
  <Tooltip>
131
124
  <TooltipTrigger asChild>
132
125
  <div
@@ -194,86 +187,9 @@ export function AppMobileNavBar({
194
187
  />
195
188
  </div>
196
189
 
197
- {/* GreatDomain icon */}
198
- {onDomainIconClick ? (
199
- <div className="relative shrink-0">
200
- <Tooltip>
201
- <TooltipTrigger asChild>
202
- <div
203
- aria-label={
204
- isDefaultWl
205
- ? translate("common.layout.navbar.greatDomain")
206
- : translate("common.layout.navbar.domains")
207
- }
208
- className={cn(
209
- "size-10 rounded-[10px] flex items-center justify-center border-2 ring-2 transition-colors duration-300",
210
- isGdomainActive
211
- ? isDefaultWl
212
- ? "bg-[#EDE9FE] border-white ring-[#C092FF]"
213
- : "border-white ring-transparent"
214
- : isDefaultWl
215
- ? "hover:bg-gray-100 border-transparent ring-transparent"
216
- : "border-transparent ring-transparent",
217
- "cursor-pointer",
218
- )}
219
- style={
220
- !isDefaultWl
221
- ? {
222
- backgroundColor: primaryColor,
223
- boxShadow: isGdomainActive
224
- ? `0 0 0 2px ${primaryColor}40`
225
- : undefined,
226
- opacity: !isGdomainActive ? 0.2 : undefined,
227
- }
228
- : undefined
229
- }
230
- onClick={onDomainIconClick}
231
- >
232
- {isDefaultWl ? (
233
- <GreatDomainIcon active={isGdomainActive} />
234
- ) : (
235
- <svg
236
- xmlns="http://www.w3.org/2000/svg"
237
- width="24"
238
- height="24"
239
- viewBox="0 0 24 24"
240
- fill="none"
241
- stroke="white"
242
- strokeWidth="2"
243
- strokeLinecap="round"
244
- strokeLinejoin="round"
245
- >
246
- <path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
247
- <path d="M3.6 9h16.8" />
248
- <path d="M3.6 15h16.8" />
249
- <path d="M11.5 3a17 17 0 0 0 0 18" />
250
- <path d="M12.5 3a17 17 0 0 1 0 18" />
251
- </svg>
252
- )}
253
- </div>
254
- </TooltipTrigger>
255
- <TooltipContent side="bottom">
256
- {isDefaultWl
257
- ? translate("common.layout.navbar.greatDomain")
258
- : translate("common.layout.navbar.domains")}
259
- </TooltipContent>
260
- </Tooltip>
261
- <div
262
- className={cn(
263
- "absolute -bottom-[17px] left-1/2 -translate-x-1/2 w-5 h-[3px] rounded-t-xl transition-opacity duration-300",
264
- isDefaultWl ? "bg-[#984DFF]" : "",
265
- isGdomainActive ? "opacity-100" : "opacity-0",
266
- )}
267
- style={!isDefaultWl ? { backgroundColor: primaryColor } : undefined}
268
- />
269
- </div>
270
- ) : null}
271
-
272
- {extraLeftSlot ? (
273
- <div className="min-w-0 shrink [&>*]:max-w-full">{extraLeftSlot}</div>
274
- ) : null}
190
+ {extraLeftSlot}
275
191
  </div>
276
- <div className="flex items-center gap-1.5 shrink-0">
192
+ <div className="flex items-center gap-1.5">
277
193
  <ProfilePopover
278
194
  side="bottom"
279
195
  align="end"