Skip to content

Commit afcae29

Browse files
committed
first draft schema
1 parent cd0815b commit afcae29

1 file changed

Lines changed: 110 additions & 6 deletions

File tree

convex/schema.ts

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,113 @@
1-
import { defineSchema } from "convex/server";
1+
// convex/schema.ts
2+
import { defineSchema, defineTable } from "convex/server";
23
import { authTables } from "@convex-dev/auth/server";
3-
4-
const schema = defineSchema({
4+
import { v } from "convex/values";
5+
6+
export default defineSchema({
57
...authTables,
6-
// Your other tables...
8+
9+
// raw email data
10+
listservEmails: defineTable({
11+
listserv: v.string(), // listserv name
12+
sentAt: v.number(), // timestamp
13+
fromAddress: v.optional(v.string()), // listserv email address
14+
rawHtml: v.optional(v.string()),
15+
rawText: v.optional(v.string()),
16+
section: v.optional(v.string()), // "On-Campus", "Off-Campus", "Opportunities"
17+
}).index("by_listserv", ["listserv"]),
18+
19+
// One row per listserv item
20+
events: defineTable({
21+
listservEmailId: v.id("listservEmails"), // link to the listserv email data
22+
listserv: v.string(),
23+
listservSection: v.string(),
24+
25+
title: v.string(),
26+
description: v.string(),
27+
eventType: v.union(
28+
v.literal("event"), // one-time event
29+
v.literal("opportunity"), // internship, job, program, application
30+
v.literal("hackathon"),
31+
v.literal("courses"), // workshop series / class series
32+
v.literal("fundraiser"),
33+
v.literal("info"), // announcements with no clear CTA, catch-all
34+
),
35+
36+
// ex. WICC x Jane Street, AppDev x Ramp, etc.
37+
hostClub: v.string(), // primary org (maps to a clubs table eventually)
38+
coHosts: v.array(v.string()), // ["Ramp"], [] if none
39+
40+
dates: v.array(
41+
v.object({
42+
timestamp: v.number(),
43+
type: v.union(
44+
v.literal("start"), // start & end for recurring events
45+
v.literal("end"),
46+
v.literal("deadline"),
47+
v.literal("single"), // one-off event with no end
48+
),
49+
}),
50+
),
51+
isRecurring: v.boolean(),
52+
recurrenceNote: v.optional(v.string()), // "Every Wednesday 5-6:30pm"
53+
54+
location: v.optional(
55+
v.object({
56+
displayText: v.string(),
57+
address: v.optional(v.string()),
58+
isVirtual: v.boolean(),
59+
buildingCode: v.optional(v.string()), // "Gates 114", "CIS 250"
60+
}),
61+
),
62+
63+
links: v.array(
64+
v.object({
65+
url: v.string(),
66+
type: v.union(
67+
v.literal("registration"), // more for courses, hackathons, etc.
68+
v.literal("application"), // internships, jobs, programs
69+
v.literal("rsvp"), // events with physical link (decide if combines with registration)
70+
v.literal("info"), // general info, websites, etc.
71+
v.literal("social"), // instagram, etc.
72+
),
73+
label: v.optional(v.string()), // "Apply here", "RSVP Link"
74+
}),
75+
),
76+
77+
contacts: v.array(
78+
v.object({
79+
type: v.union(
80+
v.literal("email"),
81+
v.literal("instagram"),
82+
v.literal("website"),
83+
),
84+
value: v.string(),
85+
}),
86+
),
87+
88+
tags: v.array(v.string()),
89+
targetAudience: v.optional(
90+
v.union( // decide if we need all or define more
91+
v.literal("all"),
92+
v.literal("first_year"),
93+
v.literal("women_nonbinary"),
94+
v.literal("international"),
95+
v.literal("graduate"),
96+
),
97+
),
98+
perks: v.array(
99+
v.union(
100+
v.literal("food"),
101+
v.literal("swag"),
102+
v.literal("prizes"),
103+
v.literal("travel_covered"),
104+
v.literal("paid"),
105+
),
106+
),
107+
108+
})
109+
.index("by_listserv", ["listserv"])
110+
.index("by_section", ["listservSection"])
111+
.index("by_event_type", ["eventType"])
112+
.index("by_host", ["hostClub"]),
7113
});
8-
9-
export default schema;

0 commit comments

Comments
 (0)