@spfn/monitor 0.1.0-beta.21 → 0.1.0-beta.23

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/server.d.ts CHANGED
@@ -291,6 +291,13 @@ declare class ErrorGroupsRepository extends BaseRepository {
291
291
  findMany(filters?: ErrorGroupFilters): Promise<ErrorGroup[]>;
292
292
  create(data: NewErrorGroup): Promise<ErrorGroup>;
293
293
  incrementCount(id: number): Promise<ErrorGroup | null>;
294
+ /**
295
+ * Reopen a resolved group: set active, clear resolvedAt, and bump count +
296
+ * lastSeenAt in a SINGLE UPDATE (the reopen path used to do updateStatus then
297
+ * incrementCount — two round trips writing the same row, the second clobbering
298
+ * the first).
299
+ */
300
+ reactivate(id: number): Promise<ErrorGroup | null>;
294
301
  updateStatus(id: number, status: ErrorGroupStatus): Promise<ErrorGroup | null>;
295
302
  countByStatus(): Promise<Record<ErrorGroupStatus, number>>;
296
303
  }
package/dist/server.js CHANGED
@@ -2786,6 +2786,23 @@ var ErrorGroupsRepository = class extends BaseRepository {
2786
2786
  }).where(eq(errorGroups.id, id4)).returning();
2787
2787
  return result[0] ?? null;
2788
2788
  }
2789
+ /**
2790
+ * Reopen a resolved group: set active, clear resolvedAt, and bump count +
2791
+ * lastSeenAt in a SINGLE UPDATE (the reopen path used to do updateStatus then
2792
+ * incrementCount — two round trips writing the same row, the second clobbering
2793
+ * the first).
2794
+ */
2795
+ async reactivate(id4) {
2796
+ const now = /* @__PURE__ */ new Date();
2797
+ const result = await this.db.update(errorGroups).set({
2798
+ status: "active",
2799
+ resolvedAt: null,
2800
+ count: sql`${errorGroups.count} + 1`,
2801
+ lastSeenAt: now,
2802
+ updatedAt: now
2803
+ }).where(eq(errorGroups.id, id4)).returning();
2804
+ return result[0] ?? null;
2805
+ }
2789
2806
  async updateStatus(id4, status) {
2790
2807
  const now = /* @__PURE__ */ new Date();
2791
2808
  const result = await this.db.update(errorGroups).set({
@@ -2829,8 +2846,8 @@ var ErrorEventsRepository = class extends BaseRepository2 {
2829
2846
  return await this.readDb.select().from(errorEvents).where(eq2(errorEvents.groupId, groupId)).orderBy(desc2(errorEvents.createdAt)).limit(limit).offset(offset);
2830
2847
  }
2831
2848
  async deleteOlderThan(date) {
2832
- const result = await this.db.delete(errorEvents).where(lt(errorEvents.createdAt, date)).returning();
2833
- return result.length;
2849
+ const result = await this.db.delete(errorEvents).where(lt(errorEvents.createdAt, date));
2850
+ return result.rowCount ?? result.count ?? 0;
2834
2851
  }
2835
2852
  };
2836
2853
  var errorEventsRepository = new ErrorEventsRepository();
@@ -2905,8 +2922,8 @@ var LogsRepository = class extends BaseRepository3 {
2905
2922
  return counts;
2906
2923
  }
2907
2924
  async deleteOlderThan(date) {
2908
- const result = await this.db.delete(logs).where(lt2(logs.createdAt, date)).returning();
2909
- return result.length;
2925
+ const result = await this.db.delete(logs).where(lt2(logs.createdAt, date));
2926
+ return result.rowCount ?? result.count ?? 0;
2910
2927
  }
2911
2928
  };
2912
2929
  var logsRepository = new LogsRepository();
@@ -3053,8 +3070,7 @@ async function trackError(err, ctx, metadata) {
3053
3070
  return;
3054
3071
  }
3055
3072
  if (existing.status === "resolved") {
3056
- await errorGroupsRepository.updateStatus(existing.id, "active");
3057
- await errorGroupsRepository.incrementCount(existing.id);
3073
+ await errorGroupsRepository.reactivate(existing.id);
3058
3074
  const event = await safeCreateEvent(existing.id, err, ctx, metadata);
3059
3075
  logger2.info("Error group reopened", { fingerprint, groupId: existing.id });
3060
3076
  if (event) {
@@ -3290,6 +3306,45 @@ var monitorRouter = defineRouter({
3290
3306
 
3291
3307
  // src/server/integrations/error-handler.ts
3292
3308
  import { getMinStatusCode } from "@spfn/monitor/config";
3309
+ var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
3310
+ "authorization",
3311
+ "proxy-authorization",
3312
+ "cookie",
3313
+ "set-cookie",
3314
+ "x-api-key",
3315
+ "x-auth-token",
3316
+ "x-csrf-token",
3317
+ "x-xsrf-token",
3318
+ "x-spfn-proxy-signature",
3319
+ "x-amz-security-token"
3320
+ ]);
3321
+ var SENSITIVE_QUERY = /* @__PURE__ */ new Set([
3322
+ "token",
3323
+ "access_token",
3324
+ "refresh_token",
3325
+ "id_token",
3326
+ "code",
3327
+ "secret",
3328
+ "client_secret",
3329
+ "password",
3330
+ "passwd",
3331
+ "pwd",
3332
+ "api_key",
3333
+ "apikey",
3334
+ "key",
3335
+ "signature",
3336
+ "sig",
3337
+ "session",
3338
+ "sessionid",
3339
+ "auth"
3340
+ ]);
3341
+ function redact(obj, deny) {
3342
+ const out = {};
3343
+ for (const [k, v] of Object.entries(obj)) {
3344
+ out[k] = deny.has(k.toLowerCase()) ? "***" : v;
3345
+ }
3346
+ return out;
3347
+ }
3293
3348
  var logger4 = monitorLogger.errorTracking;
3294
3349
  function createMonitorErrorHandler(options = {}) {
3295
3350
  return async (err, ctx) => {
@@ -3303,8 +3358,10 @@ function createMonitorErrorHandler(options = {}) {
3303
3358
  method: ctx.method,
3304
3359
  requestId: ctx.requestId,
3305
3360
  userId: ctx.userId != null ? String(ctx.userId) : void 0,
3306
- headers: ctx.request.headers,
3307
- query: ctx.request.query,
3361
+ // Redact secrets before they are persisted (error_events.headers) and
3362
+ // forwarded to Slack (S-H3 / S-M2 / S-L3).
3363
+ headers: redact(ctx.request.headers, SENSITIVE_HEADERS),
3364
+ query: redact(ctx.request.query, SENSITIVE_QUERY),
3308
3365
  environment: options.environment
3309
3366
  };
3310
3367
  const metadata = options.extractMetadata?.(err, trackingCtx);