-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueries.ts
More file actions
109 lines (95 loc) · 2.83 KB
/
Copy pathqueries.ts
File metadata and controls
109 lines (95 loc) · 2.83 KB
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
import {
FormQuestionOption,
formQuestions,
forms,
services,
} from "@/lib/db/schema";
import { cacheTag } from "next/cache";
import { db } from "@/lib/db";
import { asc, count, desc, eq, sql } from "drizzle-orm";
export type FormQuestionType = "text" | "multiple_choices" | "checkboxes" | "user_agreement";
export type QuestionView = {
id: string;
sortOrder: number;
type: FormQuestionType;
prompt: string;
options: FormQuestionOption[] | null;
}
export type FormListItem = {
id: string;
name: string;
questionCount: number;
attachedServiceCount: number;
createdAt: Date;
updatedAt: Date;
}
export type FormView = FormListItem & {
questions: QuestionView[];
};
const FORMS_TAG = "forms";
export async function listForms(): Promise<FormListItem[]> {
"use cache";
cacheTag(FORMS_TAG);
const rows = await db
.select({
id: forms.id,
name: forms.name,
createdAt: forms.createdAt,
updatedAt: forms.updatedAt,
questionCount: sql<number>`cast(count(distinct ${formQuestions.id}) as integer)`,
attachedServiceCount: sql<number>`cast(count(distinct ${services.id}) as integer)`,
})
.from(forms)
.leftJoin(formQuestions, eq(formQuestions.formId, forms.id))
.leftJoin(services, eq(services.formId, forms.id))
.groupBy(forms.id, forms.name, forms.createdAt, forms.updatedAt)
.orderBy(desc(forms.createdAt));
return rows.map((row) => ({
id: row.id,
name: row.name,
questionCount: Number(row.questionCount),
attachedServiceCount: Number(row.attachedServiceCount),
createdAt: row.createdAt,
updatedAt: row.updatedAt,
}));
}
export async function getForm(id: string): Promise<FormView | null> {
"use cache";
cacheTag(FORMS_TAG);
const [form] = await db
.select()
.from(forms)
.where(eq(forms.id, id))
.limit(1);
if (!form) return null;
const questionRows = await db
.select({
id: formQuestions.id,
sortOrder: formQuestions.sortOrder,
type: formQuestions.type,
prompt: formQuestions.prompt,
options: formQuestions.options,
})
.from(formQuestions)
.where(eq(formQuestions.formId, id))
.orderBy(asc(formQuestions.sortOrder));
const [serviceRow] = await db
.select({ count: count() })
.from(services)
.where(eq(services.formId, id));
return {
id: form.id,
name: form.name,
questionCount: questionRows.length,
attachedServiceCount: serviceRow?.count ?? 0,
createdAt: form.createdAt,
updatedAt: form.updatedAt,
questions: questionRows.map((q) => ({
id: q.id,
sortOrder: q.sortOrder,
type: q.type,
prompt: q.prompt,
options: q.options ?? null,
})),
};
}