feat(platform): guild.search and pin spans include guildId (v0.8.417)

Add searchGuildId to guild.search spans via endSearchSpan helper and
guildId metadata on pin.message and pin.unpin spans for diagnostics.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-24 00:24:52 -04:00
co-authored by Cursor
parent c879b0a84a
commit 30854a724a
2 changed files with 28 additions and 14 deletions
+2
View File
@@ -166,6 +166,8 @@ Primary consumer: `apps/pearcord/index.js` sidecar reading pear-pipe JSON.
**v0.8.410 (Phase 447):** `createGuildCustomRole`/`updateGuildCustomRole`/`deleteGuildCustomRole`/`reorderGuildCustomRoles`/`setMemberCustomRoles` spans and `role.* error` lines include `guildId`; `upsertChannelPermissionOverwrite`/`deleteChannelPermissionOverwrite` spans and `permission.overwrite*.error` include `guildId`, `channelId`, `targetType`, `targetId`. View snapshot adds `channelPermsByChannel` (effective `viewChannel`/`sendMessages` per channel) and `channelOverwriteCount` (guild overwrite row count). Bundle: `test:phase447-roles-permissions`. **v0.8.410 (Phase 447):** `createGuildCustomRole`/`updateGuildCustomRole`/`deleteGuildCustomRole`/`reorderGuildCustomRoles`/`setMemberCustomRoles` spans and `role.* error` lines include `guildId`; `upsertChannelPermissionOverwrite`/`deleteChannelPermissionOverwrite` spans and `permission.overwrite*.error` include `guildId`, `channelId`, `targetType`, `targetId`. View snapshot adds `channelPermsByChannel` (effective `viewChannel`/`sendMessages` per channel) and `channelOverwriteCount` (guild overwrite row count). Bundle: `test:phase447-roles-permissions`.
**v0.8.417:** `guild.search` spans include `guildId` on start/end (`endSearchSpan` helper); `pin.message`/`pin.unpin` spans include `guildId`. Smoke: `test:platform-search-span-guild-id`. Bundle: `test:phase454-search-pins`.
**v0.8.408:** `markChannelRead` calls `_invalidateSearchCache()` when the channel is a thread (`thread.read` path) so search results refresh after thread read. Smoke: `test:search-cache-invalidate-thread-read`. Bundle: `test:phase445-search-inbox`. **v0.8.408:** `markChannelRead` calls `_invalidateSearchCache()` when the channel is a thread (`thread.read` path) so search results refresh after thread read. Smoke: `test:search-cache-invalidate-thread-read`. Bundle: `test:phase445-search-inbox`.
**v0.8.406:** `createThread`/`createForumPost`/`markChannelRead` (thread channels)/`archiveThread` log `thread.create`/`forum.post`/`thread.read`/`thread.archive` spans and errors; audit entries for `thread.create`, `forum.post.create`, `thread.archive`, and `thread.unarchive`. Smoke: `test:thread-platform-errors`. **v0.8.406:** `createThread`/`createForumPost`/`markChannelRead` (thread channels)/`archiveThread` log `thread.create`/`forum.post`/`thread.read`/`thread.archive` spans and errors; audit entries for `thread.create`, `forum.post.create`, `thread.archive`, and `thread.unarchive`. Smoke: `test:thread-platform-errors`.
+26 -14
View File
@@ -1629,12 +1629,14 @@ class PearcordPlatform extends EventEmitter {
const cacheSpan = this.log.time('guild.search', { const cacheSpan = this.log.time('guild.search', {
scope: this._searchScope, scope: this._searchScope,
queryLen: String(q).length, queryLen: String(q).length,
cached: true cached: true,
guildId: this.guild?.guild?.id || null
}) })
cacheSpan.end({ cacheSpan.end({
count: this._cachedSearchResults.length, count: this._cachedSearchResults.length,
cached: true, cached: true,
logLevel: 'debug' logLevel: 'debug',
guildId: this.guild?.guild?.id || null
}) })
return this._cachedSearchResults return this._cachedSearchResults
} }
@@ -1653,10 +1655,15 @@ class PearcordPlatform extends EventEmitter {
} }
this._lastSearchFromCache = false this._lastSearchFromCache = false
const searchStarted = Date.now() const searchStarted = Date.now()
const searchGuildId = this.guild?.guild?.id || null
const span = this.log.time('guild.search', { const span = this.log.time('guild.search', {
scope: this._searchScope, scope: this._searchScope,
queryLen: String(q).length queryLen: String(q).length,
guildId: searchGuildId
}) })
const endSearchSpan = (fields = {}) => {
span.end({ guildId: searchGuildId, ...fields })
}
try { try {
if (this._guildOpenNoViewableChannels) { if (this._guildOpenNoViewableChannels) {
this._lastSearchMeshMeta = { this._lastSearchMeshMeta = {
@@ -1669,7 +1676,7 @@ class PearcordPlatform extends EventEmitter {
refreshing: false refreshing: false
} }
this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt
span.end({ count: 0, skipped: 'no-viewable-channels' }) endSearchSpan({ count: 0, skipped: 'no-viewable-channels' })
this._commitSearchCache(cacheKey, []) this._commitSearchCache(cacheKey, [])
return [] return []
} }
@@ -1685,7 +1692,7 @@ class PearcordPlatform extends EventEmitter {
ch = await this.db.get(COLLECTIONS.CHANNELS, { guildId, id: forumChannelId }) ch = await this.db.get(COLLECTIONS.CHANNELS, { guildId, id: forumChannelId })
} }
if (!ch || !isForumChannel(ch)) { if (!ch || !isForumChannel(ch)) {
span.end({ count: 0, scope: 'forum', skipped: 'not-forum' }) endSearchSpan({ count: 0, scope: 'forum', skipped: 'not-forum' })
this._commitSearchCache(cacheKey, []) this._commitSearchCache(cacheKey, [])
return [] return []
} }
@@ -1714,14 +1721,14 @@ class PearcordPlatform extends EventEmitter {
this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt
const searchMs = Date.now() - searchStarted const searchMs = Date.now() - searchStarted
this._lastSearchMeshMeta = { ...this._lastSearchMeshMeta, searchMs } this._lastSearchMeshMeta = { ...this._lastSearchMeshMeta, searchMs }
span.end({ count: out.hits?.length || 0, scope: 'forum', searchMs }) endSearchSpan({ count: out.hits?.length || 0, scope: 'forum', searchMs })
this._commitSearchCache(cacheKey, out.hits) this._commitSearchCache(cacheKey, out.hits)
return out.hits return out.hits
} }
if (this._searchScope === 'channel') { if (this._searchScope === 'channel') {
const channelId = this.activeChannelId const channelId = this.activeChannelId
if (!channelId) { if (!channelId) {
span.end({ count: 0, scope: 'channel', skipped: 'no-channel' }) endSearchSpan({ count: 0, scope: 'channel', skipped: 'no-channel' })
this._commitSearchCache(cacheKey, []) this._commitSearchCache(cacheKey, [])
return [] return []
} }
@@ -1781,7 +1788,7 @@ class PearcordPlatform extends EventEmitter {
searchMs searchMs
} }
this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt
span.end({ count: hits.length, scope: 'channel', searchMs }) endSearchSpan({ count: hits.length, scope: 'channel', searchMs })
this._commitSearchCache(cacheKey, hits) this._commitSearchCache(cacheKey, hits)
return hits return hits
} }
@@ -1802,7 +1809,7 @@ class PearcordPlatform extends EventEmitter {
this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt this._searchFetchedAt = this._lastSearchMeshMeta.fetchedAt
const searchMs = Date.now() - searchStarted const searchMs = Date.now() - searchStarted
this._lastSearchMeshMeta = { ...this._lastSearchMeshMeta, searchMs } this._lastSearchMeshMeta = { ...this._lastSearchMeshMeta, searchMs }
span.end({ endSearchSpan({
count: filtered?.length || 0, count: filtered?.length || 0,
scope: 'guild', scope: 'guild',
mesh: !!out.mesh, mesh: !!out.mesh,
@@ -1811,12 +1818,13 @@ class PearcordPlatform extends EventEmitter {
this._commitSearchCache(cacheKey, filtered) this._commitSearchCache(cacheKey, filtered)
return filtered return filtered
} }
span.end({ count: 0, scope: this._searchScope }) endSearchSpan({ count: 0, scope: this._searchScope })
this._commitSearchCache(cacheKey, []) this._commitSearchCache(cacheKey, [])
return [] return []
} catch (err) { } catch (err) {
this.log.error('guild.search error', { this.log.error('guild.search error', {
scope: this._searchScope, scope: this._searchScope,
guildId: searchGuildId,
error: err?.message || String(err) error: err?.message || String(err)
}) })
span.fail(err) span.fail(err)
@@ -10910,7 +10918,8 @@ class PearcordPlatform extends EventEmitter {
} }
async pinMessage (messageId) { async pinMessage (messageId) {
const span = this.log.time('pin.message', { messageId }) const guildId = this.guild?.guild?.id || null
const span = this.log.time('pin.message', { messageId, guildId })
try { try {
const user = this.identity.user const user = this.identity.user
if (!user || !this.guild?.guild) throw new Error('no guild') if (!user || !this.guild?.guild) throw new Error('no guild')
@@ -10933,11 +10942,12 @@ class PearcordPlatform extends EventEmitter {
await this.db.insert(COLLECTIONS.PINS, pin) await this.db.insert(COLLECTIONS.PINS, pin)
this.guild.gossipPin(pin) this.guild.gossipPin(pin)
this.emit('pin', pin) this.emit('pin', pin)
span.end({ channelId: pin.channelId }) span.end({ channelId: pin.channelId, guildId })
return pin return pin
} catch (err) { } catch (err) {
this.log.error('pin.message error', { this.log.error('pin.message error', {
messageId, messageId,
guildId,
error: err?.message || String(err) error: err?.message || String(err)
}) })
span.fail(err) span.fail(err)
@@ -10946,7 +10956,8 @@ class PearcordPlatform extends EventEmitter {
} }
async unpinMessage (messageId) { async unpinMessage (messageId) {
const span = this.log.time('pin.unpin', { messageId }) const guildId = this.guild?.guild?.id || null
const span = this.log.time('pin.unpin', { messageId, guildId })
try { try {
const roles = await this._memberRoles() const roles = await this._memberRoles()
if (!roleHasPermission(roles, PERMISSION.MANAGE_MESSAGES)) { if (!roleHasPermission(roles, PERMISSION.MANAGE_MESSAGES)) {
@@ -10957,10 +10968,11 @@ class PearcordPlatform extends EventEmitter {
messageId messageId
}) })
this.emit('pin', { channelId: this.activeChannelId, messageId, removed: true }) this.emit('pin', { channelId: this.activeChannelId, messageId, removed: true })
span.end({ channelId: this.activeChannelId }) span.end({ channelId: this.activeChannelId, guildId })
} catch (err) { } catch (err) {
this.log.error('pin.unpin error', { this.log.error('pin.unpin error', {
messageId, messageId,
guildId,
error: err?.message || String(err) error: err?.message || String(err)
}) })
span.fail(err) span.fail(err)