feat(threads-forum): channel.delete and thread/forum span guildId (v0.8.421)
deleteChannel with gossip; thread.create, thread.archive, and forum.post spans include guildId, span.fail, and structured error logs. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -35,6 +35,8 @@ Expose a single `EventEmitter` API the UI drives over IPC (`apps/pearcord/index.
|
|||||||
| `onboarded`, `identity`, `storagePath`, `db`, `dbPath` | Session state |
|
| `onboarded`, `identity`, `storagePath`, `db`, `dbPath` | Session state |
|
||||||
| `listGuilds()`, `loadGuild(guildId)`, `createGuild({ name, publicListing? })`, `joinInvite(code)` | Guild session |
|
| `listGuilds()`, `loadGuild(guildId)`, `createGuild({ name, publicListing? })`, `joinInvite(code)` | Guild session |
|
||||||
|
|
||||||
|
**v0.8.421 (Phase 458):** `channel.delete` span + gossip; `thread.create`, `thread.archive`, `forum.post` spans include `guildId` + `span.fail`. Bundle: `npm run test:phase458-threads-forum`. See [MESSAGE_THREADS.md](../../docs/MESSAGE_THREADS.md), [FORUM_CHANNELS.md](../../docs/FORUM_CHANNELS.md).
|
||||||
|
|
||||||
**v0.8.420 (Phase 457):** `channel.create`, `channel.update` (rename), and `category.create` spans + error logs with `guildId`. `create-channel` IPC selects new channel and emits composer focus. Bundle: `npm run test:phase457-channels`. See [CHANNELS.md](../../docs/CHANNELS.md).
|
**v0.8.420 (Phase 457):** `channel.create`, `channel.update` (rename), and `category.create` spans + error logs with `guildId`. `create-channel` IPC selects new channel and emits composer focus. Bundle: `npm run test:phase457-channels`. See [CHANNELS.md](../../docs/CHANNELS.md).
|
||||||
|
|
||||||
**v0.8.419 (Phase 456):** `session.startup` span ends with `guildCount` + `guildId`; `session.startup error` log. `identity.register` span + `identity.register error`. `guild.open` span end includes `guildId`. `loadGuild` / `createGuild` bust search cache and clear `_lastSearchFromCache`. Bundle: `npm run test:phase456-onboarding-session`. See [SESSION.md](../../docs/SESSION.md).
|
**v0.8.419 (Phase 456):** `session.startup` span ends with `guildCount` + `guildId`; `session.startup error` log. `identity.register` span + `identity.register error`. `guild.open` span end includes `guildId`. `loadGuild` / `createGuild` bust search cache and clear `_lastSearchFromCache`. Bundle: `npm run test:phase456-onboarding-session`. See [SESSION.md](../../docs/SESSION.md).
|
||||||
|
|||||||
@@ -3077,6 +3077,9 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
this._fanoutBotEvent(BOT_EVENTS.CHANNEL_CREATE, { channel: ch })
|
this._fanoutBotEvent(BOT_EVENTS.CHANNEL_CREATE, { channel: ch })
|
||||||
this.emit('channel', ch)
|
this.emit('channel', ch)
|
||||||
})
|
})
|
||||||
|
guildInstance.on('channel-delete', (p) => {
|
||||||
|
this.emit('channel-delete', p)
|
||||||
|
})
|
||||||
guildInstance.on('pin', (p) => this.emit('pin', p))
|
guildInstance.on('pin', (p) => this.emit('pin', p))
|
||||||
guildInstance.on('ban', (p) => this._onBanGossip(p))
|
guildInstance.on('ban', (p) => this._onBanGossip(p))
|
||||||
guildInstance.on('channel-settings', (p) => {
|
guildInstance.on('channel-settings', (p) => {
|
||||||
@@ -10657,7 +10660,9 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createForumPost ({ title, content, tags }) {
|
async createForumPost ({ title, content, tags }) {
|
||||||
|
const guildId = this.guild?.guild?.id || null
|
||||||
const span = this.log.time('forum.post', {
|
const span = this.log.time('forum.post', {
|
||||||
|
guildId,
|
||||||
title: String(title || '').trim().slice(0, 64) || null
|
title: String(title || '').trim().slice(0, 64) || null
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
@@ -10682,7 +10687,6 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
const message = await this.sendMessage(body)
|
const message = await this.sendMessage(body)
|
||||||
const merged = await this.guild.setThreadRootMessage(thread.id, message.id)
|
const merged = await this.guild.setThreadRootMessage(thread.id, message.id)
|
||||||
this.guild.gossipChannelUpdate(merged)
|
this.guild.gossipChannelUpdate(merged)
|
||||||
const guildId = this.guild.guild.id
|
|
||||||
const palette = this.forum.parsePaletteFromTopic(forum.topic)
|
const palette = this.forum.parsePaletteFromTopic(forum.topic)
|
||||||
const postTags = this.forum.normalizePostTags(
|
const postTags = this.forum.normalizePostTags(
|
||||||
(tags || []).filter((t) => !palette.length || palette.includes(t))
|
(tags || []).filter((t) => !palette.length || palette.includes(t))
|
||||||
@@ -10701,19 +10705,25 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
targetId: thread.id
|
targetId: thread.id
|
||||||
})
|
})
|
||||||
this.emit('channel', merged)
|
this.emit('channel', merged)
|
||||||
span.end({ threadId: thread.id, tagCount: postTags.length })
|
span.end({ guildId, threadId: thread.id, tagCount: postTags.length })
|
||||||
return { thread: { ...merged, tags: postTags }, message }
|
return { thread: { ...merged, tags: postTags }, message }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error('forum.post error', {
|
this.log.error('forum.post error', {
|
||||||
|
guildId,
|
||||||
title: String(title || '').trim().slice(0, 64) || null,
|
title: String(title || '').trim().slice(0, 64) || null,
|
||||||
err: err?.message || String(err)
|
err: err?.message || String(err)
|
||||||
})
|
})
|
||||||
|
span.fail(err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createThread ({ messageId, name }) {
|
async createThread ({ messageId, name }) {
|
||||||
const span = this.log.time('thread.create', { messageId: messageId || null })
|
const guildId = this.guild?.guild?.id || null
|
||||||
|
const span = this.log.time('thread.create', {
|
||||||
|
guildId,
|
||||||
|
messageId: messageId || null
|
||||||
|
})
|
||||||
try {
|
try {
|
||||||
if (!this.guild?.guild || !this.activeChannelId) throw new Error('no active text channel')
|
if (!this.guild?.guild || !this.activeChannelId) throw new Error('no active text channel')
|
||||||
const parent = await this.db.get(COLLECTIONS.CHANNELS, {
|
const parent = await this.db.get(COLLECTIONS.CHANNELS, {
|
||||||
@@ -10741,13 +10751,15 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
})
|
})
|
||||||
this.selectChannel(thread.id)
|
this.selectChannel(thread.id)
|
||||||
this.emit('channel', thread)
|
this.emit('channel', thread)
|
||||||
span.end({ threadId: thread.id, parentId: parent.id })
|
span.end({ guildId, threadId: thread.id, parentId: parent.id })
|
||||||
return thread
|
return thread
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error('thread.create error', {
|
this.log.error('thread.create error', {
|
||||||
|
guildId,
|
||||||
messageId: messageId || null,
|
messageId: messageId || null,
|
||||||
err: err?.message || String(err)
|
err: err?.message || String(err)
|
||||||
})
|
})
|
||||||
|
span.fail(err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10841,7 +10853,12 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async archiveThread (threadId, archived = true) {
|
async archiveThread (threadId, archived = true) {
|
||||||
const span = this.log.time('thread.archive', { threadId, archived: !!archived })
|
const guildId = this.guild?.guild?.id || null
|
||||||
|
const span = this.log.time('thread.archive', {
|
||||||
|
guildId,
|
||||||
|
threadId,
|
||||||
|
archived: !!archived
|
||||||
|
})
|
||||||
try {
|
try {
|
||||||
if (!this.guild?.guild) throw new Error('no guild')
|
if (!this.guild?.guild) throw new Error('no guild')
|
||||||
const channels = await this.guild.listChannels()
|
const channels = await this.guild.listChannels()
|
||||||
@@ -10854,14 +10871,51 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
targetId: threadId
|
targetId: threadId
|
||||||
})
|
})
|
||||||
this.emit('channel-update', merged)
|
this.emit('channel-update', merged)
|
||||||
span.end({ threadId, archived: !!archived })
|
span.end({ guildId, threadId, archived: !!archived })
|
||||||
return merged
|
return merged
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error('thread.archive error', {
|
this.log.error('thread.archive error', {
|
||||||
|
guildId,
|
||||||
threadId,
|
threadId,
|
||||||
archived: !!archived,
|
archived: !!archived,
|
||||||
err: err?.message || String(err)
|
err: err?.message || String(err)
|
||||||
})
|
})
|
||||||
|
span.fail(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteChannel (channelId) {
|
||||||
|
const guildId = this.guild?.guild?.id || null
|
||||||
|
const span = this.log.time('channel.delete', { guildId, channelId: channelId || null })
|
||||||
|
try {
|
||||||
|
if (!this.guild) throw new Error('no guild')
|
||||||
|
if (!(await this._hasPerm(PERMISSION.MANAGE_CHANNELS))) {
|
||||||
|
throw new Error('no permission to delete channels')
|
||||||
|
}
|
||||||
|
const deletedId = String(channelId || '')
|
||||||
|
const wasActive = this.activeChannelId === deletedId
|
||||||
|
const payload = await this.guild.deleteChannel(deletedId)
|
||||||
|
this.guild.gossipChannelDelete(payload)
|
||||||
|
this._invalidateSearchCache()
|
||||||
|
if (wasActive) {
|
||||||
|
const channels = await this.guild.listChannels()
|
||||||
|
await this._selectGuildChannelWithUnread(channels)
|
||||||
|
}
|
||||||
|
await this._audit('channel.delete', {
|
||||||
|
guildId: this.guild.guild.id,
|
||||||
|
targetId: deletedId
|
||||||
|
})
|
||||||
|
this.emit('channel-delete', payload)
|
||||||
|
span.end({ guildId, channelId: deletedId })
|
||||||
|
return payload
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error('channel.delete error', {
|
||||||
|
guildId,
|
||||||
|
channelId: channelId || null,
|
||||||
|
err: err?.message || String(err)
|
||||||
|
})
|
||||||
|
span.fail(err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user