@vtex/faststore-plugin-buyer-portal 1.1.72-experimental.5 → 1.1.72-experimental.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.1.72-experimental.5",
3
+ "version": "1.1.72-experimental.6",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -7,38 +7,5 @@ export const getOrgUnitBasicDataService = async ({
7
7
  id: string;
8
8
  cookie: string;
9
9
  }) => {
10
- try {
11
- console.log("[DEBUG] getOrgUnitBasicDataService called:", {
12
- id,
13
- hasCookie: !!cookie,
14
- });
15
-
16
- if (!id) {
17
- console.error("[ERROR] getOrgUnitBasicDataService: missing id");
18
- throw new Error("Organization Unit ID is required");
19
- }
20
-
21
- if (!cookie) {
22
- console.error("[ERROR] getOrgUnitBasicDataService: missing cookie");
23
- throw new Error("Authentication cookie is required");
24
- }
25
-
26
- const result = await orgUnitClient.getOrgUnitBasicData(id, cookie);
27
-
28
- console.log("[DEBUG] getOrgUnitBasicDataService result:", {
29
- success: !!result,
30
- orgUnitName: result?.name,
31
- });
32
-
33
- return result;
34
- } catch (error) {
35
- console.error("[ERROR] getOrgUnitBasicDataService failed:", {
36
- error: error instanceof Error ? error.message : "Unknown error",
37
- id,
38
- hasCookie: !!cookie,
39
- });
40
-
41
- // Return null instead of throwing to prevent 500 - let caller handle
42
- return null;
43
- }
10
+ return orgUnitClient.getOrgUnitBasicData(id, cookie);
44
11
  };
@@ -91,47 +91,5 @@ export function getCookieAsString(cookie: Record<string, string>): string {
91
91
  }
92
92
 
93
93
  function parseJwt(token: string): ParsedCookie {
94
- try {
95
- if (!token || typeof token !== "string") {
96
- console.error("[ERROR] Invalid JWT token:", { token: typeof token });
97
- throw new Error("Invalid JWT token: token is not a string");
98
- }
99
-
100
- const parts = token.split(".");
101
- if (parts.length !== 3) {
102
- console.error("[ERROR] Invalid JWT format:", {
103
- partsCount: parts.length,
104
- });
105
- throw new Error("Invalid JWT format: expected 3 parts");
106
- }
107
-
108
- const payload = parts[1];
109
- if (!payload) {
110
- console.error("[ERROR] Empty JWT payload");
111
- throw new Error("Invalid JWT: empty payload");
112
- }
113
-
114
- console.log("[DEBUG] Parsing JWT payload...");
115
- const decoded = JSON.parse(Buffer.from(payload, "base64").toString());
116
-
117
- console.log("[DEBUG] JWT parsed successfully:", {
118
- hasUserId: !!decoded.userId,
119
- hasCustomerId: !!decoded.customerId,
120
- exp: decoded.exp,
121
- currentTime: Math.floor(Date.now() / 1000),
122
- });
123
-
124
- return decoded;
125
- } catch (error) {
126
- console.error("[ERROR] JWT parsing failed:", {
127
- error: error instanceof Error ? error.message : "Unknown error",
128
- tokenLength: token?.length || 0,
129
- tokenPrefix: token?.substring(0, 20) + "...",
130
- });
131
- throw new Error(
132
- `JWT parsing failed: ${
133
- error instanceof Error ? error.message : "Unknown error"
134
- }`
135
- );
136
- }
94
+ return JSON.parse(Buffer.from(token.split(".")[1], "base64").toString());
137
95
  }
@@ -1,6 +1,6 @@
1
1
  import { Dropdown } from "@faststore/ui";
2
2
 
3
- import { useGetRolesOptions } from "../../../roles/hooks";
3
+ // import { useGetRolesOptions } from "../../../roles/hooks"; // Not needed - using props instead
4
4
  import {
5
5
  BasicDropdownMenu,
6
6
  HeaderInside,
@@ -13,21 +13,23 @@ import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
13
13
  import { ReassignOrgUnitDrawer, UpdateUserDrawer } from "../../components";
14
14
  import { UserDropdownMenu } from "../../components/UserDropdownMenu/UserDropdownMenu";
15
15
 
16
+ import type { RoleData } from "../../../roles/types";
16
17
  import type { UserData } from "../../types/UserData";
17
18
 
18
19
  export type UserDetailsLayoutProps = {
19
20
  data: {
20
21
  user?: UserData | null;
21
22
  orgUnit: { id: string; name: string };
23
+ rolesOptions?: RoleData[] | null;
22
24
  };
23
25
  };
24
26
 
25
27
  export const UserDetailsLayout = ({
26
- data: { user },
28
+ data: { user, rolesOptions },
27
29
  }: UserDetailsLayoutProps) => {
28
30
  const { currentOrgUnit } = useBuyerPortal();
29
31
 
30
- const { rolesOptions } = useGetRolesOptions(currentOrgUnit?.id ?? "");
32
+ // const { rolesOptions } = useGetRolesOptions(currentOrgUnit?.id ?? ""); // Using props instead
31
33
 
32
34
  const {
33
35
  open: openReassignDrawer,
@@ -57,7 +59,7 @@ export const UserDetailsLayout = ({
57
59
  <BasicDropdownMenu.Trigger />
58
60
  <UserDropdownMenu
59
61
  user={{ name: user?.name ?? "", id: user?.id ?? "" }}
60
- rolesOptions={rolesOptions}
62
+ rolesOptions={rolesOptions ?? null}
61
63
  />
62
64
  </Dropdown>
63
65
  </HeaderInside>
@@ -128,7 +130,7 @@ export const UserDetailsLayout = ({
128
130
  )}
129
131
  {isUpdateUserDrawerOpen && (
130
132
  <UpdateUserDrawer
131
- rolesOptions={rolesOptions}
133
+ rolesOptions={rolesOptions ?? null}
132
134
  userId={user?.id ?? ""}
133
135
  orgUnitId={currentOrgUnit?.id ?? ""}
134
136
  isOpen={isUpdateUserDrawerOpen}
@@ -1,17 +1,15 @@
1
- /**
2
- * User Details Page with integrated debug functionality
3
- */
4
-
5
1
  import {
6
2
  getOrgUnitBasicDataService,
7
3
  getOrgUnitByUserIdService,
8
4
  } from "../features/org-units/services";
5
+ import { getRolesIdsService } from "../features/roles/services";
9
6
  import { BuyerPortalProvider } from "../features/shared/components";
10
7
  import { type ClientContext, getClientContext } from "../features/shared/utils";
11
8
  import { UserDetailsLayout } from "../features/users/layouts";
12
9
  import { getUserByIdService } from "../features/users/services/get-user-by-id.service";
13
10
 
14
11
  import type { OrgUnitBasicData } from "../features/org-units/types";
12
+ import type { RoleData } from "../features/roles/types";
15
13
  import type { LoaderData } from "../features/shared/types";
16
14
  import type { UserData } from "../features/users/types";
17
15
 
@@ -24,313 +22,65 @@ export type UserDetailsPageData = {
24
22
  data: {
25
23
  user?: UserData | null;
26
24
  orgUnit: { id: string; name: string };
25
+ rolesOptions?: RoleData[] | null;
27
26
  };
28
27
  context: {
29
28
  clientContext: ClientContext;
30
29
  currentOrgUnit: OrgUnitBasicData | null;
31
30
  currentUser: UserData | null;
32
31
  };
33
- debug?: {
34
- logs: Array<{
35
- timestamp: string;
36
- level: "info" | "error" | "warn";
37
- step: string;
38
- message: string;
39
- data?: any;
40
- }>;
41
- error?: any;
42
- };
43
32
  };
44
33
 
45
34
  export async function loader(
46
35
  data: LoaderData<UserDetailsPageQuery>
47
36
  ): Promise<UserDetailsPageData> {
48
- const logs: NonNullable<UserDetailsPageData["debug"]>["logs"] = [];
49
-
50
- function addLog(
51
- level: "info" | "error" | "warn",
52
- step: string,
53
- message: string,
54
- logData?: any
55
- ) {
56
- const timestamp = new Date().toISOString();
57
- logs.push({ timestamp, level, step, message, data: logData });
58
- console.log(
59
- `🔍 [USER-DETAILS] [${level.toUpperCase()}] ${step}: ${message}`,
60
- logData || ""
61
- );
62
- }
63
-
64
- function createErrorResponse(errorMessage: string, errorDetails?: any) {
65
- return {
66
- data: { user: null, orgUnit: { id: "", name: "" } },
67
- context: {
68
- clientContext: {
69
- cookie: "",
70
- vtexIdclientAutCookie: "",
71
- customerId: "",
72
- userId: "",
73
- },
74
- currentOrgUnit: null,
75
- currentUser: null,
76
- },
77
- debug: {
78
- logs,
79
- error: {
80
- message: errorMessage,
81
- details: errorDetails,
82
- timestamp: new Date().toISOString(),
83
- },
84
- },
85
- };
86
- }
37
+ const { cookie, customerId, ...clientContext } = await getClientContext(data);
87
38
 
88
- addLog("info", "START", "Starting user-details loader");
39
+ const { userId, orgUnitId } = data.query;
89
40
 
90
- // Proteção extra contra dados malformados
91
- if (!data) {
92
- addLog("error", "VALIDATION", "LoaderData is undefined");
93
- return createErrorResponse("LoaderData is undefined - request malformed");
94
- }
41
+ const user = await getUserByIdService({ orgUnitId, userId, cookie });
95
42
 
96
- if (!data.query) {
97
- addLog("error", "VALIDATION", "Query parameters missing");
98
- return createErrorResponse("Query parameters missing from request");
43
+ if (!user) {
44
+ data.res?.writeHead(302, { Location: "/buyer-portal" });
45
+ data.res?.end();
99
46
  }
100
47
 
101
- try {
102
- addLog("info", "REQUEST", "Request info", {
103
- cookies: Object.keys(data.req?.cookies || {}),
104
- query: data.query,
105
- });
106
-
107
- addLog("info", "CONTEXT", "Getting client context...");
108
- const { cookie, ...clientContext } = await getClientContext(data);
109
- addLog("info", "CONTEXT", "Client context obtained ✅", {
110
- hasUserId: !!clientContext.userId,
111
- hasCustomerId: !!clientContext.customerId,
112
- cookieLength: cookie?.length || 0,
113
- });
114
-
115
- const { userId, orgUnitId } = data.query;
116
-
117
- if (!userId || !orgUnitId) {
118
- addLog("error", "VALIDATION", "Missing required query params", {
119
- userId,
120
- orgUnitId,
121
- });
122
- return createErrorResponse(
123
- "Missing required query parameters: userId or orgUnitId",
124
- { providedUserId: userId, providedOrgUnitId: orgUnitId }
125
- );
126
- }
127
-
128
- addLog("info", "VALIDATION", "Query params validated ✅", {
129
- userId,
130
- orgUnitId,
131
- });
132
-
133
- addLog("info", "USER_SERVICE", "Fetching user by ID...");
134
- const user = await getUserByIdService({ orgUnitId, userId, cookie });
135
- addLog("info", "USER_SERVICE", "User service result", {
136
- found: !!user,
137
- email: user?.email,
138
- });
139
-
140
- if (!user) {
141
- addLog("warn", "USER_SERVICE", "User not found");
142
- return createErrorResponse("User not found", { userId, orgUnitId });
143
- }
144
-
145
- addLog("info", "ORG_UNIT_BASIC", "Fetching current org unit...");
146
- const currentOrgUnit = await getOrgUnitBasicDataService({
48
+ const [currentOrgUnit, orgUnitFromUser, rolesOptions] = await Promise.all([
49
+ getOrgUnitBasicDataService({
147
50
  id: orgUnitId,
148
51
  cookie,
149
- });
150
- addLog("info", "ORG_UNIT_BASIC", "Current org unit result", {
151
- found: !!currentOrgUnit,
152
- name: currentOrgUnit?.name,
153
- });
154
-
155
- addLog("info", "ORG_UNIT_USER", "Fetching org unit by user ID...");
156
- const orgUnitFromUser = await getOrgUnitByUserIdService({
52
+ }),
53
+ getOrgUnitByUserIdService({
157
54
  userId,
158
55
  cookie,
159
- });
160
- addLog("info", "ORG_UNIT_USER", "Org unit from user result", {
161
- found: !!orgUnitFromUser,
162
- id: orgUnitFromUser?.id,
163
- });
164
-
165
- addLog("info", "SUCCESS", "All steps completed successfully! ✅");
166
-
167
- const result = {
168
- data: {
169
- user,
170
- orgUnit: {
171
- id: orgUnitFromUser?.id ?? "",
172
- name: orgUnitFromUser?.name ?? "",
173
- },
174
- },
175
- context: {
176
- clientContext: { cookie, ...clientContext },
177
- currentOrgUnit,
178
- currentUser: user,
56
+ }),
57
+ getRolesIdsService({
58
+ unitId: orgUnitId,
59
+ customerId,
60
+ cookie,
61
+ }).catch(() => null), // Gracefully handle errors
62
+ ]);
63
+
64
+ return {
65
+ data: {
66
+ user,
67
+ orgUnit: {
68
+ id: orgUnitFromUser?.id ?? "",
69
+ name: orgUnitFromUser?.name ?? "",
179
70
  },
180
- };
181
-
182
- // Só incluir debug se houver erros ou warnings
183
- const hasIssues = logs.some(
184
- (log) => log.level === "error" || log.level === "warn"
185
- );
186
- if (hasIssues) {
187
- (result as UserDetailsPageData).debug = { logs };
188
- }
189
-
190
- return result;
191
- } catch (error) {
192
- const errorMessage =
193
- error instanceof Error ? error.message : "Unknown error occurred";
194
- const errorDetails =
195
- error instanceof Error
196
- ? {
197
- name: error.name,
198
- stack: error.stack,
199
- }
200
- : { rawError: error };
201
-
202
- addLog("error", "FATAL_ERROR", "Loader failed with error", {
203
- message: errorMessage,
204
- details: errorDetails,
205
- });
206
-
207
- // Always return a valid response, never throw
208
- return createErrorResponse(errorMessage, errorDetails);
209
- }
71
+ rolesOptions,
72
+ },
73
+ context: {
74
+ clientContext: { cookie, customerId, ...clientContext },
75
+ currentOrgUnit,
76
+ currentUser: user,
77
+ },
78
+ };
210
79
  }
211
80
 
212
- const UserDetailsPage = (props?: UserDetailsPageData) => {
213
- // Se props estiver undefined
214
- if (!props) {
215
- return (
216
- <div style={{ padding: "40px", textAlign: "center" }}>
217
- <h1>🚨 Erro de Carregamento</h1>
218
- <p>Não foi possível carregar os dados da página.</p>
219
- <p>Tente recarregar a página ou verificar sua conexão.</p>
220
- </div>
221
- );
222
- }
223
-
224
- const { data, context, debug } = props;
225
-
226
- // Se tiver debug info (erros), mostrar página simples de debug
227
- if (debug?.error) {
228
- return (
229
- <div style={{ maxWidth: "800px", margin: "0 auto", padding: "20px" }}>
230
- <div
231
- style={{
232
- background: "#fff3cd",
233
- padding: "20px",
234
- marginBottom: "20px",
235
- borderRadius: "8px",
236
- }}
237
- >
238
- <h1>🚨 Erro na Página User Details</h1>
239
- <p>Ocorreu um erro ao carregar a página.</p>
240
- </div>
241
-
242
- <div style={{ marginBottom: "20px" }}>
243
- <h2>📝 Logs de Execução</h2>
244
- <div
245
- style={{
246
- background: "#1e1e1e",
247
- color: "#fff",
248
- padding: "20px",
249
- borderRadius: "8px",
250
- fontFamily: "monospace",
251
- fontSize: "12px",
252
- maxHeight: "400px",
253
- overflowY: "auto",
254
- }}
255
- >
256
- {debug.logs?.map((log, index) => (
257
- <div key={index} style={{ marginBottom: "10px" }}>
258
- <div
259
- style={{
260
- color:
261
- log.level === "error"
262
- ? "#ff6b6b"
263
- : log.level === "warn"
264
- ? "#ffa726"
265
- : "#81c784",
266
- }}
267
- >
268
- [{log.level.toUpperCase()}] {log.step}: {log.message}
269
- </div>
270
- {log.data && (
271
- <pre
272
- style={{ fontSize: "10px", color: "#ccc", margin: "5px 0" }}
273
- >
274
- {JSON.stringify(log.data, null, 2)}
275
- </pre>
276
- )}
277
- </div>
278
- ))}
279
- </div>
280
- </div>
281
-
282
- {debug.error && (
283
- <div style={{ marginBottom: "20px" }}>
284
- <h2>❌ Detalhes do Erro</h2>
285
- <pre
286
- style={{
287
- background: "#f8d7da",
288
- padding: "15px",
289
- borderRadius: "8px",
290
- fontSize: "12px",
291
- overflow: "auto",
292
- }}
293
- >
294
- {JSON.stringify(debug.error, null, 2)}
295
- </pre>
296
- </div>
297
- )}
298
-
299
- <div
300
- style={{
301
- background: "#d1ecf1",
302
- padding: "15px",
303
- borderRadius: "8px",
304
- }}
305
- >
306
- <h3>🔧 Como resolver:</h3>
307
- <ol>
308
- <li>Verifique se você está logado na VTEX</li>
309
- <li>Confirme se os IDs da URL estão corretos</li>
310
- <li>Tente fazer logout e login novamente</li>
311
- <li>Abra o console do browser (F12) para ver logs adicionais</li>
312
- </ol>
313
- </div>
314
-
315
- <script
316
- dangerouslySetInnerHTML={{
317
- __html: `
318
- console.group('🔍 USER DETAILS DEBUG INFO');
319
- console.log('Error Details:', ${JSON.stringify(debug.error)});
320
- console.log('Execution Logs:', ${JSON.stringify(debug.logs)});
321
- console.groupEnd();
322
- `,
323
- }}
324
- />
325
- </div>
326
- );
327
- }
328
-
329
- // Se não tiver debug info, mostrar página normal
330
- return (
331
- <BuyerPortalProvider {...context}>
332
- <UserDetailsLayout data={data} />
333
- </BuyerPortalProvider>
334
- );
335
- };
81
+ const UserDetailsPage = ({ data, context }: UserDetailsPageData) => (
82
+ <BuyerPortalProvider {...context}>
83
+ <UserDetailsLayout data={data} />
84
+ </BuyerPortalProvider>
85
+ );
336
86
  export default UserDetailsPage;
@@ -1,253 +0,0 @@
1
- # 🚨 Guia de Debug - Erro 500 na Página User Details
2
-
3
- ## ✅ **O que foi implementado:**
4
-
5
- ### 1. **Logging Detalhado**
6
-
7
- - ✅ Adicionado logging extensivo no loader `user-details.tsx`
8
- - ✅ Melhorado parsing JWT com validação robusta
9
- - ✅ Tratamento de erro em `getOrgUnitBasicDataService`
10
- - ✅ Criado utilitários de debug (`debug.ts`)
11
-
12
- ### 2. **Página de Debug**
13
-
14
- - ✅ Criada página temporária `/buyer-portal/debug-user-details/[orgUnitId]/[userId]`
15
- - ✅ Adicionada rota no `plugin.config.js`
16
- - ✅ Interface visual para troubleshooting
17
-
18
- ## 🔍 **Como debugar o erro 500:**
19
-
20
- ### **Passo 1: Acesse a página problemática**
21
-
22
- ```
23
- https://seusite.com/buyer-portal/user/[orgUnitId]/[userId]
24
- ```
25
-
26
- **Substitua:**
27
-
28
- - `[orgUnitId]` pelo ID da org unit problemática
29
- - `[userId]` pelo ID do usuário que está causando erro
30
-
31
- **IMPORTANTE:** Quando houver erro, a página vai mostrar **automaticamente** uma tela de debug com todos os logs!
32
-
33
- ### **Passo 2: Analise os logs (DIRETO NA PÁGINA! 🎉)**
34
-
35
- **IMPORTANTE:** Agora os logs aparecem **diretamente na página de debug**! Não precisa acessar servidor!
36
-
37
- Na página debug você verá:
38
-
39
- - 📝 **Execution Logs (Real-time)** - Uma seção com todos os logs do processo
40
- - ✅ Logs verdes: operações que funcionaram
41
- - ⚠️ Logs amarelos: avisos
42
- - ❌ Logs vermelhos: erros
43
-
44
- **Exemplo do que você vai ver:**
45
-
46
- ```
47
- 14:30:25 - START
48
- [INFO] Starting debug loader
49
-
50
- 14:30:25 - VALIDATION
51
- [INFO] Request validation passed ✅
52
-
53
- 14:30:25 - CONTEXT
54
- [INFO] Client context obtained ✅
55
- { hasUserId: true, cookieLength: 234 }
56
-
57
- 14:30:26 - USER_SERVICE
58
- [ERROR] User service failed
59
- { error: "JWT parsing failed", tokenLength: 0 }
60
- ```
61
-
62
- ### **Passo 3: Verifique pontos críticos**
63
-
64
- #### **3.1 Cookies de Autenticação**
65
-
66
- ```javascript
67
- // Procure por este log:
68
- [DEBUG] JWT parsed successfully: { hasUserId: true, hasCustomerId: true }
69
-
70
- // Se aparecer erro:
71
- [ERROR] JWT parsing failed
72
- [ERROR] Invalid JWT token
73
- ```
74
-
75
- #### **3.2 APIs da VTEX**
76
-
77
- ```javascript
78
- // Procure por:
79
- [DEBUG] getOrgUnitBasicDataService called
80
- [ERROR] getOrgUnitBasicDataService failed
81
- ```
82
-
83
- #### **3.3 Parâmetros da URL**
84
-
85
- ```javascript
86
- // Deve aparecer:
87
- [DEBUG] user-details loader started: { query: { userId: "123", orgUnitId: "456" } }
88
-
89
- // Se não tiver userId ou orgUnitId, vai dar erro:
90
- [ERROR] Missing required query parameters
91
- ```
92
-
93
- ## 🎯 **Cenários mais comuns:**
94
-
95
- ### **Erro 1: Cookie JWT inválido/expirado**
96
-
97
- **Sintomas:**
98
-
99
- - `[ERROR] JWT parsing failed`
100
- - `[ERROR] Invalid JWT token`
101
-
102
- **Solução:**
103
-
104
- - Usuário precisa fazer login novamente
105
- - Verificar se o cookie `VtexIdclientAutCookie_[storeId]` existe
106
-
107
- ### **Erro 2: API VTEX indisponível**
108
-
109
- **Sintomas:**
110
-
111
- - `[ERROR] getOrgUnitBasicDataService failed`
112
- - `[ERROR] getUserByIdService failed`
113
-
114
- **Solução:**
115
-
116
- - Verificar conectividade com APIs da VTEX
117
- - Verificar se `storeConfig.api.storeId` está correto
118
-
119
- ### **Erro 3: Parâmetros de URL inválidos**
120
-
121
- **Sintomas:**
122
-
123
- - `[ERROR] Missing required query parameters`
124
- - `[DEBUG] User service result: { userFound: false }`
125
-
126
- **Solução:**
127
-
128
- - Verificar se userId e orgUnitId são válidos
129
- - Testar com IDs conhecidos que funcionam
130
-
131
- ### **Erro 4: Discovery Config**
132
-
133
- **Sintomas:**
134
-
135
- - Erro ao construir URLs de API
136
- - `storeConfig is undefined`
137
-
138
- **Solução:**
139
-
140
- - Verificar se `discovery.config` está presente
141
- - Verificar configurações da store
142
-
143
- ## 🛠️ **Comandos úteis para debug:**
144
-
145
- ### **1. Ver logs no Browser Console (FÁCIL!):**
146
-
147
- ```bash
148
- # Abra DevTools (F12) no Chrome/Firefox
149
- # Vá na aba Console
150
- # Procure por logs que começam com:
151
- 🔍 [BUYER-PORTAL-DEBUG]
152
-
153
- # Exemplo do que vai aparecer:
154
- 🔍 [BUYER-PORTAL-DEBUG] CONTEXT: Getting client context...
155
- 🔍 [BUYER-PORTAL-DEBUG] USER_SERVICE: Fetching user by ID...
156
- ```
157
-
158
- ### **2. Ver logs do servidor (se tiver acesso):**
159
-
160
- ```bash
161
- # Tail nos logs do Next.js
162
- tail -f /caminho/para/logs/nextjs.log | grep -E "(DEBUG|ERROR)"
163
-
164
- # Ou se usando PM2:
165
- pm2 logs | grep -E "(DEBUG|ERROR)"
166
- ```
167
-
168
- ### **3. Testar APIs manualmente:**
169
-
170
- ```bash
171
- # Teste a API de usuário:
172
- curl -H "Cookie: VtexIdclientAutCookie_[storeId]=TOKEN" \
173
- "https://[storeId].myvtex.com/_v/store-front/users/[orgUnitId]/[userId]"
174
- ```
175
-
176
- ### **4. Verificar configurações:**
177
-
178
- ```javascript
179
- // No browser console (dev tools):
180
- console.log("Store Config:", window.storeConfig);
181
- ```
182
-
183
- ## 📊 **Informações importantes da página de debug:**
184
-
185
- ### **JSON Debug Response:**
186
-
187
- ```json
188
- {
189
- "success": false,
190
- "debug": {
191
- "timestamp": "2024-01-01T12:00:00.000Z",
192
- "cookies": {
193
- "cookieKeys": ["session", "VtexIdclientAutCookie_store"],
194
- "vtexAuthCookie": true
195
- },
196
- "query": { "userId": "123", "orgUnitId": "456" }
197
- },
198
- "error": {
199
- "message": "JWT parsing failed",
200
- "name": "Error"
201
- }
202
- }
203
- ```
204
-
205
- ## 🚀 **Após identificar o problema:**
206
-
207
- ### **1. Remover arquivos de debug (IMPORTANTE!):**
208
-
209
- ```bash
210
- rm src/pages/debug-user-details.tsx
211
- rm src/features/shared/utils/debug.ts
212
- rm DEBUG-500-GUIDE.md
213
- ```
214
-
215
- ### **2. Remover rota debug do plugin.config.js**
216
-
217
- ### **3. Limpar logs de produção:**
218
-
219
- - Remover/comentar console.log em produção
220
- - Manter apenas logs de erro essenciais
221
-
222
- ## 🆘 **Se ainda não conseguir resolver:**
223
-
224
- ### **Colete estas informações:**
225
-
226
- 1. **Logs completos** da página de debug
227
- 2. **URL exata** que está falhando
228
- 3. **Browser e versão** do usuário
229
- 4. **Horário específico** do erro
230
- 5. **Se funciona em desenvolvimento** mas não em produção
231
-
232
- ### **Pontos adicionais para investigar:**
233
-
234
- - **Rate limiting** das APIs da VTEX
235
- - **Configurações de CORS**
236
- - **Certificados SSL**
237
- - **Timeout de requests**
238
- - **Configurações de proxy/CDN**
239
-
240
- ## 📝 **Checklist de debug:**
241
-
242
- - [ ] Página de debug criada e testada
243
- - [ ] Logs do servidor coletados
244
- - [ ] Cookies de auth verificados
245
- - [ ] APIs da VTEX testadas manualmente
246
- - [ ] Parâmetros de URL validados
247
- - [ ] Discovery config verificado
248
- - [ ] Diferenças dev vs prod identificadas
249
- - [ ] Arquivos de debug removidos após solução
250
-
251
- ---
252
-
253
- **⚡ Dica:** A página de debug é sua melhor ferramenta - ela vai te mostrar exatamente onde está falhando!
@@ -1,157 +0,0 @@
1
- /**
2
- * Debug utilities for production troubleshooting
3
- * Use these functions to gather information when debugging 500 errors
4
- */
5
-
6
- export interface DebugInfo {
7
- timestamp: string;
8
- url?: string;
9
- userAgent?: string;
10
- cookies: Record<string, any>;
11
- headers?: Record<string, any>;
12
- query?: Record<string, any>;
13
- environment: string;
14
- }
15
-
16
- export function getDebugInfo(req?: any, query?: any): DebugInfo {
17
- return {
18
- timestamp: new Date().toISOString(),
19
- url: req?.url,
20
- userAgent: req?.headers?.["user-agent"],
21
- cookies: {
22
- cookieKeys: Object.keys(req?.cookies || {}),
23
- hasCookies: !!(req?.cookies && Object.keys(req.cookies).length > 0),
24
- vtexAuthCookie: !!(
25
- req?.cookies?.VtexIdclientAutCookie ||
26
- Object.keys(req?.cookies || {}).find((key) =>
27
- key.includes("VtexIdclientAutCookie")
28
- )
29
- ),
30
- },
31
- headers: {
32
- hasAuthorization: !!req?.headers?.authorization,
33
- contentType: req?.headers?.["content-type"],
34
- origin: req?.headers?.origin,
35
- },
36
- query,
37
- environment: process.env.NODE_ENV || "unknown",
38
- };
39
- }
40
-
41
- export function logDebugInfo(info: DebugInfo, context: string = "DEBUG") {
42
- console.log(`[${context}] Debug Info:`, JSON.stringify(info, null, 2));
43
- }
44
-
45
- /**
46
- * Browser-safe logging that works on both client and server
47
- */
48
- export function logToBrowser(
49
- message: string,
50
- data?: any,
51
- level: "info" | "error" | "warn" = "info"
52
- ) {
53
- if (typeof window !== "undefined") {
54
- // Client-side: log to browser console
55
- const logFunc =
56
- level === "error"
57
- ? console.error
58
- : level === "warn"
59
- ? console.warn
60
- : console.log;
61
- logFunc(`🔍 [BUYER-PORTAL-DEBUG] ${message}`, data || "");
62
- } else {
63
- // Server-side: still log to server console
64
- const logFunc =
65
- level === "error"
66
- ? console.error
67
- : level === "warn"
68
- ? console.warn
69
- : console.log;
70
- logFunc(`🔍 [BUYER-PORTAL-DEBUG] ${message}`, data || "");
71
- }
72
- }
73
-
74
- /**
75
- * Safe function to extract error details without exposing sensitive data
76
- */
77
- export function sanitizeError(error: unknown): Record<string, any> {
78
- if (error instanceof Error) {
79
- return {
80
- name: error.name,
81
- message: error.message,
82
- stack:
83
- process.env.NODE_ENV === "development"
84
- ? error.stack
85
- : "Hidden in production",
86
- };
87
- }
88
-
89
- if (typeof error === "string") {
90
- return { message: error };
91
- }
92
-
93
- return { message: "Unknown error type", type: typeof error };
94
- }
95
-
96
- /**
97
- * Create a debug endpoint response for troubleshooting
98
- */
99
- export function createDebugResponse(req?: any, error?: unknown) {
100
- const debugInfo = getDebugInfo(req);
101
- const errorInfo = error ? sanitizeError(error) : null;
102
-
103
- return {
104
- debug: debugInfo,
105
- error: errorInfo,
106
- suggestions: [
107
- "Check if authentication cookies are present and valid",
108
- "Verify VTEX API endpoints are accessible",
109
- "Ensure required query parameters are provided",
110
- "Check server logs for more detailed error information",
111
- ],
112
- };
113
- }
114
-
115
- /**
116
- * Validate essential request data
117
- */
118
- export function validateRequest(
119
- req?: any,
120
- requiredQuery: string[] = []
121
- ): {
122
- isValid: boolean;
123
- errors: string[];
124
- } {
125
- const errors: string[] = [];
126
-
127
- if (!req) {
128
- errors.push("Request object is missing");
129
- }
130
-
131
- if (!req?.cookies || Object.keys(req.cookies).length === 0) {
132
- errors.push("No cookies found in request");
133
- }
134
-
135
- // Check for VTEX auth cookie
136
- const hasVtexAuth =
137
- req?.cookies &&
138
- Object.keys(req.cookies).some((key) =>
139
- key.includes("VtexIdclientAutCookie")
140
- );
141
-
142
- if (!hasVtexAuth) {
143
- errors.push("VTEX authentication cookie not found");
144
- }
145
-
146
- // Check required query parameters
147
- for (const param of requiredQuery) {
148
- if (!req?.query?.[param]) {
149
- errors.push(`Required query parameter missing: ${param}`);
150
- }
151
- }
152
-
153
- return {
154
- isValid: errors.length === 0,
155
- errors,
156
- };
157
- }