Skip to content

Commit 2fe10ae

Browse files
authored
feat: allow /thread to be used in completed threads (#128)
1 parent fc162a5 commit 2fe10ae

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

src/commands/thread.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import assert from 'assert'
12
import { ChannelType, ThreadChannel } from 'discord.js'
23
import { SlashCommand, SlashCreator, CommandContext } from 'slash-create'
34
import { commandLog } from '../communication/interaction'
@@ -6,7 +7,7 @@ import {
67
updateFeedbackThreadId,
78
validatePendingSubmission
89
} from '../db/submission'
9-
import { fetchSubmissionForContext } from '../utils/commands'
10+
import { fetchAnySubmissionForContext } from '../utils/commands'
1011
import { getAssignedGuilds } from '../utils/discordUtils'
1112
import { runCatching } from '../utils/request'
1213

@@ -21,14 +22,17 @@ export default class ThreadCommand extends SlashCommand {
2122
}
2223

2324
async run (ctx: CommandContext): Promise<void> {
24-
const submission = await fetchSubmissionForContext(ctx)
25+
const submission = await fetchAnySubmissionForContext(ctx)
2526

2627
if (!submission) {
2728
return
2829
}
2930

3031
let existingThread: ThreadChannel | undefined
3132

33+
// Running commands in a thread with a raw submission should be impossible
34+
assert(submission.state !== 'RAW', 'submission was in raw state')
35+
3236
if (submission.state === 'ERROR') {
3337
commandLog.warning({
3438
type: 'text',
@@ -39,6 +43,21 @@ export default class ThreadCommand extends SlashCommand {
3943
return
4044
}
4145

46+
if (submission.state === 'ACCEPTED' || submission.state === 'DENIED') {
47+
const { feedbackThread } = submission
48+
if (!feedbackThread) {
49+
commandLog.warning({
50+
type: 'text',
51+
content:
52+
'Cannot add you, no thread exists.',
53+
ctx
54+
})
55+
return
56+
}
57+
58+
existingThread = feedbackThread
59+
}
60+
4261
if (submission.state === 'PROCESSING' || submission.state === 'PAUSED') {
4362
// Allow thread creation in paused state, as reviewers may need to contact submitters about warnings
4463
existingThread = submission.feedbackThread
@@ -85,6 +104,10 @@ export default class ThreadCommand extends SlashCommand {
85104
}),
86105
'rethrow'
87106
)
107+
108+
// We checked for the states above, this just lets TS infer it so we don't have any casting.
109+
assert(submission.state === 'PROCESSING' || submission.state === 'PAUSED' || submission.state === 'WARNING', 'impossible')
110+
88111
await updateFeedbackThreadId(submission, feedbackThread.id)
89112

90113
await runCatching(

src/db/submission.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ export async function fetchSubmissionByMessageId (
212212
// from button votes, whereby the author must exist
213213
const author = await fetchAuthor(data.authorId)
214214

215+
// May or may not exist, do not abort if it does not
216+
let feedbackThread
217+
if (data.feedbackThreadId) {
218+
try {
219+
feedbackThread = await fetchFeedbackThread(data.feedbackThreadId)
220+
} catch {
221+
logger.warn(`Feedback thread for submission (message ID ${id}) did not exist`)
222+
}
223+
}
224+
215225
const completed: CompletedSubmission = {
216226
...data,
217227
state: data.state,
@@ -221,7 +231,8 @@ export async function fetchSubmissionByMessageId (
221231
source: data.sourceLinks,
222232
other: data.otherLinks
223233
},
224-
author
234+
author,
235+
feedbackThread
225236
}
226237

227238
return completed
@@ -385,11 +396,12 @@ async function resolvePrismaData (
385396

386397
logger.trace('API requests successful')
387398

388-
const submission: AnySubmission = {
399+
const submission = {
389400
...data,
390401
state: data.state,
391402

392403
feedbackThread,
404+
author: undefined,
393405
tech: data.techUsed,
394406
links: {
395407
other: data.otherLinks,

src/types/submission.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ export interface CompletedSubmission extends BaseSubmission {
7676
id: Cuid
7777
submittedAt: Date
7878

79-
// Author may no longer exist when we fetch in this state
80-
author?: GuildMember
79+
// Author / thread may no longer exist when we fetch in this state
80+
author: GuildMember | undefined
81+
feedbackThread: ThreadChannel | undefined
8182
}
8283

8384
// These type guards exist for more readable code, and better TS behavior

src/utils/commands.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,43 @@
11
import { CommandContext } from 'slash-create'
22
import { commandLog } from '../communication/interaction'
33
import { internalLog } from '../communication/internal'
4-
import { fetchSubmissionByThreadId } from '../db/submission'
5-
import { PendingSubmission, ValidatedSubmission } from '../types/submission'
4+
import { fetchAnySubmissionByThreadId, fetchSubmissionByThreadId } from '../db/submission'
5+
import { AnySubmission, PendingSubmission, ValidatedSubmission } from '../types/submission'
6+
7+
/**
8+
* Fetches the submission for the given command context.
9+
* This does NOT validate the state of the submission in any way
10+
* This relies on the thread ID to perform the lookup.
11+
*/
12+
export async function fetchAnySubmissionForContext (ctx: CommandContext): Promise<AnySubmission | undefined> {
13+
const id = ctx.channelID
14+
15+
if (!id) {
16+
return void commandLog.error({
17+
type: 'text',
18+
content: 'Interaction came with no thread ID.',
19+
ctx
20+
})
21+
}
22+
23+
const submission = await fetchAnySubmissionByThreadId(id)
24+
25+
if (!submission) {
26+
commandLog.error({
27+
type: 'text',
28+
content: `Could not look up submission for channel ID ${id}`,
29+
ctx
30+
})
31+
32+
return void internalLog.error({
33+
type: 'text',
34+
content: `Could not look up submission for channel ID ${id}`,
35+
ctx: undefined
36+
})
37+
}
38+
39+
return submission
40+
}
641

742
/**
843
* Fetches the submission for the given command context.

0 commit comments

Comments
 (0)