@bbearai/core 0.2.14 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +56 -72
- package/dist/index.mjs +56 -72
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
type ReportType = 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
|
|
5
5
|
type Severity = 'critical' | 'high' | 'medium' | 'low';
|
|
6
|
-
type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'verified' | 'wont_fix' | 'duplicate';
|
|
6
|
+
type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'ready_to_test' | 'verified' | 'resolved' | 'reviewed' | 'closed' | 'wont_fix' | 'duplicate';
|
|
7
7
|
interface AppContext {
|
|
8
8
|
/** Current route/screen path */
|
|
9
9
|
currentRoute: string;
|
|
@@ -160,6 +160,11 @@ interface BugBearConfig {
|
|
|
160
160
|
* the full web experience (analytics, discussions, history, etc.)
|
|
161
161
|
*/
|
|
162
162
|
dashboardUrl?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Called when an error occurs inside the BugBear SDK.
|
|
165
|
+
* Wire this to your error reporting service (e.g. Sentry.captureException).
|
|
166
|
+
*/
|
|
167
|
+
onError?: (error: Error, context?: Record<string, unknown>) => void;
|
|
163
168
|
}
|
|
164
169
|
interface BugBearTheme {
|
|
165
170
|
/** Primary brand color */
|
|
@@ -710,6 +715,19 @@ declare class BugBearClient {
|
|
|
710
715
|
* Uses parameterized RPC function to prevent SQL injection
|
|
711
716
|
*/
|
|
712
717
|
getTesterInfo(): Promise<TesterInfo | null>;
|
|
718
|
+
/**
|
|
719
|
+
* Get detailed assignment stats for the current tester via RPC.
|
|
720
|
+
* Returns counts by status (pending, in_progress, passed, failed, blocked, skipped, total).
|
|
721
|
+
*/
|
|
722
|
+
getTesterStats(): Promise<{
|
|
723
|
+
pending: number;
|
|
724
|
+
in_progress: number;
|
|
725
|
+
passed: number;
|
|
726
|
+
failed: number;
|
|
727
|
+
blocked: number;
|
|
728
|
+
skipped: number;
|
|
729
|
+
total: number;
|
|
730
|
+
} | null>;
|
|
713
731
|
/**
|
|
714
732
|
* Basic email format validation (defense in depth)
|
|
715
733
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
type ReportType = 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
|
|
5
5
|
type Severity = 'critical' | 'high' | 'medium' | 'low';
|
|
6
|
-
type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'verified' | 'wont_fix' | 'duplicate';
|
|
6
|
+
type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'ready_to_test' | 'verified' | 'resolved' | 'reviewed' | 'closed' | 'wont_fix' | 'duplicate';
|
|
7
7
|
interface AppContext {
|
|
8
8
|
/** Current route/screen path */
|
|
9
9
|
currentRoute: string;
|
|
@@ -160,6 +160,11 @@ interface BugBearConfig {
|
|
|
160
160
|
* the full web experience (analytics, discussions, history, etc.)
|
|
161
161
|
*/
|
|
162
162
|
dashboardUrl?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Called when an error occurs inside the BugBear SDK.
|
|
165
|
+
* Wire this to your error reporting service (e.g. Sentry.captureException).
|
|
166
|
+
*/
|
|
167
|
+
onError?: (error: Error, context?: Record<string, unknown>) => void;
|
|
163
168
|
}
|
|
164
169
|
interface BugBearTheme {
|
|
165
170
|
/** Primary brand color */
|
|
@@ -710,6 +715,19 @@ declare class BugBearClient {
|
|
|
710
715
|
* Uses parameterized RPC function to prevent SQL injection
|
|
711
716
|
*/
|
|
712
717
|
getTesterInfo(): Promise<TesterInfo | null>;
|
|
718
|
+
/**
|
|
719
|
+
* Get detailed assignment stats for the current tester via RPC.
|
|
720
|
+
* Returns counts by status (pending, in_progress, passed, failed, blocked, skipped, total).
|
|
721
|
+
*/
|
|
722
|
+
getTesterStats(): Promise<{
|
|
723
|
+
pending: number;
|
|
724
|
+
in_progress: number;
|
|
725
|
+
passed: number;
|
|
726
|
+
failed: number;
|
|
727
|
+
blocked: number;
|
|
728
|
+
skipped: number;
|
|
729
|
+
total: number;
|
|
730
|
+
} | null>;
|
|
713
731
|
/**
|
|
714
732
|
* Basic email format validation (defense in depth)
|
|
715
733
|
*/
|
package/dist/index.js
CHANGED
|
@@ -173,7 +173,7 @@ var ContextCaptureManager = class {
|
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
captureFetch() {
|
|
176
|
-
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
176
|
+
if (typeof window === "undefined" || typeof fetch === "undefined" || typeof document === "undefined") return;
|
|
177
177
|
this.originalFetch = window.fetch;
|
|
178
178
|
const self = this;
|
|
179
179
|
window.fetch = async function(input, init) {
|
|
@@ -440,7 +440,7 @@ var BugBearClient = class {
|
|
|
440
440
|
sort_order
|
|
441
441
|
)
|
|
442
442
|
)
|
|
443
|
-
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true });
|
|
443
|
+
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
444
444
|
if (error) {
|
|
445
445
|
console.error("BugBear: Failed to fetch assignments", error);
|
|
446
446
|
return [];
|
|
@@ -594,7 +594,7 @@ var BugBearClient = class {
|
|
|
594
594
|
if (options?.testResult) {
|
|
595
595
|
updateData.test_result = options.testResult;
|
|
596
596
|
}
|
|
597
|
-
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
597
|
+
const { data: updatedRow, error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId).eq("status", currentAssignment.status).select("id").maybeSingle();
|
|
598
598
|
if (error) {
|
|
599
599
|
console.error("BugBear: Failed to update assignment status", {
|
|
600
600
|
message: error.message,
|
|
@@ -607,6 +607,9 @@ var BugBearClient = class {
|
|
|
607
607
|
});
|
|
608
608
|
return { success: false, error: error.message };
|
|
609
609
|
}
|
|
610
|
+
if (!updatedRow) {
|
|
611
|
+
return { success: false, error: "Assignment status has changed. Please refresh and try again." };
|
|
612
|
+
}
|
|
610
613
|
if (options?.feedback && ["passed", "failed", "blocked"].includes(status)) {
|
|
611
614
|
const { data: assignmentData, error: fetchError2 } = await this.supabase.from("test_assignments").select("test_case_id").eq("id", assignmentId).single();
|
|
612
615
|
if (fetchError2) {
|
|
@@ -833,6 +836,28 @@ var BugBearClient = class {
|
|
|
833
836
|
return null;
|
|
834
837
|
}
|
|
835
838
|
}
|
|
839
|
+
/**
|
|
840
|
+
* Get detailed assignment stats for the current tester via RPC.
|
|
841
|
+
* Returns counts by status (pending, in_progress, passed, failed, blocked, skipped, total).
|
|
842
|
+
*/
|
|
843
|
+
async getTesterStats() {
|
|
844
|
+
try {
|
|
845
|
+
const testerInfo = await this.getTesterInfo();
|
|
846
|
+
if (!testerInfo) return null;
|
|
847
|
+
const { data, error } = await this.supabase.rpc("get_tester_stats", {
|
|
848
|
+
p_project_id: this.config.projectId,
|
|
849
|
+
p_tester_id: testerInfo.id
|
|
850
|
+
});
|
|
851
|
+
if (error) {
|
|
852
|
+
console.error("BugBear: Failed to fetch tester stats", error);
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
return data;
|
|
856
|
+
} catch (err) {
|
|
857
|
+
console.error("BugBear: Error fetching tester stats", err);
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
836
861
|
/**
|
|
837
862
|
* Basic email format validation (defense in depth)
|
|
838
863
|
*/
|
|
@@ -1166,75 +1191,35 @@ var BugBearClient = class {
|
|
|
1166
1191
|
try {
|
|
1167
1192
|
const testerInfo = await this.getTesterInfo();
|
|
1168
1193
|
if (!testerInfo) return [];
|
|
1169
|
-
const { data
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
priority,
|
|
1174
|
-
is_pinned,
|
|
1175
|
-
is_resolved,
|
|
1176
|
-
last_message_at,
|
|
1177
|
-
created_at
|
|
1178
|
-
`).eq("project_id", this.config.projectId).or(`audience.eq.all,audience_tester_ids.cs.{${testerInfo.id}}`).order("is_pinned", { ascending: false }).order("last_message_at", { ascending: false });
|
|
1194
|
+
const { data, error } = await this.supabase.rpc("get_threads_with_unread", {
|
|
1195
|
+
p_project_id: this.config.projectId,
|
|
1196
|
+
p_tester_id: testerInfo.id
|
|
1197
|
+
});
|
|
1179
1198
|
if (error) {
|
|
1180
|
-
console.error("BugBear: Failed to fetch threads", error);
|
|
1199
|
+
console.error("BugBear: Failed to fetch threads via RPC", error);
|
|
1181
1200
|
return [];
|
|
1182
1201
|
}
|
|
1183
|
-
if (!
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
const unreadCounts = await Promise.all(
|
|
1205
|
-
threads.map(async (thread) => {
|
|
1206
|
-
const readStatus = readStatusMap.get(thread.id);
|
|
1207
|
-
const lastReadAt = readStatus?.last_read_at || "1970-01-01T00:00:00Z";
|
|
1208
|
-
const { count, error: countError } = await this.supabase.from("discussion_messages").select("*", { count: "exact", head: true }).eq("thread_id", thread.id).gt("created_at", lastReadAt);
|
|
1209
|
-
return { threadId: thread.id, count: countError ? 0 : count || 0 };
|
|
1210
|
-
})
|
|
1211
|
-
);
|
|
1212
|
-
const unreadCountMap = new Map(
|
|
1213
|
-
unreadCounts.map((uc) => [uc.threadId, uc.count])
|
|
1214
|
-
);
|
|
1215
|
-
return threads.map((thread) => {
|
|
1216
|
-
const lastMsg = lastMessageMap.get(thread.id);
|
|
1217
|
-
return {
|
|
1218
|
-
id: thread.id,
|
|
1219
|
-
subject: thread.subject,
|
|
1220
|
-
threadType: thread.thread_type,
|
|
1221
|
-
priority: thread.priority,
|
|
1222
|
-
isPinned: thread.is_pinned,
|
|
1223
|
-
isResolved: thread.is_resolved,
|
|
1224
|
-
lastMessageAt: thread.last_message_at,
|
|
1225
|
-
createdAt: thread.created_at,
|
|
1226
|
-
unreadCount: unreadCountMap.get(thread.id) || 0,
|
|
1227
|
-
lastMessage: lastMsg ? {
|
|
1228
|
-
id: lastMsg.id,
|
|
1229
|
-
threadId: lastMsg.thread_id,
|
|
1230
|
-
senderType: lastMsg.sender_type,
|
|
1231
|
-
senderName: lastMsg.sender_name,
|
|
1232
|
-
content: lastMsg.content,
|
|
1233
|
-
createdAt: lastMsg.created_at,
|
|
1234
|
-
attachments: lastMsg.attachments || []
|
|
1235
|
-
} : void 0
|
|
1236
|
-
};
|
|
1237
|
-
});
|
|
1202
|
+
if (!data || data.length === 0) return [];
|
|
1203
|
+
return data.map((row) => ({
|
|
1204
|
+
id: row.thread_id,
|
|
1205
|
+
subject: row.thread_subject,
|
|
1206
|
+
threadType: row.thread_type,
|
|
1207
|
+
priority: row.thread_priority,
|
|
1208
|
+
isPinned: row.is_pinned,
|
|
1209
|
+
isResolved: row.is_resolved,
|
|
1210
|
+
lastMessageAt: row.last_message_at,
|
|
1211
|
+
createdAt: row.created_at,
|
|
1212
|
+
unreadCount: Number(row.unread_count) || 0,
|
|
1213
|
+
lastMessage: row.last_message_preview ? {
|
|
1214
|
+
id: "",
|
|
1215
|
+
threadId: row.thread_id,
|
|
1216
|
+
senderType: row.last_message_sender_type || "system",
|
|
1217
|
+
senderName: row.last_message_sender_name || "",
|
|
1218
|
+
content: row.last_message_preview,
|
|
1219
|
+
createdAt: row.last_message_at,
|
|
1220
|
+
attachments: []
|
|
1221
|
+
} : void 0
|
|
1222
|
+
}));
|
|
1238
1223
|
} catch (err) {
|
|
1239
1224
|
console.error("BugBear: Error fetching threads", err);
|
|
1240
1225
|
return [];
|
|
@@ -1253,7 +1238,7 @@ var BugBearClient = class {
|
|
|
1253
1238
|
content,
|
|
1254
1239
|
created_at,
|
|
1255
1240
|
attachments
|
|
1256
|
-
`).eq("thread_id", threadId).order("created_at", { ascending: true });
|
|
1241
|
+
`).eq("thread_id", threadId).order("created_at", { ascending: true }).limit(200);
|
|
1257
1242
|
if (error) {
|
|
1258
1243
|
console.error("BugBear: Failed to fetch messages", error);
|
|
1259
1244
|
return [];
|
|
@@ -1302,7 +1287,6 @@ var BugBearClient = class {
|
|
|
1302
1287
|
console.error("BugBear: Failed to send message", error);
|
|
1303
1288
|
return false;
|
|
1304
1289
|
}
|
|
1305
|
-
await this.supabase.from("discussion_threads").update({ last_message_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", threadId);
|
|
1306
1290
|
await this.markThreadAsRead(threadId);
|
|
1307
1291
|
return true;
|
|
1308
1292
|
} catch (err) {
|
|
@@ -1533,7 +1517,7 @@ var BugBearClient = class {
|
|
|
1533
1517
|
*/
|
|
1534
1518
|
async getSessionFindings(sessionId) {
|
|
1535
1519
|
try {
|
|
1536
|
-
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true });
|
|
1520
|
+
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true }).limit(100);
|
|
1537
1521
|
if (error) {
|
|
1538
1522
|
console.error("BugBear: Failed to fetch findings", error);
|
|
1539
1523
|
return [];
|
package/dist/index.mjs
CHANGED
|
@@ -144,7 +144,7 @@ var ContextCaptureManager = class {
|
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
146
|
captureFetch() {
|
|
147
|
-
if (typeof window === "undefined" || typeof fetch === "undefined") return;
|
|
147
|
+
if (typeof window === "undefined" || typeof fetch === "undefined" || typeof document === "undefined") return;
|
|
148
148
|
this.originalFetch = window.fetch;
|
|
149
149
|
const self = this;
|
|
150
150
|
window.fetch = async function(input, init) {
|
|
@@ -411,7 +411,7 @@ var BugBearClient = class {
|
|
|
411
411
|
sort_order
|
|
412
412
|
)
|
|
413
413
|
)
|
|
414
|
-
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true });
|
|
414
|
+
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
415
415
|
if (error) {
|
|
416
416
|
console.error("BugBear: Failed to fetch assignments", error);
|
|
417
417
|
return [];
|
|
@@ -565,7 +565,7 @@ var BugBearClient = class {
|
|
|
565
565
|
if (options?.testResult) {
|
|
566
566
|
updateData.test_result = options.testResult;
|
|
567
567
|
}
|
|
568
|
-
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
568
|
+
const { data: updatedRow, error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId).eq("status", currentAssignment.status).select("id").maybeSingle();
|
|
569
569
|
if (error) {
|
|
570
570
|
console.error("BugBear: Failed to update assignment status", {
|
|
571
571
|
message: error.message,
|
|
@@ -578,6 +578,9 @@ var BugBearClient = class {
|
|
|
578
578
|
});
|
|
579
579
|
return { success: false, error: error.message };
|
|
580
580
|
}
|
|
581
|
+
if (!updatedRow) {
|
|
582
|
+
return { success: false, error: "Assignment status has changed. Please refresh and try again." };
|
|
583
|
+
}
|
|
581
584
|
if (options?.feedback && ["passed", "failed", "blocked"].includes(status)) {
|
|
582
585
|
const { data: assignmentData, error: fetchError2 } = await this.supabase.from("test_assignments").select("test_case_id").eq("id", assignmentId).single();
|
|
583
586
|
if (fetchError2) {
|
|
@@ -804,6 +807,28 @@ var BugBearClient = class {
|
|
|
804
807
|
return null;
|
|
805
808
|
}
|
|
806
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* Get detailed assignment stats for the current tester via RPC.
|
|
812
|
+
* Returns counts by status (pending, in_progress, passed, failed, blocked, skipped, total).
|
|
813
|
+
*/
|
|
814
|
+
async getTesterStats() {
|
|
815
|
+
try {
|
|
816
|
+
const testerInfo = await this.getTesterInfo();
|
|
817
|
+
if (!testerInfo) return null;
|
|
818
|
+
const { data, error } = await this.supabase.rpc("get_tester_stats", {
|
|
819
|
+
p_project_id: this.config.projectId,
|
|
820
|
+
p_tester_id: testerInfo.id
|
|
821
|
+
});
|
|
822
|
+
if (error) {
|
|
823
|
+
console.error("BugBear: Failed to fetch tester stats", error);
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
return data;
|
|
827
|
+
} catch (err) {
|
|
828
|
+
console.error("BugBear: Error fetching tester stats", err);
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
807
832
|
/**
|
|
808
833
|
* Basic email format validation (defense in depth)
|
|
809
834
|
*/
|
|
@@ -1137,75 +1162,35 @@ var BugBearClient = class {
|
|
|
1137
1162
|
try {
|
|
1138
1163
|
const testerInfo = await this.getTesterInfo();
|
|
1139
1164
|
if (!testerInfo) return [];
|
|
1140
|
-
const { data
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
priority,
|
|
1145
|
-
is_pinned,
|
|
1146
|
-
is_resolved,
|
|
1147
|
-
last_message_at,
|
|
1148
|
-
created_at
|
|
1149
|
-
`).eq("project_id", this.config.projectId).or(`audience.eq.all,audience_tester_ids.cs.{${testerInfo.id}}`).order("is_pinned", { ascending: false }).order("last_message_at", { ascending: false });
|
|
1165
|
+
const { data, error } = await this.supabase.rpc("get_threads_with_unread", {
|
|
1166
|
+
p_project_id: this.config.projectId,
|
|
1167
|
+
p_tester_id: testerInfo.id
|
|
1168
|
+
});
|
|
1150
1169
|
if (error) {
|
|
1151
|
-
console.error("BugBear: Failed to fetch threads", error);
|
|
1170
|
+
console.error("BugBear: Failed to fetch threads via RPC", error);
|
|
1152
1171
|
return [];
|
|
1153
1172
|
}
|
|
1154
|
-
if (!
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
const unreadCounts = await Promise.all(
|
|
1176
|
-
threads.map(async (thread) => {
|
|
1177
|
-
const readStatus = readStatusMap.get(thread.id);
|
|
1178
|
-
const lastReadAt = readStatus?.last_read_at || "1970-01-01T00:00:00Z";
|
|
1179
|
-
const { count, error: countError } = await this.supabase.from("discussion_messages").select("*", { count: "exact", head: true }).eq("thread_id", thread.id).gt("created_at", lastReadAt);
|
|
1180
|
-
return { threadId: thread.id, count: countError ? 0 : count || 0 };
|
|
1181
|
-
})
|
|
1182
|
-
);
|
|
1183
|
-
const unreadCountMap = new Map(
|
|
1184
|
-
unreadCounts.map((uc) => [uc.threadId, uc.count])
|
|
1185
|
-
);
|
|
1186
|
-
return threads.map((thread) => {
|
|
1187
|
-
const lastMsg = lastMessageMap.get(thread.id);
|
|
1188
|
-
return {
|
|
1189
|
-
id: thread.id,
|
|
1190
|
-
subject: thread.subject,
|
|
1191
|
-
threadType: thread.thread_type,
|
|
1192
|
-
priority: thread.priority,
|
|
1193
|
-
isPinned: thread.is_pinned,
|
|
1194
|
-
isResolved: thread.is_resolved,
|
|
1195
|
-
lastMessageAt: thread.last_message_at,
|
|
1196
|
-
createdAt: thread.created_at,
|
|
1197
|
-
unreadCount: unreadCountMap.get(thread.id) || 0,
|
|
1198
|
-
lastMessage: lastMsg ? {
|
|
1199
|
-
id: lastMsg.id,
|
|
1200
|
-
threadId: lastMsg.thread_id,
|
|
1201
|
-
senderType: lastMsg.sender_type,
|
|
1202
|
-
senderName: lastMsg.sender_name,
|
|
1203
|
-
content: lastMsg.content,
|
|
1204
|
-
createdAt: lastMsg.created_at,
|
|
1205
|
-
attachments: lastMsg.attachments || []
|
|
1206
|
-
} : void 0
|
|
1207
|
-
};
|
|
1208
|
-
});
|
|
1173
|
+
if (!data || data.length === 0) return [];
|
|
1174
|
+
return data.map((row) => ({
|
|
1175
|
+
id: row.thread_id,
|
|
1176
|
+
subject: row.thread_subject,
|
|
1177
|
+
threadType: row.thread_type,
|
|
1178
|
+
priority: row.thread_priority,
|
|
1179
|
+
isPinned: row.is_pinned,
|
|
1180
|
+
isResolved: row.is_resolved,
|
|
1181
|
+
lastMessageAt: row.last_message_at,
|
|
1182
|
+
createdAt: row.created_at,
|
|
1183
|
+
unreadCount: Number(row.unread_count) || 0,
|
|
1184
|
+
lastMessage: row.last_message_preview ? {
|
|
1185
|
+
id: "",
|
|
1186
|
+
threadId: row.thread_id,
|
|
1187
|
+
senderType: row.last_message_sender_type || "system",
|
|
1188
|
+
senderName: row.last_message_sender_name || "",
|
|
1189
|
+
content: row.last_message_preview,
|
|
1190
|
+
createdAt: row.last_message_at,
|
|
1191
|
+
attachments: []
|
|
1192
|
+
} : void 0
|
|
1193
|
+
}));
|
|
1209
1194
|
} catch (err) {
|
|
1210
1195
|
console.error("BugBear: Error fetching threads", err);
|
|
1211
1196
|
return [];
|
|
@@ -1224,7 +1209,7 @@ var BugBearClient = class {
|
|
|
1224
1209
|
content,
|
|
1225
1210
|
created_at,
|
|
1226
1211
|
attachments
|
|
1227
|
-
`).eq("thread_id", threadId).order("created_at", { ascending: true });
|
|
1212
|
+
`).eq("thread_id", threadId).order("created_at", { ascending: true }).limit(200);
|
|
1228
1213
|
if (error) {
|
|
1229
1214
|
console.error("BugBear: Failed to fetch messages", error);
|
|
1230
1215
|
return [];
|
|
@@ -1273,7 +1258,6 @@ var BugBearClient = class {
|
|
|
1273
1258
|
console.error("BugBear: Failed to send message", error);
|
|
1274
1259
|
return false;
|
|
1275
1260
|
}
|
|
1276
|
-
await this.supabase.from("discussion_threads").update({ last_message_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", threadId);
|
|
1277
1261
|
await this.markThreadAsRead(threadId);
|
|
1278
1262
|
return true;
|
|
1279
1263
|
} catch (err) {
|
|
@@ -1504,7 +1488,7 @@ var BugBearClient = class {
|
|
|
1504
1488
|
*/
|
|
1505
1489
|
async getSessionFindings(sessionId) {
|
|
1506
1490
|
try {
|
|
1507
|
-
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true });
|
|
1491
|
+
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true }).limit(100);
|
|
1508
1492
|
if (error) {
|
|
1509
1493
|
console.error("BugBear: Failed to fetch findings", error);
|
|
1510
1494
|
return [];
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbearai/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Core utilities and types for BugBear QA platform",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
10
11
|
"import": "./dist/index.mjs",
|
|
11
|
-
"require": "./dist/index.js"
|
|
12
|
-
"types": "./dist/index.d.ts"
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|