+149
apps/web/src/features/db/server/seed/data.ts
+149
apps/web/src/features/db/server/seed/data.ts
···
1
+
import type { InferSelectModel } from 'drizzle-orm';
2
+
import type { report } from '$features/db/server/schema';
3
+
4
+
import {
5
+
type InsertReportWithRelations,
6
+
type InsertContextWithRelations,
7
+
MediaType,
8
+
ContextType,
9
+
type InsertMedia,
10
+
} from '$features/db/types';
11
+
12
+
export type SeedData = {
13
+
reports: InsertReportWithRelations<InsertContextWithRelations>[];
14
+
};
15
+
16
+
const imageMedia = (media: Omit<InsertMedia, 'type'>) => {
17
+
return {
18
+
type: MediaType.image,
19
+
...media,
20
+
};
21
+
};
22
+
23
+
export const seedData: SeedData = {
24
+
reports: [
25
+
{
26
+
context: [
27
+
{
28
+
type: ContextType.root,
29
+
text: 'ICE activity spotted in area',
30
+
location: {
31
+
latitude: '34.7724',
32
+
longitude: '-84.9819',
33
+
},
34
+
media: [
35
+
imageMedia({
36
+
url: 'https://plus.unsplash.com/premium_photo-1687157829884-fae305709c06?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=900',
37
+
altText:
38
+
'A cop car with its lights on and a city building in the background, out of focus.',
39
+
}),
40
+
imageMedia({
41
+
url: 'https://plus.unsplash.com/premium_photo-1686695196013-b0e9aef9cdff?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTN8fHBvbGljZXxlbnwwfHwwfHx8MA%3D%3D&auto=format&fit=crop&q=60&w=900',
42
+
altText:
43
+
'A cop with a stupidly smug face sitting on a motorcycle being useless and cruel.',
44
+
}),
45
+
imageMedia({
46
+
url: 'https://images.unsplash.com/photo-1652793806995-7bf3265e40b0?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1760',
47
+
altText: 'Two Toronto police cars',
48
+
}),
49
+
imageMedia({
50
+
url: 'https://images.unsplash.com/photo-1590995891215-0336d27411de?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
51
+
altText:
52
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
53
+
}),
54
+
imageMedia({
55
+
url: 'https://images.unsplash.com/photo-1591073214708-44d56a561981?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
56
+
altText:
57
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
58
+
}),
59
+
imageMedia({
60
+
url: 'https://images.unsplash.com/photo-1520085401243-fa89fc9ff1b7?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1642',
61
+
altText:
62
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
63
+
}),
64
+
imageMedia({
65
+
url: 'https://images.unsplash.com/photo-1758405282251-26903f4b7fcb?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
66
+
altText:
67
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
68
+
}),
69
+
imageMedia({
70
+
url: 'https://images.unsplash.com/photo-1758405282247-86deca3ecc87?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
71
+
altText:
72
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
73
+
}),
74
+
imageMedia({
75
+
url: 'https://images.unsplash.com/photo-1686153957738-fed649408234?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1762',
76
+
altText:
77
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
78
+
}),
79
+
],
80
+
},
81
+
{
82
+
type: ContextType.info,
83
+
text: 'a protester was just kidnapped by ICE, please protect yourself and stay aware of your surroundings at all times in this area.',
84
+
location: {},
85
+
media: [
86
+
imageMedia({
87
+
url: 'https://plus.unsplash.com/premium_photo-1683134562864-1670a96e3022?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
88
+
altText: 'person being detained by masked ICE thugs',
89
+
}),
90
+
],
91
+
},
92
+
],
93
+
},
94
+
{
95
+
context: [
96
+
{
97
+
type: ContextType.root,
98
+
location: {
99
+
latitude: '34.76803247376194',
100
+
longitude: '-84.97822846789504',
101
+
},
102
+
media: [
103
+
imageMedia({
104
+
url: 'https://images.unsplash.com/photo-1590995891215-0336d27411de?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
105
+
altText:
106
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
107
+
}),
108
+
imageMedia({
109
+
url: 'https://images.unsplash.com/photo-1591073214708-44d56a561981?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
110
+
altText:
111
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
112
+
}),
113
+
imageMedia({
114
+
url: 'https://images.unsplash.com/photo-1520085401243-fa89fc9ff1b7?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1642',
115
+
altText:
116
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
117
+
}),
118
+
imageMedia({
119
+
url: 'https://images.unsplash.com/photo-1758405282251-26903f4b7fcb?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
120
+
altText:
121
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
122
+
}),
123
+
imageMedia({
124
+
url: 'https://images.unsplash.com/photo-1758405282247-86deca3ecc87?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
125
+
altText:
126
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
127
+
}),
128
+
imageMedia({
129
+
url: 'https://images.unsplash.com/photo-1686153957738-fed649408234?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1762',
130
+
altText:
131
+
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Hic, consequuntur incidunt non, fugiat debitis quas atque porro quia necessitatibus facere ut molestiae amet, a nisi temporibus unde sequi. At, nam.',
132
+
}),
133
+
],
134
+
},
135
+
{
136
+
type: ContextType.info,
137
+
text: 'a protester was just kidnapped by ICE, please protect yourself and stay aware of your surroundings at all times in this area.',
138
+
location: {},
139
+
media: [
140
+
imageMedia({
141
+
url: 'https://plus.unsplash.com/premium_photo-1683134562864-1670a96e3022?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740',
142
+
altText: 'person being detained by masked ICE thugs',
143
+
}),
144
+
],
145
+
},
146
+
],
147
+
},
148
+
],
149
+
};
+61
apps/web/src/features/db/server/seed/index.ts
+61
apps/web/src/features/db/server/seed/index.ts
···
1
+
import { db } from '$features/db/server';
2
+
import type { SelectedLocation } from '$features/db/types';
3
+
import {
4
+
context as contextTable,
5
+
location as locationTable,
6
+
report as reportTable,
7
+
media as mediaTable,
8
+
} from '../schema';
9
+
import { seedData } from './data';
10
+
11
+
interface Omit {
12
+
<T extends object, K extends [...(keyof T)[]]>(
13
+
obj: T,
14
+
...keys: K
15
+
): {
16
+
[K2 in Exclude<keyof T, K[number]>]: T[K2];
17
+
};
18
+
}
19
+
20
+
const omit: Omit = (obj, ...keys) => {
21
+
const ret = {} as {
22
+
[K in keyof typeof obj]: (typeof obj)[K];
23
+
};
24
+
let key: keyof typeof obj;
25
+
for (key in obj) {
26
+
if (!keys.includes(key)) {
27
+
ret[key] = obj[key];
28
+
}
29
+
}
30
+
return ret;
31
+
};
32
+
33
+
export const seedDatabase = async () => {
34
+
await db.transaction(async (tx) => {
35
+
for (const { context: contextItems, ...reportData } of seedData.reports) {
36
+
const parentReport = await tx.insert(reportTable).values(reportData).returning();
37
+
38
+
for (const { media: mediaItems, location: locationData, ...contextData } of contextItems) {
39
+
// const contextLocation = !!locationData?.latitude ? await tx.insert(locationTable).values() : undefined;
40
+
let contextLocation: SelectedLocation[] | undefined = undefined;
41
+
42
+
if (!!locationData?.latitude && !!locationData?.longitude) {
43
+
contextLocation = await tx.insert(locationTable).values(locationData).returning();
44
+
}
45
+
46
+
const parentContext = await tx
47
+
.insert(contextTable)
48
+
.values({
49
+
...contextData,
50
+
locationId: contextLocation?.[0].id,
51
+
reportId: parentReport[0].id,
52
+
})
53
+
.returning();
54
+
55
+
for (const mediaData of mediaItems) {
56
+
await tx.insert(mediaTable).values({ ...mediaData, contextId: parentContext[0].id });
57
+
}
58
+
}
59
+
}
60
+
});
61
+
};
-9
apps/web/src/routes/api/reports/+server.ts
-9
apps/web/src/routes/api/reports/+server.ts
+33
apps/web/src/routes/api/seed/+server.ts
+33
apps/web/src/routes/api/seed/+server.ts
···
1
+
import { json } from '@sveltejs/kit';
2
+
import { seedDatabase } from '$features/db/server/seed';
3
+
import { SEEDING_ENABLED } from '$env/static/private';
4
+
5
+
// getReports
6
+
export const GET = async () => {
7
+
if (!SEEDING_ENABLED)
8
+
return json(
9
+
{
10
+
error: 'nope',
11
+
},
12
+
{ status: 403 }
13
+
);
14
+
15
+
try {
16
+
await seedDatabase();
17
+
return json(
18
+
{
19
+
success: true,
20
+
},
21
+
{ status: 200 }
22
+
);
23
+
} catch (e) {
24
+
if (e instanceof Error) {
25
+
return json(
26
+
{
27
+
error: e?.message ?? 'Unable to seed data',
28
+
},
29
+
{ status: 500 }
30
+
);
31
+
}
32
+
}
33
+
};