-
Notifications
You must be signed in to change notification settings - Fork 1
/
options.ts
188 lines (155 loc) · 5.07 KB
/
options.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import { eq, getTableColumns } from 'drizzle-orm';
import type { Request, Response } from 'express';
import * as schema from '../db/schema';
import { getOptionUsers, getOptionComments } from '../services/comments';
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { logger } from '../utils/logger';
import { insertOptionsSchema } from '../types';
import { isUserIsPartOfGroup } from '../services/groups';
import {
getUserOption,
saveOption,
updateOption,
canUserCreateOption,
validateOptionData,
} from '../services/options';
export function getOptionHandler(dbPool: NodePgDatabase<typeof schema>) {
return async function (req: Request, res: Response) {
const { optionId } = req.params;
if (!optionId) {
return res.status(400).json({ error: 'Missing optionId' });
}
const { voteScore, ...rest } = getTableColumns(schema.options);
const rows = await dbPool
.select({
...rest,
})
.from(schema.options)
.where(eq(schema.options.id, optionId));
if (!rows.length) {
return res.status(404).json({ error: 'Option not found' });
}
return res.json({ data: rows[0] });
};
}
/**
* Retrieves comments related to a specific question option from the database and associates them with corresponding user information.
*/
export function getOptionCommentsHandler(dbPool: NodePgDatabase<typeof schema>) {
return async function (req: Request, res: Response) {
const optionId = req.params.optionId ?? '';
try {
const commentsWithUserNames = await getOptionComments(dbPool, { optionId });
return res.json({ data: commentsWithUserNames });
} catch (error) {
logger.error('Error getting comments: ', error);
return res.sendStatus(500);
}
};
}
/**
* Retrieves author and co-author data for a given question option created as a secret group.
*/
export function getOptionUsersHandler(dbPool: NodePgDatabase<typeof schema>) {
return async function (req: Request, res: Response) {
try {
const optionId = req.params.optionId;
// Check if optionId is provided
if (!optionId) {
return res.status(400).json({ error: 'Missing optionId parameter' });
}
// Execute queries
const responseData = await getOptionUsers(optionId, dbPool);
// Send response
return res.status(200).json({ data: responseData });
} catch (error) {
logger.error('Error in getOptionUsers:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
};
}
export function saveOptionHandler(dbPool: NodePgDatabase<typeof schema>) {
return async function (req: Request, res: Response) {
const userId = req.session.userId;
const body = insertOptionsSchema.safeParse(req.body);
if (!body.success) {
return res.status(400).json({ errors: body.error.issues });
}
const brokenRules = await validateOptionData({
dbPool,
option: body.data,
});
if (brokenRules.length > 0) {
return res.status(400).json({ errors: brokenRules });
}
const userCanCreate = await canUserCreateOption({
dbPool,
option: body.data,
});
if (!userCanCreate) {
return res.status(401).json({ errors: ['User can not create this option'] });
}
const userIsPartOfGroup = await isUserIsPartOfGroup({
dbPool,
userId,
groupId: body.data.groupId,
});
if (!userIsPartOfGroup) {
return res.status(400).json({ errors: ['Can not register for this group'] });
}
try {
const out = await saveOption(dbPool, body.data);
return res.json({ data: out });
} catch (e) {
logger.error('error saving option ' + e);
return res.sendStatus(500);
}
};
}
export function updateOptionHandler(dbPool: NodePgDatabase<typeof schema>) {
return async function (req: Request, res: Response) {
const optionId = req.params.optionId;
if (!optionId) {
return res.status(400).json({ errors: ['optionId is required'] });
}
const userId = req.session.userId;
const body = insertOptionsSchema.safeParse(req.body);
if (!body.success) {
return res.status(400).json({ errors: body.error.issues });
}
const brokenRules = await validateOptionData({
dbPool,
option: body.data,
});
if (brokenRules.length > 0) {
return res.status(400).json({ errors: brokenRules });
}
const userIsPartOfGroup = await isUserIsPartOfGroup({
dbPool,
userId,
groupId: body.data.groupId,
});
if (!userIsPartOfGroup) {
return res.status(400).json({ errors: ['Can not register for this group'] });
}
const existingOption = await getUserOption({
dbPool,
optionId,
userId,
});
if (!existingOption) {
return res.status(400).json({ errors: ['Cannot update this option'] });
}
try {
const out = await updateOption({
data: body.data,
option: existingOption,
dbPool,
});
return res.json({ data: out });
} catch (e) {
logger.error('error saving option ' + e);
return res.sendStatus(500);
}
};
}