diff --git a/apps/blade/src/app/_components/issue-calendar/calendar-day-agenda.tsx b/apps/blade/src/app/_components/issue-calendar/calendar-day-agenda.tsx index 92098adaa..4a8174c35 100644 --- a/apps/blade/src/app/_components/issue-calendar/calendar-day-agenda.tsx +++ b/apps/blade/src/app/_components/issue-calendar/calendar-day-agenda.tsx @@ -49,7 +49,7 @@ function assigneeDisplayNames(issue: Issue): string[] { } function isOverdueIssue(issue: Issue) { - if (issue.status === "FINISHED" || !issue.date) return false; + if (issue.status === "Finished" || !issue.date) return false; const dueDate = new Date(issue.date); const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); @@ -68,6 +68,7 @@ export function IssueDayAgenda(props: { issues: Issue[]; isLoading: boolean; roleNameById: Map | undefined; + roleColorById: Map | undefined; onIssueSelect?: (issueId: string) => void; onIssuesChanged?: () => void; }) { @@ -76,6 +77,7 @@ export function IssueDayAgenda(props: { issues, isLoading, roleNameById, + roleColorById, onIssueSelect, onIssuesChanged, } = props; @@ -101,7 +103,7 @@ export function IssueDayAgenda(props: { const copyIssueLink = useCallback((issueId: string) => { const origin = typeof window !== "undefined" ? window.location.origin : ""; - const url = `${origin}/issues/${issueId}`; + const url = `${origin}/admin/issues/${issueId}`; void navigator.clipboard.writeText(url).then( () => { toast.success("Issue link copied"); @@ -171,6 +173,7 @@ export function IssueDayAgenda(props: { const teamsText = teams.join(" · "); const showTeamsBlock = teamsText.length > 0; const assigneeNames = assigneeDisplayNames(issue); + const teamColor = roleColorById?.get(issue.team) ?? null; const assigneesText = assigneeNames.length > 0 ? assigneeNames.join(" · ") @@ -180,6 +183,14 @@ export function IssueDayAgenda(props: {
  • diff --git a/apps/blade/src/app/_components/issue-calendar/calendar-issue-dialog.tsx b/apps/blade/src/app/_components/issue-calendar/calendar-issue-dialog.tsx index 8108921af..1af3ad6f3 100644 --- a/apps/blade/src/app/_components/issue-calendar/calendar-issue-dialog.tsx +++ b/apps/blade/src/app/_components/issue-calendar/calendar-issue-dialog.tsx @@ -43,7 +43,7 @@ function isIssueOverdue( status: GetIssueResult["status"], date: Date | string | null | undefined, ) { - if (status === "FINISHED" || !date) return false; + if (status === "Finished" || !date) return false; const dueDate = new Date(date); const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); @@ -113,7 +113,7 @@ export function CalendarIssueDialog({ async function handleCopyIssueUrl() { if (!issue || typeof window === "undefined") return; - const url = `${window.location.origin}/issues/${issue.id}`; + const url = `${window.location.origin}/admin/issues/${issue.id}`; try { await navigator.clipboard.writeText(url); toast.success("Issue link copied"); @@ -146,7 +146,7 @@ export function CalendarIssueDialog({ asChild > {issue.name} diff --git a/apps/blade/src/app/_components/issue-calendar/calendar-status-dot-legend.tsx b/apps/blade/src/app/_components/issue-calendar/calendar-status-dot-legend.tsx index 2eec2b5ea..f0da1799c 100644 --- a/apps/blade/src/app/_components/issue-calendar/calendar-status-dot-legend.tsx +++ b/apps/blade/src/app/_components/issue-calendar/calendar-status-dot-legend.tsx @@ -4,10 +4,10 @@ import { ISSUE } from "@forge/consts"; const STATUS_LEGEND_LABEL: Record<(typeof ISSUE.ISSUE_STATUS)[number], string> = { - BACKLOG: "Backlog", - PLANNING: "Planning", - IN_PROGRESS: "In Progress", - FINISHED: "Finished", + Backlog: "Backlog", + Planning: "Planning", + "In Progress": "In Progress", + Finished: "Finished", }; export function IssueStatusDotLegend() { diff --git a/apps/blade/src/app/_components/issue-calendar/calendar.tsx b/apps/blade/src/app/_components/issue-calendar/calendar.tsx index b3389006b..60f465c96 100644 --- a/apps/blade/src/app/_components/issue-calendar/calendar.tsx +++ b/apps/blade/src/app/_components/issue-calendar/calendar.tsx @@ -23,16 +23,9 @@ import { import dayGridPlugin from "@fullcalendar/daygrid"; import interactionPlugin from "@fullcalendar/interaction"; import FullCalendar from "@fullcalendar/react"; -import { - CheckCircle2, - ChevronLeft, - ChevronRight, - CircleDot, - SlidersHorizontal, -} from "lucide-react"; +import { ChevronLeft, ChevronRight } from "lucide-react"; import { ISSUE } from "@forge/consts"; -import { cn } from "@forge/ui"; import { Button } from "@forge/ui/button"; import { Tabs, TabsList, TabsTrigger } from "@forge/ui/tabs"; import { toast } from "@forge/ui/toast"; @@ -40,7 +33,10 @@ import { toast } from "@forge/ui/toast"; import { api } from "~/trpc/react"; import { CreateEditDialog } from "../issues/create-edit-dialog"; import { IssueFetcherPane } from "../issues/issue-fetcher-pane"; -import IssueTemplateDialog from "../issues/issue-template-dialog"; +import { + getActiveIssueFilterTags, + IssueViewControlBar, +} from "../issues/issue-view-control-bar"; import { IssueDayAgenda } from "./calendar-day-agenda"; import { CalendarIssueDialog } from "./calendar-issue-dialog"; import { IssueStatusDotLegend } from "./calendar-status-dot-legend"; @@ -56,6 +52,16 @@ function issueStatusLabel(status: IssueCalendarStatus) { .join(" "); } +function calendarEventTextColor(backgroundColor: string) { + const hex = backgroundColor.replace("#", ""); + if (!/^[0-9a-fA-F]{6}$/.test(hex)) return "#ffffff"; + const r = parseInt(hex.slice(0, 2), 16); + const g = parseInt(hex.slice(2, 4), 16); + const b = parseInt(hex.slice(4, 6), 16); + const yiq = (r * 299 + g * 587 + b * 114) / 1000; + return yiq >= 160 ? "#111827" : "#ffffff"; +} + function startOfLocalDay(isoOrDate: Date): Date { const d = new Date(isoOrDate); return new Date(d.getFullYear(), d.getMonth(), d.getDate()); @@ -124,13 +130,6 @@ function dismissFullCalendarMorePopovers() { }); } -function formatStatus(status: string) { - return status - .toLowerCase() - .replace(/_/g, " ") - .replace(/\b\w/g, (char) => char.toUpperCase()); -} - export default function CalendarView() { const calendarRef = useRef(null); const calendarSectionRef = useRef(null); @@ -172,7 +171,7 @@ export default function CalendarView() { }, [paneData, rawPaneIssues, deferredPaneIssues]); const openCount = useMemo( - () => rawPaneIssues.filter((issue) => issue.status !== "FINISHED").length, + () => rawPaneIssues.filter((issue) => issue.status !== "Finished").length, [rawPaneIssues], ); const closedCount = rawPaneIssues.length - openCount; @@ -180,22 +179,8 @@ export default function CalendarView() { const filters = paneData?.filters; const activeFilters = useMemo(() => { - if (!filters) return []; - const tags: string[] = []; - if (filters.statusFilter !== "all") - tags.push(formatStatus(filters.statusFilter)); - if (filters.teamFilter !== "all") tags.push("Team selected"); - if (filters.issueKind !== "all") - tags.push( - filters.issueKind === "task" ? "Tasks only" : "Event-linked only", - ); - if (filters.rootOnly) tags.push("Root only"); - if (filters.dateFrom) tags.push("From " + filters.dateFrom); - if (filters.dateTo) tags.push("To " + filters.dateTo); - if (filters.searchTerm.trim()) - tags.push('Search "' + filters.searchTerm.trim() + '"'); - return tags; - }, [filters]); + return getActiveIssueFilterTags(filters, paneData?.roleNameById); + }, [filters, paneData?.roleNameById]); const issuesForCurrentView = useMemo(() => { if (view === "issueDayAgenda") { @@ -236,10 +221,18 @@ export default function CalendarView() { return issuesForCurrentView.flatMap((issue): EventInput[] => { if (!issue.date) return []; const d = new Date(issue.date); + const teamColor = paneData?.roleColorById.get(issue.team) ?? null; + const eventPalette = teamColor + ? { + backgroundColor: teamColor, + borderColor: teamColor, + textColor: calendarEventTextColor(teamColor), + } + : {}; const baseClassNames = [ "calendar-issue", issue.event ? "calendar-issue--linked" : "calendar-issue--task", - ...(issue.status === "FINISHED" ? ["calendar-issue--finished"] : []), + ...(issue.status === "Finished" ? ["calendar-issue--finished"] : []), ] as string[]; const useAllDayBand = !issue.event && isDefaultTaskDueMoment(d); @@ -254,6 +247,7 @@ export default function CalendarView() { display: "block" as const, extendedProps: { issueStatus: issue.status }, classNames: baseClassNames, + ...eventPalette, }, ]; } @@ -269,10 +263,11 @@ export default function CalendarView() { display: "block" as const, extendedProps: { issueStatus: issue.status }, classNames: baseClassNames, + ...eventPalette, }, ]; }); - }, [view, issuesForCurrentView]); + }, [paneData?.roleColorById, view, issuesForCurrentView]); const fullCalendarViews = useMemo( () => ({ @@ -409,7 +404,7 @@ export default function CalendarView() { return undefined; } const ex = arg.event.extendedProps as { issueStatus?: IssueCalendarStatus }; - const status: IssueCalendarStatus = ex.issueStatus ?? "BACKLOG"; + const status: IssueCalendarStatus = ex.issueStatus ?? "Backlog"; const statusLabel = issueStatusLabel(status); return (
    + setIsFiltersOpen(true)} + /> +
    @@ -578,71 +583,6 @@ export default function CalendarView() {
    - -
    -
    0 - ? "md:flex-row md:items-start md:justify-between md:gap-6" - : "sm:flex-row sm:items-center sm:justify-between sm:gap-4 md:gap-6", - )} - > -
    -
    -
    - - {openCount} Open -
    -
    - - {closedCount} Closed -
    -
    - {activeFilters.length > 0 ? ( -
    - Active filters - {activeFilters.map((tag) => ( - - {tag} - - ))} -
    - ) : null} -
    - -
    - - - - - -
    -
    -
    @@ -688,6 +628,7 @@ export default function CalendarView() { issues={issuesForCurrentView} isLoading={paneData?.isLoading ?? true} roleNameById={paneData?.roleNameById} + roleColorById={paneData?.roleColorById} onIssueSelect={(issueId: string) => { setDetailIssueId(issueId); setIsDetailOpen(true); diff --git a/apps/blade/src/app/_components/issue-kanban/issues-kanban.tsx b/apps/blade/src/app/_components/issue-kanban/issues-kanban.tsx index 90aa65af4..1615a7659 100644 --- a/apps/blade/src/app/_components/issue-kanban/issues-kanban.tsx +++ b/apps/blade/src/app/_components/issue-kanban/issues-kanban.tsx @@ -2,22 +2,17 @@ import { useMemo, useState } from "react"; import Link from "next/link"; -import { - Calendar, - CheckCircle2, - CircleDot, - Pencil, - SlidersHorizontal, - Users, -} from "lucide-react"; +import { Calendar, Pencil, Users } from "lucide-react"; import { ISSUE } from "@forge/consts"; -import { Button } from "@forge/ui/button"; import { toast } from "@forge/ui/toast"; import { CreateEditDialog } from "~/app/_components/issues/create-edit-dialog"; import { IssueFetcherPane } from "~/app/_components/issues/issue-fetcher-pane"; -import IssueTemplateDialog from "~/app/_components/issues/issue-template-dialog"; +import { + getActiveIssueFilterTags, + IssueViewControlBar, +} from "~/app/_components/issues/issue-view-control-bar"; import { api } from "~/trpc/react"; const STATUS_COLORS: Record = { @@ -66,18 +61,20 @@ export function KanbanBoard() { onError: () => toast.error("Failed to update issue status"), }); - const issues = paneData?.issues - ? paneData.issues.map((issue) => ({ + const issues = useMemo( + () => + (paneData?.issues ?? []).map((issue) => ({ ...issue, status: statusOverrides[issue.id] ?? issue.status, - })) - : []; + })), + [paneData?.issues, statusOverrides], + ); const isLoading = paneData?.isLoading ?? true; // --- Header Stats Logic --- const openCount = useMemo( - () => issues.filter((issue) => issue.status !== "FINISHED").length, + () => issues.filter((issue) => issue.status !== "Finished").length, [issues], ); const closedCount = issues.length - openCount; @@ -85,22 +82,8 @@ export function KanbanBoard() { // --- Active Filters Logic --- const filters = paneData?.filters; const activeFilters = useMemo(() => { - if (!filters) return []; - const tags: string[] = []; - if (filters.statusFilter !== "all") - tags.push(formatStatus(filters.statusFilter)); - if (filters.teamFilter !== "all") tags.push("Team selected"); - if (filters.issueKind !== "all") - tags.push( - filters.issueKind === "task" ? "Tasks only" : "Event-linked only", - ); - if (filters.rootOnly) tags.push("Root"); - if (filters.dateFrom) tags.push("From " + filters.dateFrom); - if (filters.dateTo) tags.push("To " + filters.dateTo); - if (filters.searchTerm.trim()) - tags.push('Search "' + filters.searchTerm.trim() + '"'); - return tags; - }, [filters]); + return getActiveIssueFilterTags(filters, paneData?.roleNameById); + }, [filters, paneData?.roleNameById]); const handleDragStart = ( e: React.DragEvent, @@ -147,44 +130,12 @@ export function KanbanBoard() { return (
    -
    -
    -
    - - {openCount} Open -
    -
    - - {closedCount} Closed -
    -
    - - {/* Action Buttons */} -
    - - - - - -
    -
    - - {/* 2. Active Filter Tags */} - {activeFilters.length > 0 && ( -
    - {activeFilters.map((tag) => ( - - {tag} - - ))} -
    - )} + setIsFiltersOpen(true)} + /> {/* 3. The Board */} {isLoading ? ( @@ -228,7 +179,7 @@ export function KanbanBoard() {
    {issue.name} diff --git a/apps/blade/src/app/_components/issue-list/issues-list.tsx b/apps/blade/src/app/_components/issue-list/issues-list.tsx index 8da1b3c6f..ce95daca2 100644 --- a/apps/blade/src/app/_components/issue-list/issues-list.tsx +++ b/apps/blade/src/app/_components/issue-list/issues-list.tsx @@ -2,30 +2,22 @@ import { useMemo, useState } from "react"; import Link from "next/link"; -import { - CheckCircle2, - CircleDot, - Pencil, - SlidersHorizontal, -} from "lucide-react"; +import { Pencil } from "lucide-react"; -import type { ISSUE } from "@forge/consts"; +import { ISSUE } from "@forge/consts"; import { Button } from "@forge/ui/button"; import { toast } from "@forge/ui/toast"; import { CreateEditDialog } from "~/app/_components/issues/create-edit-dialog"; import { IssueFetcherPane } from "~/app/_components/issues/issue-fetcher-pane"; import { StatusSelect } from "~/app/_components/issues/issue-form-fields"; -import IssueTemplateDialog from "~/app/_components/issues/issue-template-dialog"; +import { + getActiveIssueFilterTags, + IssueViewControlBar, +} from "~/app/_components/issues/issue-view-control-bar"; +import SortButton from "~/app/_components/shared/SortButton"; import { api } from "~/trpc/react"; -function formatStatus(status: string) { - return status - .toLowerCase() - .replace(/_/g, " ") - .replace(/\b\w/g, (char) => char.toUpperCase()); -} - function formatDate(value: Date | null) { if (!value) return "No due date"; return new Date(value).toLocaleDateString(); @@ -54,8 +46,11 @@ function formatTeamLabel(roleName: string) { return trimmed || roleName; } +type SortField = "name" | "status" | "date" | "team" | "updatedAt"; +type SortOrder = "asc" | "desc" | null; + function isOverdueIssue(issue: ISSUE.IssueFetcherPaneIssue) { - if (issue.status === "FINISHED" || !issue.date) return false; + if (issue.status === "Finished" || !issue.date) return false; const dueDate = new Date(issue.date); const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); @@ -64,6 +59,8 @@ function isOverdueIssue(issue: ISSUE.IssueFetcherPaneIssue) { export function IssuesList() { const [isFiltersOpen, setIsFiltersOpen] = useState(false); + const [sortField, setSortField] = useState(null); + const [sortOrder, setSortOrder] = useState(null); const [statusOverrides, setStatusOverrides] = useState< Record >({}); @@ -91,12 +88,19 @@ export function IssuesList() { }, }); - const issues = useMemo(() => paneData?.issues ?? [], [paneData?.issues]); + const issues = useMemo( + () => + (paneData?.issues ?? []).map((issue) => ({ + ...issue, + status: statusOverrides[issue.id] ?? issue.status, + })), + [paneData?.issues, statusOverrides], + ); const isLoading = paneData?.isLoading ?? true; const error = paneData?.error ?? null; const openCount = useMemo( - () => issues.filter((issue) => issue.status !== "FINISHED").length, + () => issues.filter((issue) => issue.status !== "Finished").length, [issues], ); const closedCount = issues.length - openCount; @@ -104,66 +108,109 @@ export function IssuesList() { const filters = paneData?.filters; const activeFilters = useMemo(() => { - if (!filters) return []; - const tags: string[] = []; - if (filters.statusFilter !== "all") - tags.push(formatStatus(filters.statusFilter)); - if (filters.teamFilter !== "all") tags.push("Team selected"); - if (filters.issueKind !== "all") - tags.push( - filters.issueKind === "task" ? "Tasks only" : "Event-linked only", - ); - if (filters.rootOnly) tags.push("Root only"); - if (filters.dateFrom) tags.push("From " + filters.dateFrom); - if (filters.dateTo) tags.push("To " + filters.dateTo); - if (filters.searchTerm.trim()) - tags.push('Search "' + filters.searchTerm.trim() + '"'); - return tags; - }, [filters]); + return getActiveIssueFilterTags(filters, paneData?.roleNameById); + }, [filters, paneData?.roleNameById]); - return ( -
    -
    -
    -
    - - {openCount} Open -
    -
    - - {closedCount} Closed -
    -
    -
    - - - - - -
    -
    + const sortedIssues = useMemo(() => { + if (!sortField || !sortOrder) return issues; - {activeFilters.length > 0 && ( -
    - {activeFilters.map((tag) => ( - - {tag} - - ))} -
    - )} + const roleNameById = paneData?.roleNameById; + const statusRank = new Map( + ISSUE.ISSUE_STATUS.map((status, index) => [status, index]), + ); + + const getTeamName = (issue: ISSUE.IssueFetcherPaneIssue) => + formatTeamLabel(roleNameById?.get(issue.team) ?? issue.team); + + const compareNullableDates = (left: Date | null, right: Date | null) => { + if (!left && !right) return 0; + if (!left) return 1; + if (!right) return -1; + return left.getTime() - right.getTime(); + }; + + const sorted = [...issues].sort((left, right) => { + switch (sortField) { + case "name": + return left.name.localeCompare(right.name); + case "status": + return ( + (statusRank.get(left.status) ?? 0) - + (statusRank.get(right.status) ?? 0) + ); + case "date": + return compareNullableDates(left.date, right.date); + case "team": + return getTeamName(left).localeCompare(getTeamName(right)); + case "updatedAt": + return compareNullableDates(left.updatedAt, right.updatedAt); + } + }); + + return sortOrder === "asc" ? sorted : sorted.reverse(); + }, [issues, paneData?.roleNameById, sortField, sortOrder]); + + return ( +
    + setIsFiltersOpen(true)} + />
    -
    - Issue - Status - Due +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    Edit
    @@ -187,24 +234,18 @@ export function IssuesList() { {!isLoading && !error && - issues.map((issue) => ( + sortedIssues.map((issue) => (
    {issue.name} -
    - {formatUpdatedAt(issue.updatedAt)} •{" "} - {formatTeamLabel( - paneData?.roleNameById.get(issue.team) ?? issue.team, - )} -
    @@ -262,6 +303,22 @@ export function IssuesList() {
    +
    + + Team + + {formatTeamLabel( + paneData?.roleNameById.get(issue.team) ?? issue.team, + )} +
    + +
    + + Updated + + {formatUpdatedAt(issue.updatedAt)} +
    +
    Edit diff --git a/apps/blade/src/app/_components/issues/create-edit-dialog.tsx b/apps/blade/src/app/_components/issues/create-edit-dialog.tsx index 4586af220..431b98008 100644 --- a/apps/blade/src/app/_components/issues/create-edit-dialog.tsx +++ b/apps/blade/src/app/_components/issues/create-edit-dialog.tsx @@ -20,6 +20,7 @@ import { Checkbox } from "@forge/ui/checkbox"; import { Dialog, DialogContent, + DialogDescription, DialogFooter, DialogHeader, DialogTitle, @@ -57,6 +58,11 @@ import { updateIssueNode, validateIssueNodes, } from "./issue-node"; +import { + hasInputKeyword, + resolveChildTemplateName, + resolveRootTemplateName, +} from "./issue-template-keywords"; const baseField = "w-full"; @@ -131,22 +137,30 @@ type CreateEditDialogComponentProps = Omit< const defaultForm = (): ISSUE.IssueEditNode => newIssueNode(); +function ensureTeamVisible(teamId: string, roleIds: string[] | undefined) { + if (!teamId) return roleIds ?? []; + return Array.from(new Set([...(roleIds ?? []), teamId])); +} + function templateToIssueNodes( items: ISSUE.IssueTemplate[], parentDate: Date, + parentName?: string, ): ISSUE.IssueEditNode[] { return items.map((item) => { const date = item.dateMs ? new Date(parentDate.getTime() - item.dateMs) : undefined; + const resolvedName = resolveChildTemplateName(item.title, parentName); return newIssueNode({ - name: item.title, + name: resolvedName, description: item.description ?? "", team: item.team ?? "", date, children: templateToIssueNodes( item.children ?? [], date ?? normalizeTaskDueDate(), + resolvedName, ), }); }); @@ -166,6 +180,10 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { const [internalOpen, setInternalOpen] = useState(false); const isControlled = open !== undefined; const isOpen = isControlled ? open : internalOpen; + const [templateInputPrompt, setTemplateInputPrompt] = useState<{ + template: { name: string; body: unknown }; + value: string; + } | null>(null); const utils = api.useUtils(); const rolesQuery = api.roles.getAllLinks.useQuery(); const hackathonsQuery = api.hackathon.getHackathons.useQuery(); @@ -288,8 +306,12 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { [rolesData], ); const safeVisibilityIds = useMemo( - () => formValues.roles.filter((roleId) => roleIdSet.has(roleId)), - [formValues.roles, roleIdSet], + () => + ensureTeamVisible( + effectiveTeam, + formValues.roles.filter((roleId) => roleIdSet.has(roleId)), + ), + [effectiveTeam, formValues.roles, roleIdSet], ); const safeEventVisibilityIds = useMemo( () => @@ -343,13 +365,20 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { const { data: templates = [], isLoading: isTemplatesLoading } = api.issues.getTemplates.useQuery(undefined, { enabled: isOpen }); - const applyTemplate = (template: { name: string; body: unknown }) => { + const applyTemplate = ( + template: { name: string; body: unknown }, + rootInput?: string, + ) => { const body = template.body as ISSUE.IssueTemplate[]; const root = Array.isArray(body) ? body[0] : undefined; + const resolvedRootName = resolveRootTemplateName( + root?.title ?? template.name, + rootInput?.trim() ?? "", + ); setFormValues((prev) => ({ ...prev, - name: root?.title ?? template.name, + name: resolvedRootName, description: root?.description ?? prev.description, ...(root?.team ? { team: root.team } : {}), })); @@ -358,10 +387,30 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { templateToIssueNodes( root?.children ?? [], normalizeTaskDueDate(formValues.date), + resolvedRootName, ), ); }; + const handleTemplateSelection = (template: { + name: string; + body: unknown; + }) => { + const body = template.body as ISSUE.IssueTemplate[]; + const root = Array.isArray(body) ? body[0] : undefined; + const rootTitle = root?.title ?? template.name; + + if (hasInputKeyword(rootTitle)) { + setTemplateInputPrompt({ + template, + value: "", + }); + return; + } + + applyTemplate(template); + }; + async function buildIssueNodes( nodes: ISSUE.IssueEditNode[], ): Promise { @@ -407,7 +456,10 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { priority: node.priority, team: node.team, event: eventId, - teamVisibilityIds: node.roles.length > 0 ? node.roles : undefined, + teamVisibilityIds: + ensureTeamVisible(node.team, node.roles).length > 0 + ? ensureTeamVisible(node.team, node.roles) + : undefined, assigneeIds: node.assigneeIds, children: node.children.length > 0 @@ -551,6 +603,16 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { } }; + const handleTemplateInputApply = () => { + if (!templateInputPrompt) return; + + const trimmedValue = templateInputPrompt.value.trim(); + if (!trimmedValue) return; + + applyTemplate(templateInputPrompt.template, trimmedValue); + setTemplateInputPrompt(null); + }; + return ( <> {trigger} @@ -822,7 +884,7 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { updateForm("roles", ids)} description="Teams who can see and manage the issue" /> @@ -913,7 +975,7 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { {templates.map((t) => ( applyTemplate(t)} + onClick={() => handleTemplateSelection(t)} > {t.name} @@ -954,6 +1016,64 @@ export function CreateEditDialog(props: CreateEditDialogComponentProps) { + { + if (!open) setTemplateInputPrompt(null); + }} + > + + + Template Input + + This template uses {`{INPUT}`} in the parent issue + title. Enter the value to substitute before child issues are + generated. + + +
    + + + setTemplateInputPrompt((previous) => + previous + ? { + ...previous, + value: event.target.value, + } + : previous, + ) + } + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + handleTemplateInputApply(); + } + }} + /> +
    + + + + +
    +
    ); } diff --git a/apps/blade/src/app/_components/issues/issue-fetcher-pane.tsx b/apps/blade/src/app/_components/issues/issue-fetcher-pane.tsx index b8775ae8d..297796eff 100644 --- a/apps/blade/src/app/_components/issues/issue-fetcher-pane.tsx +++ b/apps/blade/src/app/_components/issues/issue-fetcher-pane.tsx @@ -134,6 +134,11 @@ export function IssueFetcherPane(props: IssueFetcherPaneProps) { () => new Map(roles.map((role) => [role.id, role.name])), [roles], ); + const roleColorById = useMemo( + () => + new Map(roles.map((role) => [role.id, role.teamHexcodeColor ?? null])), + [roles], + ); const allIssues = useMemo( () => (issuesData ?? []) as ISSUE.IssueFetcherPaneIssue[], @@ -144,7 +149,7 @@ export function IssueFetcherPane(props: IssueFetcherPaneProps) { const blockedParents = new Set(); for (const issue of allIssues) { - if (issue.parent && issue.status !== "FINISHED") { + if (issue.parent && issue.status !== "Finished") { blockedParents.add(issue.parent); } } @@ -184,6 +189,7 @@ export function IssueFetcherPane(props: IssueFetcherPaneProps) { issues: isReady ? issues : [], blockedParentIds: isReady ? blockedParentIds : new Set(), roleNameById: isReady ? roleNameById : new Map(), + roleColorById: isReady ? roleColorById : new Map(), isLoading: combinedIsLoading, error: combinedErrorMessage, refresh, @@ -197,6 +203,7 @@ export function IssueFetcherPane(props: IssueFetcherPaneProps) { isReady, issues, refresh, + roleColorById, roleNameById, ], ); diff --git a/apps/blade/src/app/_components/issues/issue-node.tsx b/apps/blade/src/app/_components/issues/issue-node.tsx index fe14c43fc..8b8aee142 100644 --- a/apps/blade/src/app/_components/issues/issue-node.tsx +++ b/apps/blade/src/app/_components/issues/issue-node.tsx @@ -283,7 +283,9 @@ export function IssueNode({ update("roles", ids)} description="Teams who can see and manage this sub-issue" /> @@ -435,7 +437,7 @@ export function IssueTemplateNode({ update("name", e.target.value)} onClick={(e) => e.stopPropagation()} diff --git a/apps/blade/src/app/_components/issues/issue-template-dialog.tsx b/apps/blade/src/app/_components/issues/issue-template-dialog.tsx index 7c34a62a3..ae6f8be94 100644 --- a/apps/blade/src/app/_components/issues/issue-template-dialog.tsx +++ b/apps/blade/src/app/_components/issues/issue-template-dialog.tsx @@ -327,12 +327,18 @@ export default function IssueTemplateDialog({ <>
    - updateRoot({ name: e.target.value })} - /> +
    + updateRoot({ name: e.target.value })} + /> +

    + Root task names can include {`{INPUT}`}{" "} + to prompt for a value when the template is applied. +

    +
    @@ -373,6 +379,11 @@ export default function IssueTemplateDialog({ Add Sub-task
    +

    + Hint: sub-task names can include{" "} + {`{PARENT}`} to insert the applied parent + issue name. Example: {`{PARENT} Post`}. +

    {root.children.length === 0 && (

    No sub-tasks yet. diff --git a/apps/blade/src/app/_components/issues/issue-template-keywords.ts b/apps/blade/src/app/_components/issues/issue-template-keywords.ts new file mode 100644 index 000000000..c22e91d6f --- /dev/null +++ b/apps/blade/src/app/_components/issues/issue-template-keywords.ts @@ -0,0 +1,18 @@ +const ROOT_INPUT_KEYWORD = "{INPUT}"; +const CHILD_PARENT_KEYWORD = "{PARENT}"; + +export function hasInputKeyword(name: string) { + return name.includes(ROOT_INPUT_KEYWORD); +} + +export function resolveRootTemplateName(name: string, input: string) { + return name.replaceAll(ROOT_INPUT_KEYWORD, input); +} + +export function resolveChildTemplateName( + name: string, + parentName: string | undefined, +) { + if (!parentName) return name; + return name.replaceAll(CHILD_PARENT_KEYWORD, parentName); +} diff --git a/apps/blade/src/app/_components/issues/issue-view-control-bar.tsx b/apps/blade/src/app/_components/issues/issue-view-control-bar.tsx new file mode 100644 index 000000000..16efa7cec --- /dev/null +++ b/apps/blade/src/app/_components/issues/issue-view-control-bar.tsx @@ -0,0 +1,176 @@ +"use client"; + +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { + CalendarDays, + CheckCircle2, + CircleDot, + ListTodo, + SlidersHorizontal, + SquareKanban, +} from "lucide-react"; + +import type { ISSUE } from "@forge/consts"; +import { cn } from "@forge/ui"; +import { Button, buttonVariants } from "@forge/ui/button"; + +import { CreateEditDialog } from "~/app/_components/issues/create-edit-dialog"; +import IssueTemplateDialog from "~/app/_components/issues/issue-template-dialog"; + +function formatStatus(status: string) { + return status + .toLowerCase() + .replace(/_/g, " ") + .replace(/\b\w/g, (char) => char.toUpperCase()); +} + +export function getActiveIssueFilterTags( + filters: ISSUE.IssueFilters | null | undefined, + roleNameById?: Map | null, +) { + if (!filters) return []; + + const tags: string[] = []; + if (filters.statusFilter !== "all") + tags.push(formatStatus(filters.statusFilter)); + if (filters.teamFilter !== "all") { + const teamName = + roleNameById?.get(filters.teamFilter) ?? filters.teamFilter; + tags.push(`Team Selected: ${teamName}`); + } + if (filters.issueKind !== "all") { + tags.push( + filters.issueKind === "task" ? "Tasks only" : "Event-linked only", + ); + } + if (filters.rootOnly) tags.push("Root only"); + if (filters.dateFrom) tags.push("From " + filters.dateFrom); + if (filters.dateTo) tags.push("To " + filters.dateTo); + if (filters.searchTerm.trim()) { + tags.push('Search "' + filters.searchTerm.trim() + '"'); + } + + return tags; +} + +interface IssueViewControlBarProps { + openCount: number; + closedCount: number; + activeFilters: string[]; + onOpenFilters: () => void; + createInitialValues?: Partial; + onBeforeCreate?: () => void; + onBeforeOpenFilters?: () => void; +} + +const issueViewLinks = [ + { + href: "/admin/issues/kanban", + label: "Kanban", + icon: SquareKanban, + }, + { + href: "/admin/issues/list", + label: "List", + icon: ListTodo, + }, + { + href: "/admin/issues/calendar", + label: "Calendar", + icon: CalendarDays, + }, +] as const; + +export function IssueViewControlBar({ + openCount, + closedCount, + activeFilters, + onOpenFilters, + createInitialValues, + onBeforeCreate, + onBeforeOpenFilters, +}: IssueViewControlBarProps) { + const pathname = usePathname(); + + return ( +

    +
    +
    +
    + + {openCount} Open +
    +
    + + {closedCount} Closed +
    +
    + +
    + {issueViewLinks.map((link) => { + const Icon = link.icon; + const isActive = pathname === link.href; + + return ( + + + {link.label} + + ); + })} +
    + +
    + + + + + +
    +
    + + {activeFilters.length > 0 ? ( +
    + Active filters + {activeFilters.map((tag) => ( + + {tag} + + ))} +
    + ) : null} +
    + ); +} diff --git a/apps/blade/src/app/_components/navigation/reusable-user-dropdown.tsx b/apps/blade/src/app/_components/navigation/reusable-user-dropdown.tsx index 77455eb80..51b44b849 100644 --- a/apps/blade/src/app/_components/navigation/reusable-user-dropdown.tsx +++ b/apps/blade/src/app/_components/navigation/reusable-user-dropdown.tsx @@ -3,8 +3,10 @@ import { ChartPie, FormInput, Hotel, + ListTodo, Settings, ShieldCheck, + SquareKanban, Swords, TicketCheck, User, @@ -90,6 +92,48 @@ export const systemItems: roleItems[] = [ }, ]; +export const issuesItems: roleItems[] = [ + { + name: "Kanban", + component: ( + + ), + route: "/admin/issues/kanban", + requiredPermissions: { + or: ["READ_ISSUES", "EDIT_ISSUES", "IS_OFFICER"], + }, + }, + { + name: "List", + component: ( + + ), + route: "/admin/issues/list", + requiredPermissions: { + or: ["READ_ISSUES", "EDIT_ISSUES", "IS_OFFICER"], + }, + }, + { + name: "Calendar", + component: ( + + ), + route: "/admin/issues/calendar", + requiredPermissions: { + or: ["READ_ISSUES", "EDIT_ISSUES", "IS_OFFICER"], + }, + }, +]; + export const clubItems: roleItems[] = [ { name: "Members", diff --git a/apps/blade/src/app/_components/navigation/user-dropdown.tsx b/apps/blade/src/app/_components/navigation/user-dropdown.tsx index dba314b02..9f24a511c 100644 --- a/apps/blade/src/app/_components/navigation/user-dropdown.tsx +++ b/apps/blade/src/app/_components/navigation/user-dropdown.tsx @@ -24,6 +24,7 @@ import { adminItems, clubItems, hackathonItems, + issuesItems, systemItems, userItems, } from "./reusable-user-dropdown"; @@ -74,6 +75,10 @@ export function UserDropdown({ permissions }: UserDropdownProps) { systemItems, permissions, ); + const filteredIssuesItems = filterItemsByPermissions( + issuesItems, + permissions, + ); const filteredClubItems = filterItemsByPermissions(clubItems, permissions); const filteredHackathonItems = filterItemsByPermissions( hackathonItems, @@ -107,6 +112,12 @@ export function UserDropdown({ permissions }: UserDropdownProps) { )} + {filteredIssuesItems.length > 0 && ( + <> + Issues + + + )} {filteredClubItems.length > 0 && ( <> Club diff --git a/apps/blade/src/app/issues/[id]/page.tsx b/apps/blade/src/app/admin/issues/[id]/page.tsx similarity index 97% rename from apps/blade/src/app/issues/[id]/page.tsx rename to apps/blade/src/app/admin/issues/[id]/page.tsx index 3fe716184..dd45b346d 100644 --- a/apps/blade/src/app/issues/[id]/page.tsx +++ b/apps/blade/src/app/admin/issues/[id]/page.tsx @@ -6,13 +6,13 @@ import { auth } from "@forge/auth"; import { SIGN_IN_PATH } from "~/consts"; import { api } from "~/trpc/server"; -interface IssuePageProps { +interface AdminIssuePageProps { params: Promise<{ id: string; }>; } -export default async function IssuePage({ params }: IssuePageProps) { +export default async function AdminIssuePage({ params }: AdminIssuePageProps) { const session = await auth(); if (!session) redirect(SIGN_IN_PATH); @@ -21,6 +21,7 @@ export default async function IssuePage({ params }: IssuePageProps) { const { id } = await params; if (!z.string().uuid().safeParse(id).success) notFound(); + let issue; try { issue = await api.issues.getIssue({ id }); diff --git a/apps/blade/src/app/issues/calendar/page.tsx b/apps/blade/src/app/admin/issues/calendar/page.tsx similarity index 60% rename from apps/blade/src/app/issues/calendar/page.tsx rename to apps/blade/src/app/admin/issues/calendar/page.tsx index bd35f7b61..e012850ea 100644 --- a/apps/blade/src/app/issues/calendar/page.tsx +++ b/apps/blade/src/app/admin/issues/calendar/page.tsx @@ -3,11 +3,10 @@ import { notFound, redirect } from "next/navigation"; import { auth } from "@forge/auth"; import Calendar from "~/app/_components/issue-calendar/calendar"; -import { SessionNavbar } from "~/app/_components/navigation/session-navbar"; import { SIGN_IN_PATH } from "~/consts"; import { api, HydrateClient } from "~/trpc/server"; -export default async function Events() { +export default async function AdminIssuesCalendarPage() { const session = await auth(); if (!session) { redirect(SIGN_IN_PATH); @@ -25,14 +24,9 @@ export default async function Events() { return ( -
    -
    - -
    -
    - -
    -
    +
    + +
    ); } diff --git a/apps/blade/src/app/issues/kanban/page.tsx b/apps/blade/src/app/admin/issues/kanban/page.tsx similarity index 76% rename from apps/blade/src/app/issues/kanban/page.tsx rename to apps/blade/src/app/admin/issues/kanban/page.tsx index 72aaaa270..970578abf 100644 --- a/apps/blade/src/app/issues/kanban/page.tsx +++ b/apps/blade/src/app/admin/issues/kanban/page.tsx @@ -3,11 +3,10 @@ import { notFound, redirect } from "next/navigation"; import { auth } from "@forge/auth"; import { KanbanBoard } from "~/app/_components/issue-kanban/issues-kanban"; -import { SessionNavbar } from "~/app/_components/navigation/session-navbar"; import { SIGN_IN_PATH } from "~/consts"; import { api, HydrateClient } from "~/trpc/server"; -export default async function KanbanPage() { +export default async function AdminIssuesKanbanPage() { const session = await auth(); if (!session) redirect(SIGN_IN_PATH); @@ -23,8 +22,7 @@ export default async function KanbanPage() { return ( - -
    +
    diff --git a/apps/blade/src/app/issues/list/page.tsx b/apps/blade/src/app/admin/issues/list/page.tsx similarity index 74% rename from apps/blade/src/app/issues/list/page.tsx rename to apps/blade/src/app/admin/issues/list/page.tsx index dade766ab..d04c6969c 100644 --- a/apps/blade/src/app/issues/list/page.tsx +++ b/apps/blade/src/app/admin/issues/list/page.tsx @@ -3,16 +3,15 @@ import { notFound, redirect } from "next/navigation"; import { auth } from "@forge/auth"; import { IssuesList } from "~/app/_components/issue-list/issues-list"; -import { SessionNavbar } from "~/app/_components/navigation/session-navbar"; import { SIGN_IN_PATH } from "~/consts"; import { api, HydrateClient } from "~/trpc/server"; -export default async function IssueListPage() { +export default async function AdminIssuesListPage() { const session = await auth(); if (!session) redirect(SIGN_IN_PATH); const hasAccess = await api.roles.hasPermission({ - and: [ + or: [ "READ_ISSUES", "EDIT_ISSUES", "EDIT_ISSUE_TEMPLATES", @@ -23,8 +22,7 @@ export default async function IssueListPage() { return ( - -
    +
    diff --git a/apps/blade/src/app/admin/page.tsx b/apps/blade/src/app/admin/page.tsx index d63f6d916..73b949829 100644 --- a/apps/blade/src/app/admin/page.tsx +++ b/apps/blade/src/app/admin/page.tsx @@ -6,8 +6,10 @@ import { ChartPie, FormInput, Hotel, + ListTodo, Settings, ShieldCheck, + SquareKanban, Swords, TicketCheck, User, @@ -135,6 +137,33 @@ export default async function Admin() { }, ], }, + { + title: "Issues", + description: "Manage issues across kanban, list, and calendar views", + icon: SquareKanban, + color: "text-amber-500", + bgColor: "bg-amber-500/10", + items: [ + { + href: "/admin/issues/kanban", + label: "Kanban", + icon: SquareKanban, + show: perms.READ_ISSUES || perms.EDIT_ISSUES || perms.IS_OFFICER, + }, + { + href: "/admin/issues/list", + label: "List", + icon: ListTodo, + show: perms.READ_ISSUES || perms.EDIT_ISSUES || perms.IS_OFFICER, + }, + { + href: "/admin/issues/calendar", + label: "Calendar", + icon: CalendarDays, + show: perms.READ_ISSUES || perms.EDIT_ISSUES || perms.IS_OFFICER, + }, + ], + }, { title: "System", description: "Forms, emails, and role management", diff --git a/apps/cron/src/crons/issue-reminders.ts b/apps/cron/src/crons/issue-reminders.ts index 768189173..c41a6e151 100644 --- a/apps/cron/src/crons/issue-reminders.ts +++ b/apps/cron/src/crons/issue-reminders.ts @@ -1,6 +1,7 @@ import { Routes } from "discord-api-types/v10"; import { and, inArray, isNotNull, ne } from "drizzle-orm"; +import { IS_PROD, ISSUE } from "@forge/consts"; import { db } from "@forge/db/client"; import { Roles } from "@forge/db/schemas/auth"; import { Issue } from "@forge/db/schemas/knight-hacks"; @@ -10,20 +11,6 @@ import { api } from "@forge/utils/discord"; import { env } from "../env"; import { CronBuilder } from "../structs/CronBuilder"; -const ISSUE_REMINDER_CHANNELS = { - Teams: "Teams", - Directors: "Directors", - Design: "Design", - HackOrg: "HackOrg", -} as const; - -const ISSUE_REMINDER_DESTINATION_CHANNEL_IDS = { - Teams: "1459204271655489567", - Directors: "1463407041191088188", - HackOrg: "1461565747649187874", - Design: "1483901622558920945", -}; - const ISSUE_REMINDER_DAYS = { Fourteen: "Fourteen", Seven: "Seven", @@ -33,10 +20,10 @@ const ISSUE_REMINDER_DAYS = { } as const; const ISSUE_REMINDER_DAY_LABELS: Record = { - Fourteen: "Due in 14 days", - Seven: "Due in 7 days", - Three: "Due in 3 days", - One: "Due in 1 day", + Fourteen: "14 days", + Seven: "7 days", + Three: "3 days", + One: "1 day", Overdue: "Overdue", }; @@ -54,24 +41,29 @@ type IssueReminderDay = interface IssueReminderTarget { issueId: string; issueName: string; + issuePriority: (typeof ISSUE.PRIORITY)[number]; + issueUpdatedAt: Date; + issueDueDate: Date; teamId: string; teamDiscordRoleId: string; assigneeDiscordUserIds: string[]; - channel: keyof typeof ISSUE_REMINDER_CHANNELS; + discordChannelId: string; day: IssueReminderDay; overdueDays: number | null; } type GroupedIssueReminders = Partial< - Record< - keyof typeof ISSUE_REMINDER_CHANNELS, - Partial> - > + Record>> >; const MAX_DISCORD_MESSAGE_LENGTH = 2000; const ISSUE_REMINDER_TIMEZONE = "America/New_York"; +const resolveDestinationChannelId = (roleChannelId: string): string => { + if (!IS_PROD) return ISSUE.DEV_ISSUE_REMINDER_CHANNEL_ID; + return roleChannelId || ISSUE.DEFAULT_ISSUE_REMINDER_CHANNEL_ID; +}; + const getTimezoneMidnightTimestamp = (date: Date, timeZone: string): number => { const parts = new Intl.DateTimeFormat("en-US", { timeZone, @@ -111,24 +103,28 @@ const getIssueReminderDiffDays = (date: Date, now = new Date()): number => { const buildIssueReminderTarget = (issue: { id: string; name: string; + priority: (typeof ISSUE.PRIORITY)[number]; + updatedAt: Date; team: string; date: Date | null; teamDiscordRoleId: string; assigneeDiscordUserIds: string[]; - channel: keyof typeof ISSUE_REMINDER_CHANNELS | null; + discordChannelId: string; }): IssueReminderTarget | null => { if (!issue.date) return null; - if (!issue.channel) return null; const day = getIssueReminderDay(issue.date); if (!day) return null; if (!issue.teamDiscordRoleId) return null; return { issueId: issue.id, issueName: issue.name, + issuePriority: issue.priority, + issueUpdatedAt: issue.updatedAt, + issueDueDate: issue.date, teamId: issue.team, teamDiscordRoleId: issue.teamDiscordRoleId, assigneeDiscordUserIds: issue.assigneeDiscordUserIds, - channel: issue.channel, + discordChannelId: issue.discordChannelId, day, overdueDays: day === ISSUE_REMINDER_DAYS.Overdue @@ -148,8 +144,8 @@ const groupIssueReminderTargets = ( ): GroupedIssueReminders => { const grouped: GroupedIssueReminders = {}; for (const t of targets) { - grouped[t.channel] ??= {}; - const channelGroup = grouped[t.channel]; + grouped[t.discordChannelId] ??= {}; + const channelGroup = grouped[t.discordChannelId]; if (!channelGroup) continue; channelGroup[t.day] ??= []; const dayGroup = channelGroup[t.day]; @@ -175,15 +171,55 @@ const sanitizeIssueReminderTitle = (title: string): string => { .trim(); }; +const formatIssueReminderDate = (date: Date): string => { + return new Intl.DateTimeFormat("en-US", { + timeZone: ISSUE_REMINDER_TIMEZONE, + year: "numeric", + month: "2-digit", + day: "2-digit", + }).format(date); +}; + +const formatIssueReminderDateTime = (date: Date): string => { + return new Intl.DateTimeFormat("en-US", { + timeZone: ISSUE_REMINDER_TIMEZONE, + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }).format(date); +}; + +const ISSUE_PRIORITY_RANK: Record<(typeof ISSUE.PRIORITY)[number], number> = + ISSUE.PRIORITY.reduce( + (acc, priority, index) => ({ + ...acc, + [priority]: index, + }), + {} as Record<(typeof ISSUE.PRIORITY)[number], number>, + ); + +const sortIssueReminderTargets = ( + targets: IssueReminderTarget[], +): IssueReminderTarget[] => { + return [...targets].sort((a, b) => { + const priorityDiff = + ISSUE_PRIORITY_RANK[b.issuePriority] - + ISSUE_PRIORITY_RANK[a.issuePriority]; + if (priorityDiff !== 0) return priorityDiff; + return a.issueName.localeCompare(b.issueName, undefined, { + sensitivity: "base", + }); + }); +}; + const formatIssueReminder = (target: IssueReminderTarget): string => { - const mentions = getIssueMentionTargets(target).join(", "); + const mentionTargets = getIssueMentionTargets(target); + const assigneeOrTeam = mentionTargets.join(", "); const issueUrl = getIssueUrl(target.issueId); const issueTitle = sanitizeIssueReminderTitle(target.issueName); - const overdueSuffix = - target.day === ISSUE_REMINDER_DAYS.Overdue && target.overdueDays !== null - ? ` (${target.overdueDays} days)` - : ""; - return `[${issueTitle}](<${issueUrl}>)${overdueSuffix} ${mentions}`; + return `[${issueTitle}](<${issueUrl}>) | ${assigneeOrTeam} | ${target.issuePriority} | Updated: ${formatIssueReminderDateTime(target.issueUpdatedAt)} | Due: ${formatIssueReminderDateTime(target.issueDueDate)}`; }; const truncateReminderLine = (line: string, maxLength: number): string => { @@ -193,7 +229,7 @@ const truncateReminderLine = (line: string, maxLength: number): string => { }; const getIssueUrl = (issueId: string): string => { - return `${env.BLADE_URL.replace(/\/$/, "")}/issues/${issueId}`; + return `${env.BLADE_URL.replace(/\/$/, "")}/admin/issues/${issueId}`; }; const getAllowedMentions = ( @@ -218,31 +254,25 @@ const getAllowedMentions = ( }; }; -const formatIssueReminderEmbedDescription = (content: string): string => { - return content - .replace(/^# Issue Reminders\n?/, "") - .replace(/^## (.+)$/gm, "**$1**") - .trim(); -}; - const splitChannelReminderMessages = ( grouped: Partial>, ): { content: string; targets: IssueReminderTarget[] }[] => { const chunks: { content: string; targets: IssueReminderTarget[] }[] = []; - let currentContent = "# Issue Reminders"; + let currentContent = `## Issue Reminders - ${formatIssueReminderDate(new Date())}`; let currentTargets: IssueReminderTarget[] = []; for (const day of ISSUE_REMINDER_DAY_ORDER) { const targets = grouped[day]; if (!targets || targets.length === 0) continue; - const sectionLines = targets.map(formatIssueReminder); - const sectionContent = `## ${ISSUE_REMINDER_DAY_LABELS[day]}\n${sectionLines.join("\n")}`; + const sortedTargets = sortIssueReminderTargets(targets); + const sectionLines = sortedTargets.map(formatIssueReminder); + const sectionContent = `### ${ISSUE_REMINDER_DAY_LABELS[day]}\n${sectionLines.join("\n")}`; const nextContent = `${currentContent}\n${sectionContent}`; if (nextContent.length <= MAX_DISCORD_MESSAGE_LENGTH) { currentContent = nextContent; - currentTargets.push(...targets); + currentTargets.push(...sortedTargets); continue; } @@ -250,7 +280,7 @@ const splitChannelReminderMessages = ( chunks.push({ content: currentContent, targets: currentTargets }); } - let sectionChunkContent = `# Issue Reminders\n\n## ${ISSUE_REMINDER_DAY_LABELS[day]}`; + let sectionChunkContent = `## Issue Reminders - ${formatIssueReminderDate(new Date())}\n\n### ${ISSUE_REMINDER_DAY_LABELS[day]}`; let sectionChunkTargets: IssueReminderTarget[] = []; const sectionHeaderLength = `${sectionChunkContent}\n`.length; @@ -259,7 +289,7 @@ const splitChannelReminderMessages = ( sectionLines[index] ?? "", MAX_DISCORD_MESSAGE_LENGTH - sectionHeaderLength, ); - const target = targets[index]; + const target = sortedTargets[index]; if (!target) continue; const nextSectionChunkContent = `${sectionChunkContent}\n${line}`; if (nextSectionChunkContent.length > MAX_DISCORD_MESSAGE_LENGTH) { @@ -270,7 +300,7 @@ const splitChannelReminderMessages = ( }); } - sectionChunkContent = `# Issue Reminders\n\n## ${ISSUE_REMINDER_DAY_LABELS[day]}\n${line}`; + sectionChunkContent = `## Issue Reminders - ${formatIssueReminderDate(new Date())}\n\n### ${ISSUE_REMINDER_DAY_LABELS[day]}\n${line}`; sectionChunkTargets = [target]; continue; } @@ -291,25 +321,21 @@ const splitChannelReminderMessages = ( }; const sendIssueReminderChunk = async ( - channel: keyof typeof ISSUE_REMINDER_CHANNELS, channelId: string, chunk: { content: string; targets: IssueReminderTarget[] }, ) => { try { await api.post(Routes.channelMessages(channelId), { body: { - embeds: [ - { - title: "Issue Reminders", - description: formatIssueReminderEmbedDescription(chunk.content), - color: 0xcca4f4, - }, - ], + content: chunk.content, allowed_mentions: getAllowedMentions(chunk.targets), }, }); } catch (error) { - logger.error(`Failed sending issue reminder chunk for ${channel}.`, error); + logger.error( + `Failed sending issue reminder chunk for channel ${channelId}.`, + error, + ); } }; @@ -318,7 +344,7 @@ export const issueReminders = new CronBuilder({ color: 2, }).addCron("0 9 * * *", async () => { const issues = await db.query.Issue.findMany({ - where: and(isNotNull(Issue.date), ne(Issue.status, "FINISHED")), + where: and(isNotNull(Issue.date), ne(Issue.status, "Finished")), with: { userAssignments: { with: { @@ -343,7 +369,7 @@ export const issueReminders = new CronBuilder({ string, { discordRoleId: string; - issueReminderChannel: keyof typeof ISSUE_REMINDER_CHANNELS | null; + issueReminderChannel: string; } > = {}; for (const r of roles) { @@ -355,41 +381,40 @@ export const issueReminders = new CronBuilder({ const reminderTargets = issues .map((issue) => { const role = roleDataByTeamId[issue.team]; - if (!role?.issueReminderChannel) { + if (!role) { logger.warn( - `Skipping issue reminder: no issue reminder channel configured for team ${issue.team}.`, + `Skipping issue reminder: no role row for team ${issue.team}.`, ); + return null; } + const discordChannelId = resolveDestinationChannelId( + role.issueReminderChannel, + ); return buildIssueReminderTarget({ id: issue.id, name: issue.name, + priority: issue.priority, + updatedAt: issue.updatedAt, team: issue.team, date: issue.date, - teamDiscordRoleId: role?.discordRoleId ?? "", + teamDiscordRoleId: role.discordRoleId, assigneeDiscordUserIds: issue.userAssignments.map( (assignment) => assignment.user.discordUserId, ), - channel: role?.issueReminderChannel ?? null, + discordChannelId, }); }) .filter(isIssueReminderTarget); const groupedReminders = groupIssueReminderTargets(reminderTargets); - for (const channel of Object.keys( - ISSUE_REMINDER_CHANNELS, - ) as (keyof typeof ISSUE_REMINDER_CHANNELS)[]) { - const groupedChannel = groupedReminders[channel]; + for (const [channelId, groupedChannel] of Object.entries(groupedReminders)) { if (!groupedChannel) continue; const chunks = splitChannelReminderMessages(groupedChannel); if (chunks.length === 0) continue; for (const chunk of chunks) { - await sendIssueReminderChunk( - channel, - ISSUE_REMINDER_DESTINATION_CHANNEL_IDS[channel], - chunk, - ); + await sendIssueReminderChunk(channelId, chunk); } } }); diff --git a/packages/api/src/routers/issues.ts b/packages/api/src/routers/issues.ts index 76f85f7ab..0cce1a27b 100644 --- a/packages/api/src/routers/issues.ts +++ b/packages/api/src/routers/issues.ts @@ -3,7 +3,7 @@ import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { ISSUE } from "@forge/consts"; -import { and, eq, exists, inArray, sql } from "@forge/db"; +import { and, eq, exists, inArray, or, sql } from "@forge/db"; import { db } from "@forge/db/client"; import { Permissions, User } from "@forge/db/schemas/auth"; import { @@ -36,6 +36,10 @@ type IssueCreateNode = z.infer & { children?: IssueCreateNode[]; }; +function ensureTeamVisible(teamId: string, teamVisibilityIds?: string[]) { + return Array.from(new Set([...(teamVisibilityIds ?? []), teamId])); +} + const issueCreateSchema: z.ZodType = baseIssueCreateSchema.extend({ children: z.lazy(() => z.array(issueCreateSchema)).optional(), @@ -64,9 +68,14 @@ async function createChildIssues( message: "Failed to create sub-issue.", }); } - if (teamVisibilityIds?.length) { + const ensuredTeamVisibilityIds = ensureTeamVisible( + rest.team, + teamVisibilityIds, + ); + + if (ensuredTeamVisibilityIds.length > 0) { await tx.insert(IssuesToTeamsVisibility).values( - teamVisibilityIds.map((teamId) => ({ + ensuredTeamVisibilityIds.map((teamId) => ({ issueId: created.id, teamId, })), @@ -95,6 +104,58 @@ async function requireIssue(id: string, label = "Issue") { return issue; } +async function collectIssueSubtreeIds( + tx: Parameters[0]>[0], + rootId: string, +) { + const allIds = [rootId]; + let frontier = [rootId]; + + while (frontier.length > 0) { + const children = await tx + .select({ id: Issue.id }) + .from(Issue) + .where(inArray(Issue.parent, frontier)); + + if (children.length === 0) break; + + frontier = children.map((child) => child.id); + allIds.push(...frontier); + } + + return allIds; +} + +async function issueVisibilityFilterForUser( + userId: string, + isOfficer: boolean, +) { + if (isOfficer) { + return sql`TRUE`; + } + + const userRoles = ( + await db.query.Permissions.findMany({ + where: eq(Permissions.userId, userId), + }) + ).map((permission) => permission.roleId); + + if (userRoles.length === 0) { + return sql`FALSE`; + } + + const visibleIssueIds = await db + .select({ issueId: IssuesToTeamsVisibility.issueId }) + .from(IssuesToTeamsVisibility) + .where(inArray(IssuesToTeamsVisibility.teamId, userRoles)); + + const visibilityIssueIds = visibleIssueIds.map((row) => row.issueId); + + return visibilityIssueIds.length > 0 + ? or(inArray(Issue.team, userRoles), inArray(Issue.id, visibilityIssueIds)) + : inArray(Issue.team, userRoles); +} + const baseIssueTemplateSchema = z.object({ title: z.string().min(1, "Title is required"), description: z.string().optional(), @@ -166,6 +227,10 @@ export const issuesRouter = { return await db.transaction(async (tx) => { const { teamVisibilityIds, assigneeIds, children, ...rest } = input; + const ensuredTeamVisibilityIds = ensureTeamVisible( + input.team, + teamVisibilityIds, + ); await permissionsServer.validateAssigneesBelongToTeam( tx, @@ -191,9 +256,9 @@ export const issuesRouter = { }); } - if (teamVisibilityIds?.length) { + if (ensuredTeamVisibilityIds.length > 0) { await tx.insert(IssuesToTeamsVisibility).values( - teamVisibilityIds.map((teamId) => ({ + ensuredTeamVisibilityIds.map((teamId) => ({ issueId: issue.id, teamId, })), @@ -226,31 +291,10 @@ export const issuesRouter = { .query(async ({ ctx, input }) => { permissions.controlPerms.or(["READ_ISSUES"], ctx); - let visibilityFilter; - - if (ctx.session.permissions.IS_OFFICER) { - visibilityFilter = sql`TRUE`; - } else { - const userRoles = ( - await db.query.Permissions.findMany({ - where: eq(Permissions.userId, ctx.session.user.id), - }) - ).map((p) => p.roleId); - visibilityFilter = - userRoles.length === 0 - ? sql`FALSE` - : exists( - db - .select() - .from(IssuesToTeamsVisibility) - .where( - and( - eq(IssuesToTeamsVisibility.issueId, Issue.id), - inArray(IssuesToTeamsVisibility.teamId, userRoles), - ), - ), - ); - } + const visibilityFilter = await issueVisibilityFilterForUser( + ctx.session.user.id, + Boolean(ctx.session.permissions.IS_OFFICER), + ); const issue = await db.query.Issue.findFirst({ where: and(eq(Issue.id, input.id), visibilityFilter), with: { @@ -297,31 +341,10 @@ export const issuesRouter = { ); } - let visibilityFilter; - - if (ctx.session.permissions.IS_OFFICER) { - visibilityFilter = sql`TRUE`; - } else { - const userRoles = ( - await db.query.Permissions.findMany({ - where: eq(Permissions.userId, ctx.session.user.id), - }) - ).map((p) => p.roleId); - visibilityFilter = - userRoles.length === 0 - ? sql`FALSE` - : exists( - db - .select() - .from(IssuesToTeamsVisibility) - .where( - and( - eq(IssuesToTeamsVisibility.issueId, Issue.id), - inArray(IssuesToTeamsVisibility.teamId, userRoles), - ), - ), - ); - } + const visibilityFilter = await issueVisibilityFilterForUser( + ctx.session.user.id, + Boolean(ctx.session.permissions.IS_OFFICER), + ); if (input?.assigneeIds?.length) { filters.push( @@ -400,6 +423,10 @@ export const issuesRouter = { ); const { id, assigneeIds, teamVisibilityIds, ...fields } = input; + const ensuredTeamVisibilityIds = + teamVisibilityIds !== undefined + ? ensureTeamVisible(assignmentTeamId, teamVisibilityIds) + : undefined; const updateData = Object.fromEntries( (Object.entries(fields) as [string, unknown][]).filter( ([, v]) => v !== undefined, @@ -410,16 +437,17 @@ export const issuesRouter = { await tx.update(Issue).set(updateData).where(eq(Issue.id, id)); } - if (teamVisibilityIds !== undefined) { + if (ensuredTeamVisibilityIds !== undefined) { await tx .delete(IssuesToTeamsVisibility) .where(eq(IssuesToTeamsVisibility.issueId, id)); - if (teamVisibilityIds.length > 0) { - await tx - .insert(IssuesToTeamsVisibility) - .values( - teamVisibilityIds.map((teamId) => ({ issueId: id, teamId })), - ); + if (ensuredTeamVisibilityIds.length > 0) { + await tx.insert(IssuesToTeamsVisibility).values( + ensuredTeamVisibilityIds.map((teamId) => ({ + issueId: id, + teamId, + })), + ); } } @@ -436,7 +464,7 @@ export const issuesRouter = { if ( Object.keys(updateData).length === 0 && - (teamVisibilityIds !== undefined || assigneeIds !== undefined) + (ensuredTeamVisibilityIds !== undefined || assigneeIds !== undefined) ) { await tx .update(Issue) @@ -459,7 +487,10 @@ export const issuesRouter = { permissions.controlPerms.or(["EDIT_ISSUES"], ctx); await requireIssue(input.id); - await db.delete(Issue).where(eq(Issue.id, input.id)); + await db.transaction(async (tx) => { + const issueIds = await collectIssueSubtreeIds(tx, input.id); + await tx.delete(Issue).where(inArray(Issue.id, issueIds)); + }); return { success: true }; }), diff --git a/packages/api/src/routers/roles.ts b/packages/api/src/routers/roles.ts index 784b711c9..6aa6962aa 100644 --- a/packages/api/src/routers/roles.ts +++ b/packages/api/src/routers/roles.ts @@ -13,6 +13,22 @@ import * as discord from "@forge/utils/discord"; import { permProcedure, protectedProcedure } from "../trpc"; +function discordRoleColorToHex(role: APIRole | null) { + if (!role || role.color <= 0) return null; + return `#${role.color.toString(16).padStart(6, "0")}`; +} + +async function fetchDiscordRoleHexColor(roleId: string) { + try { + const role = (await discord.api.get( + Routes.guildRole(DISCORD.KNIGHTHACKS_GUILD, roleId), + )) as APIRole | null; + return discordRoleColorToHex(role); + } catch { + return null; + } +} + export const rolesRouter = { // ROLES @@ -37,6 +53,8 @@ export const rolesRouter = { code: "CONFLICT", }); + const teamHexcodeColor = await fetchDiscordRoleHexColor(input.roleId); + // Create the role link first const insertedRoles = await db .insert(Roles) @@ -44,6 +62,7 @@ export const rolesRouter = { name: input.name, discordRoleId: input.roleId, permissions: input.permissions, + teamHexcodeColor, }) .returning(); @@ -145,12 +164,15 @@ export const rolesRouter = { code: "CONFLICT", }); + const teamHexcodeColor = await fetchDiscordRoleHexColor(input.roleId); + await db .update(Roles) .set({ name: input.name, discordRoleId: input.roleId, permissions: input.permissions, + teamHexcodeColor, }) .where(eq(Roles.id, input.id)); diff --git a/packages/consts/src/index.ts b/packages/consts/src/index.ts index 623f4b48b..b71ea4b36 100644 --- a/packages/consts/src/index.ts +++ b/packages/consts/src/index.ts @@ -1,3 +1,4 @@ +export { IS_PROD } from "./util"; export * as FORMS from "./forms"; export * as HACKATHONS from "./hackathons"; export * as PROJECT_LAUNCH from "./project-launch"; diff --git a/packages/consts/src/issue.ts b/packages/consts/src/issue.ts index 9241a24b1..e37ffe2c0 100644 --- a/packages/consts/src/issue.ts +++ b/packages/consts/src/issue.ts @@ -1,17 +1,20 @@ +export const DEFAULT_ISSUE_REMINDER_CHANNEL_ID = "1459204271655489567"; +export const DEV_ISSUE_REMINDER_CHANNEL_ID = "1263902679457992845"; + export const ISSUE_STATUS = [ - "BACKLOG", - "PLANNING", - "IN_PROGRESS", - "FINISHED", + "Backlog", + "Planning", + "In Progress", + "Finished", ] as const; -export const PRIORITY = ["LOWEST", "LOW", "MEDIUM", "HIGH", "HIGHEST"] as const; +export const PRIORITY = ["Lowest", "Low", "Medium", "High", "Highest"] as const; export const STATUS_COLORS: Record<(typeof ISSUE_STATUS)[number], string> = { - BACKLOG: "bg-slate-400", - PLANNING: "bg-amber-400", - IN_PROGRESS: "bg-emerald-400", - FINISHED: "bg-rose-400", + Backlog: "bg-slate-400", + Planning: "bg-amber-400", + "In Progress": "bg-emerald-400", + Finished: "bg-rose-400", }; export const TASK_DUE_HOURS = 23; @@ -61,6 +64,7 @@ export interface IssueFetcherPaneData { issues: IssueFetcherPaneIssue[]; blockedParentIds: Set; roleNameById: Map; + roleColorById: Map; isLoading: boolean; error: string | null; refresh: () => void; @@ -73,7 +77,7 @@ export const DEFAULT_ISSUE_FILTERS: IssueFilters = { searchTerm: "", dateFrom: "", dateTo: "", - rootOnly: true, + rootOnly: false, issueKind: "all", }; diff --git a/packages/db/drizzle/0002_dapper_forge.sql b/packages/db/drizzle/0002_dapper_forge.sql new file mode 100644 index 000000000..a2cc32be6 --- /dev/null +++ b/packages/db/drizzle/0002_dapper_forge.sql @@ -0,0 +1,4 @@ +ALTER TABLE "auth_roles" ALTER COLUMN "issue_reminder_channel" SET DATA TYPE varchar(32);--> statement-breakpoint +ALTER TABLE "auth_roles" ALTER COLUMN "issue_reminder_channel" SET DEFAULT '1459204271655489567';--> statement-breakpoint +ALTER TABLE "auth_roles" ALTER COLUMN "issue_reminder_channel" SET NOT NULL;--> statement-breakpoint +DROP TYPE "public"."issue_reminder_channel"; \ No newline at end of file diff --git a/packages/db/drizzle/0003_hot_killraven.sql b/packages/db/drizzle/0003_hot_killraven.sql new file mode 100644 index 000000000..91ad28eac --- /dev/null +++ b/packages/db/drizzle/0003_hot_killraven.sql @@ -0,0 +1 @@ +ALTER TABLE "auth_roles" ADD COLUMN "team_hexcode_color" varchar(7); \ No newline at end of file diff --git a/packages/db/drizzle/0004_youthful_galactus.sql b/packages/db/drizzle/0004_youthful_galactus.sql new file mode 100644 index 000000000..09429a7f6 --- /dev/null +++ b/packages/db/drizzle/0004_youthful_galactus.sql @@ -0,0 +1,8 @@ +ALTER TABLE "knight_hacks_issue" ALTER COLUMN "priority" SET DATA TYPE text;--> statement-breakpoint +DROP TYPE "public"."issue_priority";--> statement-breakpoint +CREATE TYPE "public"."issue_priority" AS ENUM('Lowest', 'Low', 'Medium', 'High', 'Highest');--> statement-breakpoint +ALTER TABLE "knight_hacks_issue" ALTER COLUMN "priority" SET DATA TYPE "public"."issue_priority" USING "priority"::"public"."issue_priority";--> statement-breakpoint +ALTER TABLE "knight_hacks_issue" ALTER COLUMN "status" SET DATA TYPE text;--> statement-breakpoint +DROP TYPE "public"."issue_status";--> statement-breakpoint +CREATE TYPE "public"."issue_status" AS ENUM('Backlog', 'Planning', 'In Progress', 'Finished');--> statement-breakpoint +ALTER TABLE "knight_hacks_issue" ALTER COLUMN "status" SET DATA TYPE "public"."issue_status" USING "status"::"public"."issue_status"; \ No newline at end of file diff --git a/packages/db/drizzle/meta/0002_snapshot.json b/packages/db/drizzle/meta/0002_snapshot.json new file mode 100644 index 000000000..388a28d86 --- /dev/null +++ b/packages/db/drizzle/meta/0002_snapshot.json @@ -0,0 +1,2736 @@ +{ + "id": "d293fee4-01a5-4e99-a06d-5b39520742ce", + "prevId": "41e22b5f-3477-4640-a21c-469f1df3e3d3", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "auth_account_provider_provider_account_id_pk": { + "name": "auth_account_provider_provider_account_id_pk", + "columns": ["provider", "provider_account_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_judge_session": { + "name": "auth_judge_session", + "schema": "", + "columns": { + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_permissions": { + "name": "auth_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "auth_permissions_role_id_auth_roles_id_fk": { + "name": "auth_permissions_role_id_auth_roles_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "auth_permissions_user_id_auth_user_id_fk": { + "name": "auth_permissions_user_id_auth_user_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_roles": { + "name": "auth_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "discord_role_id": { + "name": "discord_role_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "issue_reminder_channel": { + "name": "issue_reminder_channel", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'1459204271655489567'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_roles_discordRoleId_unique": { + "name": "auth_roles_discordRoleId_unique", + "nullsNotDistinct": false, + "columns": ["discord_role_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_user_id": { + "name": "discord_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_challenges": { + "name": "knight_hacks_challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sponsor": { + "name": "sponsor", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_challenges", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_challenges_title_hackathonId_unique": { + "name": "knight_hacks_challenges_title_hackathonId_unique", + "nullsNotDistinct": false, + "columns": ["title", "hackathon_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_dues_payment": { + "name": "knight_hacks_dues_payment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "payment_date": { + "name": "payment_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_dues_payment", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_dues_payment_memberId_year_unique": { + "name": "knight_hacks_dues_payment_memberId_year_unique", + "nullsNotDistinct": false, + "columns": ["member_id", "year"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event": { + "name": "knight_hacks_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_id": { + "name": "discord_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "google_id": { + "name": "google_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tag": { + "name": "tag", + "type": "event_tag", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_datetime": { + "name": "start_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_datetime": { + "name": "end_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "dues_paying": { + "name": "dues_paying", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_operations_calendar": { + "name": "is_operations_calendar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "roles": { + "name": "roles", + "type": "varchar(255)[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "discord_channel_id": { + "name": "discord_channel_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_event", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_attendee": { + "name": "knight_hacks_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_feedback": { + "name": "knight_hacks_event_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "overall_event_rating": { + "name": "overall_event_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fun_rating": { + "name": "fun_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "learned_rating": { + "name": "learned_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "heard_about_us": { + "name": "heard_about_us", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "additional_feedback": { + "name": "additional_feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "similar_event": { + "name": "similar_event", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response": { + "name": "knight_hacks_form_response", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "response_data": { + "name": "response_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "edited_at": { + "name": "edited_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_form_response_user_id_auth_user_id_fk": { + "name": "knight_hacks_form_response_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response_roles": { + "name": "knight_hacks_form_response_roles", + "schema": "", + "columns": { + "form_id": { + "name": "form_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_response_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_response_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_response_roles_form_id_role_id_pk": { + "name": "knight_hacks_form_response_roles_form_id_role_id_pk", + "columns": ["form_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_section_roles": { + "name": "knight_hacks_form_section_roles", + "schema": "", + "columns": { + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_section_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_section_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_section_roles_section_id_role_id_pk": { + "name": "knight_hacks_form_section_roles_section_id_role_id_pk", + "columns": ["section_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_sections": { + "name": "knight_hacks_form_sections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_sections_name_unique": { + "name": "knight_hacks_form_sections_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_schemas": { + "name": "knight_hacks_form_schemas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug_name": { + "name": "slug_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "dues_only": { + "name": "dues_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_resubmission": { + "name": "allow_resubmission", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_edit": { + "name": "allow_edit", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "form_data": { + "name": "form_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "form_validator_json": { + "name": "form_validator_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "section": { + "name": "section", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'General'" + }, + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "is_closed": { + "name": "is_closed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_schemas", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_schemas_slugName_unique": { + "name": "knight_hacks_form_schemas_slugName_unique", + "nullsNotDistinct": false, + "columns": ["slug_name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon": { + "name": "knight_hacks_hackathon", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "theme": { + "name": "theme", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "application_open": { + "name": "application_open", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "application_deadline": { + "name": "application_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "confirmation_deadline": { + "name": "confirmation_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "start_date": { + "name": "start_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon_sponsor": { + "name": "knight_hacks_hackathon_sponsor", + "schema": "", + "columns": { + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sponsor_id": { + "name": "sponsor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "sponsor_tier", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk": { + "name": "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_sponsor", + "columnsFrom": ["sponsor_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker": { + "name": "knight_hacks_hacker", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'United States of America'" + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "survey_1": { + "name": "survey_1", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "survey_2": { + "name": "survey_2", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_first_time": { + "name": "is_first_time", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_allergies": { + "name": "food_allergies", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agrees_to_receive_emails_from_mlh": { + "name": "agrees_to_receive_emails_from_mlh", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_code_of_conduct": { + "name": "agrees_to_mlh_code_of_conduct", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_data_sharing": { + "name": "agrees_to_mlh_data_sharing", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_user_id_auth_user_id_fk": { + "name": "knight_hacks_hacker_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_hacker", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_attendee": { + "name": "knight_hacks_hacker_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_id": { + "name": "hacker_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "time_applied": { + "name": "time_applied", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_confirmed": { + "name": "time_confirmed", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "class": { + "name": "class", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": null + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk": { + "name": "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hacker", + "columnsFrom": ["hacker_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_event_attendee": { + "name": "knight_hacks_hacker_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_att_id": { + "name": "hacker_att_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hacker_attendee", + "columnsFrom": ["hacker_att_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issue": { + "name": "knight_hacks_issue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "status": { + "name": "status", + "type": "issue_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "links": { + "name": "links", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "event": { + "name": "event", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "date": { + "name": "date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "issue_priority", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "team": { + "name": "team", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "parent": { + "name": "parent", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "issue_team_idx": { + "name": "issue_team_idx", + "columns": [ + { + "expression": "team", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_creator_idx": { + "name": "issue_creator_idx", + "columns": [ + { + "expression": "creator", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_status_idx": { + "name": "issue_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_date_idx": { + "name": "issue_date_idx", + "columns": [ + { + "expression": "date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_parent_idx": { + "name": "issue_parent_idx", + "columns": [ + { + "expression": "parent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_priority_idx": { + "name": "issue_priority_idx", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "knight_hacks_issue_event_knight_hacks_event_id_fk": { + "name": "knight_hacks_issue_event_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "knight_hacks_issue_team_auth_roles_id_fk": { + "name": "knight_hacks_issue_team_auth_roles_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_roles", + "columnsFrom": ["team"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "knight_hacks_issue_creator_auth_user_id_fk": { + "name": "knight_hacks_issue_creator_auth_user_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_user", + "columnsFrom": ["creator"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "issue_parent_fk": { + "name": "issue_parent_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["parent"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_teams_visibility": { + "name": "knight_hacks_issues_to_teams_visibility", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "auth_roles", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk", + "columns": ["issue_id", "team_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_users_assignment": { + "name": "knight_hacks_issues_to_users_assignment", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk", + "columns": ["issue_id", "user_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judged_submission": { + "name": "knight_hacks_judged_submission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "judge_id": { + "name": "judge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "private_feedback": { + "name": "private_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_feedback": { + "name": "public_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "originality_rating": { + "name": "originality_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "design_rating": { + "name": "design_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "technical_understanding_rating": { + "name": "technical_understanding_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "implementation_rating": { + "name": "implementation_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "wow_factor_rating": { + "name": "wow_factor_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk": { + "name": "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_submissions", + "columnsFrom": ["submission_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk": { + "name": "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_judges", + "columnsFrom": ["judge_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judges": { + "name": "knight_hacks_judges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_judges", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_member": { + "name": "knight_hacks_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "guild_profile_visible": { + "name": "guild_profile_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "tagline": { + "name": "tagline", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "about": { + "name": "about", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "profile_picture_url": { + "name": "profile_picture_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "company": { + "name": "company", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_member_user_id_auth_user_id_fk": { + "name": "knight_hacks_member_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_member", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_member_email_unique": { + "name": "knight_hacks_member_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + }, + "knight_hacks_member_phoneNumber_unique": { + "name": "knight_hacks_member_phoneNumber_unique", + "nullsNotDistinct": false, + "columns": ["phone_number"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_companies": { + "name": "knight_hacks_companies", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_sponsor": { + "name": "knight_hacks_sponsor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo_url": { + "name": "logo_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_submissions": { + "name": "knight_hacks_submissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk": { + "name": "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_teams", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_submissions_teamId_challengeId_unique": { + "name": "knight_hacks_submissions_teamId_challengeId_unique", + "nullsNotDistinct": false, + "columns": ["team_id", "challenge_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_teams": { + "name": "knight_hacks_teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_title": { + "name": "project_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_url": { + "name": "submission_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_created_at": { + "name": "project_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "is_project_submitted": { + "name": "is_project_submitted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "devpost_url": { + "name": "devpost_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "universities": { + "name": "universities", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emails": { + "name": "emails", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "match_key": { + "name": "match_key", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_teams", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_teams_matchKey_unique": { + "name": "knight_hacks_teams_matchKey_unique", + "nullsNotDistinct": false, + "columns": ["match_key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_template": { + "name": "knight_hacks_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_trpc_form_connection": { + "name": "knight_hacks_trpc_form_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "proc": { + "name": "proc", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "connections": { + "name": "connections", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_trpc_form_connection", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.event_tag": { + "name": "event_tag", + "schema": "public", + "values": [ + "GBM", + "Social", + "Kickstart", + "Project Launch", + "Hello World", + "Sponsorship", + "Tech Exploration", + "Class Support", + "Workshop", + "OPS", + "Collabs", + "Check-in", + "Merch", + "Food", + "Ceremony", + "CAREER-FAIR", + "RSO-FAIR" + ] + }, + "public.gender": { + "name": "gender", + "schema": "public", + "values": [ + "Man", + "Woman", + "Non-binary", + "Prefer to self-describe", + "Prefer not to answer" + ] + }, + "public.hackathon_application_state": { + "name": "hackathon_application_state", + "schema": "public", + "values": [ + "withdrawn", + "pending", + "accepted", + "waitlisted", + "checkedin", + "confirmed", + "denied" + ] + }, + "public.issue_priority": { + "name": "issue_priority", + "schema": "public", + "values": ["LOWEST", "LOW", "MEDIUM", "HIGH", "HIGHEST"] + }, + "public.issue_status": { + "name": "issue_status", + "schema": "public", + "values": ["BACKLOG", "PLANNING", "IN_PROGRESS", "FINISHED"] + }, + "public.race_or_ethnicity": { + "name": "race_or_ethnicity", + "schema": "public", + "values": [ + "White", + "Black or African American", + "Hispanic / Latino / Spanish Origin", + "Asian", + "Native Hawaiian or Other Pacific Islander", + "Native American or Alaskan Native", + "Middle Eastern", + "Prefer not to answer", + "Other" + ] + }, + "public.shirt_size": { + "name": "shirt_size", + "schema": "public", + "values": ["XS", "S", "M", "L", "XL", "2XL", "3XL"] + }, + "public.sponsor_tier": { + "name": "sponsor_tier", + "schema": "public", + "values": ["gold", "silver", "bronze", "other"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/packages/db/drizzle/meta/0003_snapshot.json b/packages/db/drizzle/meta/0003_snapshot.json new file mode 100644 index 000000000..aff9ff3e9 --- /dev/null +++ b/packages/db/drizzle/meta/0003_snapshot.json @@ -0,0 +1,2742 @@ +{ + "id": "3c88a643-8696-4819-afc0-11117b8e124e", + "prevId": "d293fee4-01a5-4e99-a06d-5b39520742ce", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "auth_account_provider_provider_account_id_pk": { + "name": "auth_account_provider_provider_account_id_pk", + "columns": ["provider", "provider_account_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_judge_session": { + "name": "auth_judge_session", + "schema": "", + "columns": { + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_permissions": { + "name": "auth_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "auth_permissions_role_id_auth_roles_id_fk": { + "name": "auth_permissions_role_id_auth_roles_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "auth_permissions_user_id_auth_user_id_fk": { + "name": "auth_permissions_user_id_auth_user_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_roles": { + "name": "auth_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "discord_role_id": { + "name": "discord_role_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "issue_reminder_channel": { + "name": "issue_reminder_channel", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'1459204271655489567'" + }, + "team_hexcode_color": { + "name": "team_hexcode_color", + "type": "varchar(7)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_roles_discordRoleId_unique": { + "name": "auth_roles_discordRoleId_unique", + "nullsNotDistinct": false, + "columns": ["discord_role_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_user_id": { + "name": "discord_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_challenges": { + "name": "knight_hacks_challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sponsor": { + "name": "sponsor", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_challenges", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_challenges_title_hackathonId_unique": { + "name": "knight_hacks_challenges_title_hackathonId_unique", + "nullsNotDistinct": false, + "columns": ["title", "hackathon_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_dues_payment": { + "name": "knight_hacks_dues_payment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "payment_date": { + "name": "payment_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_dues_payment", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_dues_payment_memberId_year_unique": { + "name": "knight_hacks_dues_payment_memberId_year_unique", + "nullsNotDistinct": false, + "columns": ["member_id", "year"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event": { + "name": "knight_hacks_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_id": { + "name": "discord_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "google_id": { + "name": "google_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tag": { + "name": "tag", + "type": "event_tag", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_datetime": { + "name": "start_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_datetime": { + "name": "end_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "dues_paying": { + "name": "dues_paying", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_operations_calendar": { + "name": "is_operations_calendar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "roles": { + "name": "roles", + "type": "varchar(255)[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "discord_channel_id": { + "name": "discord_channel_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_event", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_attendee": { + "name": "knight_hacks_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_feedback": { + "name": "knight_hacks_event_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "overall_event_rating": { + "name": "overall_event_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fun_rating": { + "name": "fun_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "learned_rating": { + "name": "learned_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "heard_about_us": { + "name": "heard_about_us", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "additional_feedback": { + "name": "additional_feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "similar_event": { + "name": "similar_event", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response": { + "name": "knight_hacks_form_response", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "response_data": { + "name": "response_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "edited_at": { + "name": "edited_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_form_response_user_id_auth_user_id_fk": { + "name": "knight_hacks_form_response_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response_roles": { + "name": "knight_hacks_form_response_roles", + "schema": "", + "columns": { + "form_id": { + "name": "form_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_response_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_response_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_response_roles_form_id_role_id_pk": { + "name": "knight_hacks_form_response_roles_form_id_role_id_pk", + "columns": ["form_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_section_roles": { + "name": "knight_hacks_form_section_roles", + "schema": "", + "columns": { + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_section_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_section_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_section_roles_section_id_role_id_pk": { + "name": "knight_hacks_form_section_roles_section_id_role_id_pk", + "columns": ["section_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_sections": { + "name": "knight_hacks_form_sections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_sections_name_unique": { + "name": "knight_hacks_form_sections_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_schemas": { + "name": "knight_hacks_form_schemas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug_name": { + "name": "slug_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "dues_only": { + "name": "dues_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_resubmission": { + "name": "allow_resubmission", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_edit": { + "name": "allow_edit", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "form_data": { + "name": "form_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "form_validator_json": { + "name": "form_validator_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "section": { + "name": "section", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'General'" + }, + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "is_closed": { + "name": "is_closed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_schemas", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_schemas_slugName_unique": { + "name": "knight_hacks_form_schemas_slugName_unique", + "nullsNotDistinct": false, + "columns": ["slug_name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon": { + "name": "knight_hacks_hackathon", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "theme": { + "name": "theme", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "application_open": { + "name": "application_open", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "application_deadline": { + "name": "application_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "confirmation_deadline": { + "name": "confirmation_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "start_date": { + "name": "start_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon_sponsor": { + "name": "knight_hacks_hackathon_sponsor", + "schema": "", + "columns": { + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sponsor_id": { + "name": "sponsor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "sponsor_tier", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk": { + "name": "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_sponsor", + "columnsFrom": ["sponsor_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker": { + "name": "knight_hacks_hacker", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'United States of America'" + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "survey_1": { + "name": "survey_1", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "survey_2": { + "name": "survey_2", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_first_time": { + "name": "is_first_time", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_allergies": { + "name": "food_allergies", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agrees_to_receive_emails_from_mlh": { + "name": "agrees_to_receive_emails_from_mlh", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_code_of_conduct": { + "name": "agrees_to_mlh_code_of_conduct", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_data_sharing": { + "name": "agrees_to_mlh_data_sharing", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_user_id_auth_user_id_fk": { + "name": "knight_hacks_hacker_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_hacker", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_attendee": { + "name": "knight_hacks_hacker_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_id": { + "name": "hacker_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "time_applied": { + "name": "time_applied", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_confirmed": { + "name": "time_confirmed", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "class": { + "name": "class", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": null + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk": { + "name": "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hacker", + "columnsFrom": ["hacker_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_event_attendee": { + "name": "knight_hacks_hacker_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_att_id": { + "name": "hacker_att_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hacker_attendee", + "columnsFrom": ["hacker_att_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issue": { + "name": "knight_hacks_issue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "status": { + "name": "status", + "type": "issue_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "links": { + "name": "links", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "event": { + "name": "event", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "date": { + "name": "date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "issue_priority", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "team": { + "name": "team", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "parent": { + "name": "parent", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "issue_team_idx": { + "name": "issue_team_idx", + "columns": [ + { + "expression": "team", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_creator_idx": { + "name": "issue_creator_idx", + "columns": [ + { + "expression": "creator", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_status_idx": { + "name": "issue_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_date_idx": { + "name": "issue_date_idx", + "columns": [ + { + "expression": "date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_parent_idx": { + "name": "issue_parent_idx", + "columns": [ + { + "expression": "parent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_priority_idx": { + "name": "issue_priority_idx", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "knight_hacks_issue_event_knight_hacks_event_id_fk": { + "name": "knight_hacks_issue_event_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "knight_hacks_issue_team_auth_roles_id_fk": { + "name": "knight_hacks_issue_team_auth_roles_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_roles", + "columnsFrom": ["team"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "knight_hacks_issue_creator_auth_user_id_fk": { + "name": "knight_hacks_issue_creator_auth_user_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_user", + "columnsFrom": ["creator"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "issue_parent_fk": { + "name": "issue_parent_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["parent"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_teams_visibility": { + "name": "knight_hacks_issues_to_teams_visibility", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "auth_roles", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk", + "columns": ["issue_id", "team_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_users_assignment": { + "name": "knight_hacks_issues_to_users_assignment", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk", + "columns": ["issue_id", "user_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judged_submission": { + "name": "knight_hacks_judged_submission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "judge_id": { + "name": "judge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "private_feedback": { + "name": "private_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_feedback": { + "name": "public_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "originality_rating": { + "name": "originality_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "design_rating": { + "name": "design_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "technical_understanding_rating": { + "name": "technical_understanding_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "implementation_rating": { + "name": "implementation_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "wow_factor_rating": { + "name": "wow_factor_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk": { + "name": "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_submissions", + "columnsFrom": ["submission_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk": { + "name": "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_judges", + "columnsFrom": ["judge_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judges": { + "name": "knight_hacks_judges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_judges", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_member": { + "name": "knight_hacks_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "guild_profile_visible": { + "name": "guild_profile_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "tagline": { + "name": "tagline", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "about": { + "name": "about", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "profile_picture_url": { + "name": "profile_picture_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "company": { + "name": "company", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_member_user_id_auth_user_id_fk": { + "name": "knight_hacks_member_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_member", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_member_email_unique": { + "name": "knight_hacks_member_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + }, + "knight_hacks_member_phoneNumber_unique": { + "name": "knight_hacks_member_phoneNumber_unique", + "nullsNotDistinct": false, + "columns": ["phone_number"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_companies": { + "name": "knight_hacks_companies", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_sponsor": { + "name": "knight_hacks_sponsor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo_url": { + "name": "logo_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_submissions": { + "name": "knight_hacks_submissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk": { + "name": "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_teams", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_submissions_teamId_challengeId_unique": { + "name": "knight_hacks_submissions_teamId_challengeId_unique", + "nullsNotDistinct": false, + "columns": ["team_id", "challenge_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_teams": { + "name": "knight_hacks_teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_title": { + "name": "project_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_url": { + "name": "submission_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_created_at": { + "name": "project_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "is_project_submitted": { + "name": "is_project_submitted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "devpost_url": { + "name": "devpost_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "universities": { + "name": "universities", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emails": { + "name": "emails", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "match_key": { + "name": "match_key", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_teams", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_teams_matchKey_unique": { + "name": "knight_hacks_teams_matchKey_unique", + "nullsNotDistinct": false, + "columns": ["match_key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_template": { + "name": "knight_hacks_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_trpc_form_connection": { + "name": "knight_hacks_trpc_form_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "proc": { + "name": "proc", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "connections": { + "name": "connections", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_trpc_form_connection", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.event_tag": { + "name": "event_tag", + "schema": "public", + "values": [ + "GBM", + "Social", + "Kickstart", + "Project Launch", + "Hello World", + "Sponsorship", + "Tech Exploration", + "Class Support", + "Workshop", + "OPS", + "Collabs", + "Check-in", + "Merch", + "Food", + "Ceremony", + "CAREER-FAIR", + "RSO-FAIR" + ] + }, + "public.gender": { + "name": "gender", + "schema": "public", + "values": [ + "Man", + "Woman", + "Non-binary", + "Prefer to self-describe", + "Prefer not to answer" + ] + }, + "public.hackathon_application_state": { + "name": "hackathon_application_state", + "schema": "public", + "values": [ + "withdrawn", + "pending", + "accepted", + "waitlisted", + "checkedin", + "confirmed", + "denied" + ] + }, + "public.issue_priority": { + "name": "issue_priority", + "schema": "public", + "values": ["LOWEST", "LOW", "MEDIUM", "HIGH", "HIGHEST"] + }, + "public.issue_status": { + "name": "issue_status", + "schema": "public", + "values": ["BACKLOG", "PLANNING", "IN_PROGRESS", "FINISHED"] + }, + "public.race_or_ethnicity": { + "name": "race_or_ethnicity", + "schema": "public", + "values": [ + "White", + "Black or African American", + "Hispanic / Latino / Spanish Origin", + "Asian", + "Native Hawaiian or Other Pacific Islander", + "Native American or Alaskan Native", + "Middle Eastern", + "Prefer not to answer", + "Other" + ] + }, + "public.shirt_size": { + "name": "shirt_size", + "schema": "public", + "values": ["XS", "S", "M", "L", "XL", "2XL", "3XL"] + }, + "public.sponsor_tier": { + "name": "sponsor_tier", + "schema": "public", + "values": ["gold", "silver", "bronze", "other"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/packages/db/drizzle/meta/0004_snapshot.json b/packages/db/drizzle/meta/0004_snapshot.json new file mode 100644 index 000000000..a2ac882fc --- /dev/null +++ b/packages/db/drizzle/meta/0004_snapshot.json @@ -0,0 +1,2742 @@ +{ + "id": "e9c3b450-eddc-4738-bdb9-b33a461431a2", + "prevId": "3c88a643-8696-4819-afc0-11117b8e124e", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "auth_account_provider_provider_account_id_pk": { + "name": "auth_account_provider_provider_account_id_pk", + "columns": ["provider", "provider_account_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_judge_session": { + "name": "auth_judge_session", + "schema": "", + "columns": { + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_permissions": { + "name": "auth_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "auth_permissions_role_id_auth_roles_id_fk": { + "name": "auth_permissions_role_id_auth_roles_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "auth_permissions_user_id_auth_user_id_fk": { + "name": "auth_permissions_user_id_auth_user_id_fk", + "tableFrom": "auth_permissions", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_roles": { + "name": "auth_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "discord_role_id": { + "name": "discord_role_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "issue_reminder_channel": { + "name": "issue_reminder_channel", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'1459204271655489567'" + }, + "team_hexcode_color": { + "name": "team_hexcode_color", + "type": "varchar(7)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "auth_roles_discordRoleId_unique": { + "name": "auth_roles_discordRoleId_unique", + "nullsNotDistinct": false, + "columns": ["discord_role_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "session_token": { + "name": "session_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "varchar(1024)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_user_id": { + "name": "discord_user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_challenges": { + "name": "knight_hacks_challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sponsor": { + "name": "sponsor", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_challenges_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_challenges", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_challenges_title_hackathonId_unique": { + "name": "knight_hacks_challenges_title_hackathonId_unique", + "nullsNotDistinct": false, + "columns": ["title", "hackathon_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_dues_payment": { + "name": "knight_hacks_dues_payment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "payment_date": { + "name": "payment_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_dues_payment_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_dues_payment", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_dues_payment_memberId_year_unique": { + "name": "knight_hacks_dues_payment_memberId_year_unique", + "nullsNotDistinct": false, + "columns": ["member_id", "year"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event": { + "name": "knight_hacks_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "discord_id": { + "name": "discord_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "google_id": { + "name": "google_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "tag": { + "name": "tag", + "type": "event_tag", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_datetime": { + "name": "start_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_datetime": { + "name": "end_datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "dues_paying": { + "name": "dues_paying", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_operations_calendar": { + "name": "is_operations_calendar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "roles": { + "name": "roles", + "type": "varchar(255)[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "discord_channel_id": { + "name": "discord_channel_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_event_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_event", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_attendee": { + "name": "knight_hacks_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_attendee_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_event_feedback": { + "name": "knight_hacks_event_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "overall_event_rating": { + "name": "overall_event_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fun_rating": { + "name": "fun_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "learned_rating": { + "name": "learned_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "heard_about_us": { + "name": "heard_about_us", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "additional_feedback": { + "name": "additional_feedback", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "similar_event": { + "name": "similar_event", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk": { + "name": "knight_hacks_event_feedback_member_id_knight_hacks_member_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_member", + "columnsFrom": ["member_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_event_feedback_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_event_feedback", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response": { + "name": "knight_hacks_form_response", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "response_data": { + "name": "response_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "edited_at": { + "name": "edited_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_form_response_user_id_auth_user_id_fk": { + "name": "knight_hacks_form_response_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_form_response", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_response_roles": { + "name": "knight_hacks_form_response_roles", + "schema": "", + "columns": { + "form_id": { + "name": "form_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_form_response_roles_form_id_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_response_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_response_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_response_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_response_roles_form_id_role_id_pk": { + "name": "knight_hacks_form_response_roles_form_id_role_id_pk", + "columns": ["form_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_section_roles": { + "name": "knight_hacks_form_section_roles", + "schema": "", + "columns": { + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_section_roles_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_form_section_roles_role_id_auth_roles_id_fk": { + "name": "knight_hacks_form_section_roles_role_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_form_section_roles", + "tableTo": "auth_roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_form_section_roles_section_id_role_id_pk": { + "name": "knight_hacks_form_section_roles_section_id_role_id_pk", + "columns": ["section_id", "role_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_sections": { + "name": "knight_hacks_form_sections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_sections_name_unique": { + "name": "knight_hacks_form_sections_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_form_schemas": { + "name": "knight_hacks_form_schemas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug_name": { + "name": "slug_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "dues_only": { + "name": "dues_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_resubmission": { + "name": "allow_resubmission", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allow_edit": { + "name": "allow_edit", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "form_data": { + "name": "form_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "form_validator_json": { + "name": "form_validator_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "section": { + "name": "section", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'General'" + }, + "section_id": { + "name": "section_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "is_closed": { + "name": "is_closed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk": { + "name": "knight_hacks_form_schemas_section_id_knight_hacks_form_sections_id_fk", + "tableFrom": "knight_hacks_form_schemas", + "tableTo": "knight_hacks_form_sections", + "columnsFrom": ["section_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_form_schemas_slugName_unique": { + "name": "knight_hacks_form_schemas_slugName_unique", + "nullsNotDistinct": false, + "columns": ["slug_name"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon": { + "name": "knight_hacks_hackathon", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "theme": { + "name": "theme", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "application_open": { + "name": "application_open", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "application_deadline": { + "name": "application_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "confirmation_deadline": { + "name": "confirmation_deadline", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "start_date": { + "name": "start_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hackathon_sponsor": { + "name": "knight_hacks_hackathon_sponsor", + "schema": "", + "columns": { + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sponsor_id": { + "name": "sponsor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "sponsor_tier", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hackathon_sponsor_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk": { + "name": "knight_hacks_hackathon_sponsor_sponsor_id_knight_hacks_sponsor_id_fk", + "tableFrom": "knight_hacks_hackathon_sponsor", + "tableTo": "knight_hacks_sponsor", + "columnsFrom": ["sponsor_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker": { + "name": "knight_hacks_hacker", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'United States of America'" + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "survey_1": { + "name": "survey_1", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "survey_2": { + "name": "survey_2", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_first_time": { + "name": "is_first_time", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_allergies": { + "name": "food_allergies", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agrees_to_receive_emails_from_mlh": { + "name": "agrees_to_receive_emails_from_mlh", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_code_of_conduct": { + "name": "agrees_to_mlh_code_of_conduct", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "agrees_to_mlh_data_sharing": { + "name": "agrees_to_mlh_data_sharing", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_user_id_auth_user_id_fk": { + "name": "knight_hacks_hacker_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_hacker", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_attendee": { + "name": "knight_hacks_hacker_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_id": { + "name": "hacker_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "time_applied": { + "name": "time_applied", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_confirmed": { + "name": "time_confirmed", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "class": { + "name": "class", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": null + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk": { + "name": "knight_hacks_hacker_attendee_hacker_id_knight_hacks_hacker_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hacker", + "columnsFrom": ["hacker_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_hacker_event_attendee": { + "name": "knight_hacks_hacker_event_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hacker_att_id": { + "name": "hacker_att_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hacker_att_id_knight_hacks_hacker_attendee_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hacker_attendee", + "columnsFrom": ["hacker_att_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_hacker_event_attendee_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk": { + "name": "knight_hacks_hacker_event_attendee_event_id_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_hacker_event_attendee", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issue": { + "name": "knight_hacks_issue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "status": { + "name": "status", + "type": "issue_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "links": { + "name": "links", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "event": { + "name": "event", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "date": { + "name": "date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "issue_priority", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "team": { + "name": "team", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "parent": { + "name": "parent", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "issue_team_idx": { + "name": "issue_team_idx", + "columns": [ + { + "expression": "team", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_creator_idx": { + "name": "issue_creator_idx", + "columns": [ + { + "expression": "creator", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_status_idx": { + "name": "issue_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_date_idx": { + "name": "issue_date_idx", + "columns": [ + { + "expression": "date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_parent_idx": { + "name": "issue_parent_idx", + "columns": [ + { + "expression": "parent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "issue_priority_idx": { + "name": "issue_priority_idx", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "knight_hacks_issue_event_knight_hacks_event_id_fk": { + "name": "knight_hacks_issue_event_knight_hacks_event_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_event", + "columnsFrom": ["event"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "knight_hacks_issue_team_auth_roles_id_fk": { + "name": "knight_hacks_issue_team_auth_roles_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_roles", + "columnsFrom": ["team"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "knight_hacks_issue_creator_auth_user_id_fk": { + "name": "knight_hacks_issue_creator_auth_user_id_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "auth_user", + "columnsFrom": ["creator"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "issue_parent_fk": { + "name": "issue_parent_fk", + "tableFrom": "knight_hacks_issue", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["parent"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_teams_visibility": { + "name": "knight_hacks_issues_to_teams_visibility", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk": { + "name": "knight_hacks_issues_to_teams_visibility_team_id_auth_roles_id_fk", + "tableFrom": "knight_hacks_issues_to_teams_visibility", + "tableTo": "auth_roles", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk": { + "name": "knight_hacks_issues_to_teams_visibility_issue_id_team_id_pk", + "columns": ["issue_id", "team_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_issues_to_users_assignment": { + "name": "knight_hacks_issues_to_users_assignment", + "schema": "", + "columns": { + "issue_id": { + "name": "issue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_knight_hacks_issue_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "knight_hacks_issue", + "columnsFrom": ["issue_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk": { + "name": "knight_hacks_issues_to_users_assignment_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_issues_to_users_assignment", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk": { + "name": "knight_hacks_issues_to_users_assignment_issue_id_user_id_pk", + "columns": ["issue_id", "user_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judged_submission": { + "name": "knight_hacks_judged_submission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "judge_id": { + "name": "judge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "private_feedback": { + "name": "private_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "public_feedback": { + "name": "public_feedback", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "originality_rating": { + "name": "originality_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "design_rating": { + "name": "design_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "technical_understanding_rating": { + "name": "technical_understanding_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "implementation_rating": { + "name": "implementation_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "wow_factor_rating": { + "name": "wow_factor_rating", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_judged_submission_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk": { + "name": "knight_hacks_judged_submission_submission_id_knight_hacks_submissions_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_submissions", + "columnsFrom": ["submission_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk": { + "name": "knight_hacks_judged_submission_judge_id_knight_hacks_judges_id_fk", + "tableFrom": "knight_hacks_judged_submission", + "tableTo": "knight_hacks_judges", + "columnsFrom": ["judge_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_judges": { + "name": "knight_hacks_judges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "room_name": { + "name": "room_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_judges_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_judges", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_member": { + "name": "knight_hacks_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "discord_user": { + "name": "discord_user", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "age": { + "name": "age", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "school": { + "name": "school", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "level_of_study": { + "name": "level_of_study", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "major": { + "name": "major", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Computer Science'" + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "race_or_ethnicity": { + "name": "race_or_ethnicity", + "type": "race_or_ethnicity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'Prefer not to answer'" + }, + "guild_profile_visible": { + "name": "guild_profile_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "tagline": { + "name": "tagline", + "type": "varchar(80)", + "primaryKey": false, + "notNull": false + }, + "about": { + "name": "about", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "profile_picture_url": { + "name": "profile_picture_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "shirt_size": { + "name": "shirt_size", + "type": "shirt_size", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "linkedin_profile_url": { + "name": "linkedin_profile_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "resume_url": { + "name": "resume_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dob": { + "name": "dob", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "grad_date": { + "name": "grad_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "company": { + "name": "company", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "date_created": { + "name": "date_created", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "time_created": { + "name": "time_created", + "type": "time", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_member_user_id_auth_user_id_fk": { + "name": "knight_hacks_member_user_id_auth_user_id_fk", + "tableFrom": "knight_hacks_member", + "tableTo": "auth_user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_member_email_unique": { + "name": "knight_hacks_member_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + }, + "knight_hacks_member_phoneNumber_unique": { + "name": "knight_hacks_member_phoneNumber_unique", + "nullsNotDistinct": false, + "columns": ["phone_number"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_companies": { + "name": "knight_hacks_companies", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_sponsor": { + "name": "knight_hacks_sponsor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo_url": { + "name": "logo_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "website_url": { + "name": "website_url", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_submissions": { + "name": "knight_hacks_submissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "challenge_id": { + "name": "challenge_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk": { + "name": "knight_hacks_submissions_challenge_id_knight_hacks_challenges_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_challenges", + "columnsFrom": ["challenge_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk": { + "name": "knight_hacks_submissions_team_id_knight_hacks_teams_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_teams", + "columnsFrom": ["team_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_submissions_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_submissions", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_submissions_teamId_challengeId_unique": { + "name": "knight_hacks_submissions_teamId_challengeId_unique", + "nullsNotDistinct": false, + "columns": ["team_id", "challenge_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_teams": { + "name": "knight_hacks_teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hackathon_id": { + "name": "hackathon_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_title": { + "name": "project_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_url": { + "name": "submission_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_created_at": { + "name": "project_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "is_project_submitted": { + "name": "is_project_submitted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "devpost_url": { + "name": "devpost_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "universities": { + "name": "universities", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emails": { + "name": "emails", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "match_key": { + "name": "match_key", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk": { + "name": "knight_hacks_teams_hackathon_id_knight_hacks_hackathon_id_fk", + "tableFrom": "knight_hacks_teams", + "tableTo": "knight_hacks_hackathon", + "columnsFrom": ["hackathon_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "knight_hacks_teams_matchKey_unique": { + "name": "knight_hacks_teams_matchKey_unique", + "nullsNotDistinct": false, + "columns": ["match_key"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_template": { + "name": "knight_hacks_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.knight_hacks_trpc_form_connection": { + "name": "knight_hacks_trpc_form_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "form": { + "name": "form", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "proc": { + "name": "proc", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "connections": { + "name": "connections", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk": { + "name": "knight_hacks_trpc_form_connection_form_knight_hacks_form_schemas_id_fk", + "tableFrom": "knight_hacks_trpc_form_connection", + "tableTo": "knight_hacks_form_schemas", + "columnsFrom": ["form"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.event_tag": { + "name": "event_tag", + "schema": "public", + "values": [ + "GBM", + "Social", + "Kickstart", + "Project Launch", + "Hello World", + "Sponsorship", + "Tech Exploration", + "Class Support", + "Workshop", + "OPS", + "Collabs", + "Check-in", + "Merch", + "Food", + "Ceremony", + "CAREER-FAIR", + "RSO-FAIR" + ] + }, + "public.gender": { + "name": "gender", + "schema": "public", + "values": [ + "Man", + "Woman", + "Non-binary", + "Prefer to self-describe", + "Prefer not to answer" + ] + }, + "public.hackathon_application_state": { + "name": "hackathon_application_state", + "schema": "public", + "values": [ + "withdrawn", + "pending", + "accepted", + "waitlisted", + "checkedin", + "confirmed", + "denied" + ] + }, + "public.issue_priority": { + "name": "issue_priority", + "schema": "public", + "values": ["Lowest", "Low", "Medium", "High", "Highest"] + }, + "public.issue_status": { + "name": "issue_status", + "schema": "public", + "values": ["Backlog", "Planning", "In Progress", "Finished"] + }, + "public.race_or_ethnicity": { + "name": "race_or_ethnicity", + "schema": "public", + "values": [ + "White", + "Black or African American", + "Hispanic / Latino / Spanish Origin", + "Asian", + "Native Hawaiian or Other Pacific Islander", + "Native American or Alaskan Native", + "Middle Eastern", + "Prefer not to answer", + "Other" + ] + }, + "public.shirt_size": { + "name": "shirt_size", + "schema": "public", + "values": ["XS", "S", "M", "L", "XL", "2XL", "3XL"] + }, + "public.sponsor_tier": { + "name": "sponsor_tier", + "schema": "public", + "values": ["gold", "silver", "bronze", "other"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index 928598a15..7ba672237 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -15,6 +15,27 @@ "when": 1776028259336, "tag": "0001_careless_eternity", "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1776104121304, + "tag": "0002_dapper_forge", + "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1776108776095, + "tag": "0003_hot_killraven", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1776180772365, + "tag": "0004_youthful_galactus", + "breakpoints": true } ] } diff --git a/packages/db/src/schemas/auth.ts b/packages/db/src/schemas/auth.ts index d84af45ac..b1f9464ac 100644 --- a/packages/db/src/schemas/auth.ts +++ b/packages/db/src/schemas/auth.ts @@ -1,14 +1,9 @@ -import { pgEnum, pgTableCreator, primaryKey } from "drizzle-orm/pg-core"; +import { pgTableCreator, primaryKey } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; -const createTable = pgTableCreator((name) => `auth_${name}`); +import { ISSUE } from "@forge/consts"; -export const IssueReminderChannelEnum = pgEnum("issue_reminder_channel", [ - "Teams", - "Directors", - "Design", - "HackOrg", -]); +const createTable = pgTableCreator((name) => `auth_${name}`); export const User = createTable("user", (t) => ({ id: t.uuid().notNull().primaryKey().defaultRandom(), @@ -44,7 +39,11 @@ export const Roles = createTable("roles", (t) => ({ name: t.varchar().notNull().default(""), discordRoleId: t.varchar().unique().notNull(), permissions: t.varchar().notNull(), - issueReminderChannel: IssueReminderChannelEnum(), + issueReminderChannel: t + .varchar({ length: 32 }) + .notNull() + .default(ISSUE.DEFAULT_ISSUE_REMINDER_CHANNEL_ID), + teamHexcodeColor: t.varchar({ length: 7 }), })); export const InsertRolesSchema = createInsertSchema(Roles);