@vtex/faststore-plugin-buyer-portal 1.1.72-experimental.4 → 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.4",
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}
@@ -2,12 +2,14 @@ import {
2
2
  getOrgUnitBasicDataService,
3
3
  getOrgUnitByUserIdService,
4
4
  } from "../features/org-units/services";
5
+ import { getRolesIdsService } from "../features/roles/services";
5
6
  import { BuyerPortalProvider } from "../features/shared/components";
6
7
  import { type ClientContext, getClientContext } from "../features/shared/utils";
7
8
  import { UserDetailsLayout } from "../features/users/layouts";
8
9
  import { getUserByIdService } from "../features/users/services/get-user-by-id.service";
9
10
 
10
11
  import type { OrgUnitBasicData } from "../features/org-units/types";
12
+ import type { RoleData } from "../features/roles/types";
11
13
  import type { LoaderData } from "../features/shared/types";
12
14
  import type { UserData } from "../features/users/types";
13
15
 
@@ -20,374 +22,65 @@ export type UserDetailsPageData = {
20
22
  data: {
21
23
  user?: UserData | null;
22
24
  orgUnit: { id: string; name: string };
25
+ rolesOptions?: RoleData[] | null;
23
26
  };
24
27
  context: {
25
28
  clientContext: ClientContext;
26
29
  currentOrgUnit: OrgUnitBasicData | null;
27
30
  currentUser: UserData | null;
28
31
  };
29
- debug?: {
30
- logs: Array<{
31
- timestamp: string;
32
- level: "info" | "error" | "warn";
33
- step: string;
34
- message: string;
35
- data?: any;
36
- }>;
37
- error?: any;
38
- };
39
32
  };
40
33
 
41
34
  export async function loader(
42
35
  data: LoaderData<UserDetailsPageQuery>
43
36
  ): Promise<UserDetailsPageData> {
44
- const logs: NonNullable<UserDetailsPageData["debug"]>["logs"] = [];
45
-
46
- function addLog(
47
- level: "info" | "error" | "warn",
48
- step: string,
49
- message: string,
50
- logData?: any
51
- ) {
52
- const timestamp = new Date().toISOString();
53
- logs.push({ timestamp, level, step, message, data: logData });
54
- console.log(
55
- `🔍 [USER-DETAILS] [${level.toUpperCase()}] ${step}: ${message}`,
56
- logData || ""
57
- );
58
- }
59
-
60
- addLog("info", "START", "Starting user-details loader");
61
-
62
- try {
63
- addLog("info", "REQUEST", "Request info", {
64
- cookies: Object.keys(data.req?.cookies || {}),
65
- query: data.query,
66
- });
67
-
68
- addLog("info", "CONTEXT", "Getting client context...");
69
- const { cookie, ...clientContext } = await getClientContext(data);
70
- addLog("info", "CONTEXT", "Client context obtained ✅", {
71
- hasUserId: !!clientContext.userId,
72
- hasCustomerId: !!clientContext.customerId,
73
- cookieLength: cookie?.length || 0,
74
- });
75
-
76
- const { userId, orgUnitId } = data.query;
77
-
78
- if (!userId || !orgUnitId) {
79
- addLog("error", "VALIDATION", "Missing required query params", {
80
- userId,
81
- orgUnitId,
82
- });
83
- throw new Error("Missing required query parameters: userId or orgUnitId");
84
- }
37
+ const { cookie, customerId, ...clientContext } = await getClientContext(data);
85
38
 
86
- addLog("info", "VALIDATION", "Query params validated ✅", {
87
- userId,
88
- orgUnitId,
89
- });
90
-
91
- addLog("info", "USER_SERVICE", "Fetching user by ID...");
92
- const user = await getUserByIdService({ orgUnitId, userId, cookie });
93
- addLog("info", "USER_SERVICE", "User service result", {
94
- found: !!user,
95
- email: user?.email,
96
- });
39
+ const { userId, orgUnitId } = data.query;
97
40
 
98
- if (!user) {
99
- addLog("warn", "USER_SERVICE", "User not found - redirecting");
100
- data.res?.writeHead(302, { Location: "/buyer-portal" });
101
- data.res?.end();
41
+ const user = await getUserByIdService({ orgUnitId, userId, cookie });
102
42
 
103
- return {
104
- data: { user: null, orgUnit: { id: "", name: "" } },
105
- context: {
106
- clientContext: { cookie, ...clientContext },
107
- currentOrgUnit: null,
108
- currentUser: null,
109
- },
110
- debug: {
111
- logs,
112
- error: { message: "User not found", userId, orgUnitId },
113
- },
114
- };
115
- }
43
+ if (!user) {
44
+ data.res?.writeHead(302, { Location: "/buyer-portal" });
45
+ data.res?.end();
46
+ }
116
47
 
117
- addLog("info", "ORG_UNIT_BASIC", "Fetching current org unit...");
118
- const currentOrgUnit = await getOrgUnitBasicDataService({
48
+ const [currentOrgUnit, orgUnitFromUser, rolesOptions] = await Promise.all([
49
+ getOrgUnitBasicDataService({
119
50
  id: orgUnitId,
120
51
  cookie,
121
- });
122
- addLog("info", "ORG_UNIT_BASIC", "Current org unit result", {
123
- found: !!currentOrgUnit,
124
- name: currentOrgUnit?.name,
125
- });
126
-
127
- addLog("info", "ORG_UNIT_USER", "Fetching org unit by user ID...");
128
- const orgUnitFromUser = await getOrgUnitByUserIdService({
52
+ }),
53
+ getOrgUnitByUserIdService({
129
54
  userId,
130
55
  cookie,
131
- });
132
- addLog("info", "ORG_UNIT_USER", "Org unit from user result", {
133
- found: !!orgUnitFromUser,
134
- id: orgUnitFromUser?.id,
135
- });
136
-
137
- addLog("info", "SUCCESS", "All steps completed successfully! ✅");
138
-
139
- const result = {
140
- data: {
141
- user,
142
- orgUnit: {
143
- id: orgUnitFromUser?.id ?? "",
144
- name: orgUnitFromUser?.name ?? "",
145
- },
146
- },
147
- context: {
148
- clientContext: { cookie, ...clientContext },
149
- currentOrgUnit,
150
- currentUser: user,
151
- },
152
- };
153
-
154
- // Só incluir debug se houver erros ou warnings
155
- const hasIssues = logs.some(
156
- (log) => log.level === "error" || log.level === "warn"
157
- );
158
- if (hasIssues) {
159
- (result as UserDetailsPageData).debug = { logs };
160
- }
161
-
162
- return result;
163
- } catch (error) {
164
- addLog("error", "FATAL_ERROR", "Loader failed with error", {
165
- error: error instanceof Error ? error.message : "Unknown error",
166
- stack: error instanceof Error ? error.stack : undefined,
167
- });
168
-
169
- // Return error page instead of throwing
170
- return {
171
- data: { user: null, orgUnit: { id: "", name: "" } },
172
- context: {
173
- clientContext: {
174
- cookie: "",
175
- vtexIdclientAutCookie: "",
176
- customerId: "",
177
- userId: "",
178
- },
179
- currentOrgUnit: null,
180
- currentUser: null,
181
- },
182
- debug: {
183
- logs,
184
- error:
185
- error instanceof Error
186
- ? {
187
- message: error.message,
188
- name: error.name,
189
- stack: error.stack,
190
- }
191
- : { message: "Unknown error", error },
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 ?? "",
192
70
  },
193
- };
194
- }
71
+ rolesOptions,
72
+ },
73
+ context: {
74
+ clientContext: { cookie, customerId, ...clientContext },
75
+ currentOrgUnit,
76
+ currentUser: user,
77
+ },
78
+ };
195
79
  }
196
80
 
197
- const UserDetailsPage = ({ data, context, debug }: UserDetailsPageData) => {
198
- // Se tiver debug info (erros), mostrar página de debug
199
- if (debug) {
200
- return (
201
- <div
202
- style={{
203
- maxWidth: "900px",
204
- margin: "0 auto",
205
- padding: "20px",
206
- fontFamily: "system-ui, sans-serif",
207
- }}
208
- >
209
- <div
210
- style={{
211
- background: "#fff3cd",
212
- border: "1px solid #ffc107",
213
- borderRadius: "8px",
214
- padding: "20px",
215
- marginBottom: "20px",
216
- }}
217
- >
218
- <h1 style={{ color: "#856404", margin: "0 0 10px 0" }}>
219
- 🚨 Erro na Página User Details
220
- </h1>
221
- <p style={{ color: "#856404", margin: 0 }}>
222
- Ocorreu um erro ao carregar a página. Veja os detalhes abaixo:
223
- </p>
224
- </div>
225
-
226
- {/* Logs em tempo real */}
227
- <div style={{ marginBottom: "30px" }}>
228
- <h2
229
- style={{
230
- color: "#333",
231
- borderBottom: "2px solid #007bff",
232
- paddingBottom: "10px",
233
- }}
234
- >
235
- 📝 Logs de Execução
236
- </h2>
237
- <div
238
- style={{
239
- background: "#1e1e1e",
240
- color: "#ffffff",
241
- padding: "20px",
242
- borderRadius: "8px",
243
- fontFamily: "Monaco, Consolas, monospace",
244
- fontSize: "13px",
245
- maxHeight: "500px",
246
- overflowY: "auto",
247
- border: "1px solid #333",
248
- }}
249
- >
250
- {debug.logs.map((log, index) => (
251
- <div
252
- key={index}
253
- style={{
254
- marginBottom: "12px",
255
- borderLeft: `4px solid ${
256
- log.level === "error"
257
- ? "#ff4444"
258
- : log.level === "warn"
259
- ? "#ff9800"
260
- : "#4caf50"
261
- }`,
262
- paddingLeft: "15px",
263
- paddingBottom: "8px",
264
- }}
265
- >
266
- <div
267
- style={{
268
- color: "#888",
269
- fontSize: "11px",
270
- marginBottom: "4px",
271
- }}
272
- >
273
- {new Date(log.timestamp).toLocaleTimeString("pt-BR")} -{" "}
274
- {log.step}
275
- </div>
276
- <div
277
- style={{
278
- color:
279
- log.level === "error"
280
- ? "#ff6b6b"
281
- : log.level === "warn"
282
- ? "#ffa726"
283
- : "#81c784",
284
- fontWeight: "bold",
285
- marginBottom: log.data ? "8px" : 0,
286
- }}
287
- >
288
- [{log.level.toUpperCase()}] {log.message}
289
- </div>
290
- {log.data && (
291
- <pre
292
- style={{
293
- fontSize: "11px",
294
- color: "#ccc",
295
- background: "#2d2d2d",
296
- padding: "8px",
297
- borderRadius: "4px",
298
- margin: 0,
299
- whiteSpace: "pre-wrap",
300
- overflow: "auto",
301
- }}
302
- >
303
- {JSON.stringify(log.data, null, 2)}
304
- </pre>
305
- )}
306
- </div>
307
- ))}
308
- </div>
309
- </div>
310
-
311
- {/* Detalhes do erro */}
312
- {debug.error && (
313
- <div style={{ marginBottom: "30px" }}>
314
- <h2
315
- style={{
316
- color: "#dc3545",
317
- borderBottom: "2px solid #dc3545",
318
- paddingBottom: "10px",
319
- }}
320
- >
321
- ❌ Detalhes do Erro
322
- </h2>
323
- <pre
324
- style={{
325
- background: "#f8d7da",
326
- color: "#721c24",
327
- padding: "20px",
328
- borderRadius: "8px",
329
- border: "1px solid #f5c6cb",
330
- overflow: "auto",
331
- fontSize: "13px",
332
- }}
333
- >
334
- {JSON.stringify(debug.error, null, 2)}
335
- </pre>
336
- </div>
337
- )}
338
-
339
- {/* Próximos passos */}
340
- <div
341
- style={{
342
- background: "#d1ecf1",
343
- border: "1px solid #bee5eb",
344
- borderRadius: "8px",
345
- padding: "20px",
346
- }}
347
- >
348
- <h3 style={{ color: "#0c5460", margin: "0 0 15px 0" }}>
349
- 🔧 Como resolver:
350
- </h3>
351
- <ol style={{ color: "#0c5460", paddingLeft: "20px" }}>
352
- <li>Verifique se você está logado na VTEX</li>
353
- <li>Confirme se os IDs da URL estão corretos</li>
354
- <li>Tente fazer logout e login novamente</li>
355
- <li>Se o erro persistir, entre em contato com o suporte</li>
356
- </ol>
357
-
358
- <div
359
- style={{
360
- marginTop: "15px",
361
- padding: "10px",
362
- background: "#b8daff",
363
- borderRadius: "4px",
364
- }}
365
- >
366
- <strong>💡 Dica:</strong> Abra o console do browser (F12) para ver
367
- logs adicionais
368
- </div>
369
- </div>
370
-
371
- <script
372
- dangerouslySetInnerHTML={{
373
- __html: `
374
- // Log debug info to browser console
375
- console.group('🔍 USER DETAILS DEBUG INFO');
376
- console.log('Error Details:', ${JSON.stringify(debug.error)});
377
- console.log('Execution Logs:', ${JSON.stringify(debug.logs)});
378
- console.groupEnd();
379
- `,
380
- }}
381
- />
382
- </div>
383
- );
384
- }
385
-
386
- // Se não tiver debug info, mostrar página normal
387
- return (
388
- <BuyerPortalProvider {...context}>
389
- <UserDetailsLayout data={data} />
390
- </BuyerPortalProvider>
391
- );
392
- };
81
+ const UserDetailsPage = ({ data, context }: UserDetailsPageData) => (
82
+ <BuyerPortalProvider {...context}>
83
+ <UserDetailsLayout data={data} />
84
+ </BuyerPortalProvider>
85
+ );
393
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
- }