Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
eee1f4f
feat(metrics): publish live hackathon counts for the weekend
aamoghS Oct 7, 2026
aaad2da
feat(panel): start a standalone judging core
aamoghS Oct 7, 2026
c3070d8
chore(deps): bump actions/upload-artifact from 4 to 6
dependabot[bot] Oct 8, 2026
429dba0
chore(deps): bump actions/download-artifact from 4 to 7
dependabot[bot] Oct 8, 2026
f4fa8fa
chore(deps-dev): bump vitest from 5.0.1 to 5.0.3
dependabot[bot] Oct 8, 2026
7f79a63
Merge pull request #478 from DataScience-GT/feat/telemetry-prod-grading
aamoghS Oct 8, 2026
907b688
Merge pull request #486 from DataScience-GT/dependabot/npm_and_yarn/d…
aamoghS Oct 8, 2026
3434dc2
chore(deps): bump @typescript-eslint/eslint-plugin from 8.70.1 to 8.7…
dependabot[bot] Oct 8, 2026
212c00a
Merge pull request #481 from DataScience-GT/dependabot/github_actions…
aamoghS Oct 8, 2026
cc354b3
chore(deps-dev): bump dotenv from 18.0.3 to 18.0.5 (#484)
dependabot[bot] Oct 8, 2026
98dda70
chore(deps-dev): bump turbo from 2.11.3 to 2.11.7 (#483)
dependabot[bot] Oct 8, 2026
4019558
Merge pull request #480 from DataScience-GT/dependabot/github_actions…
aamoghS Oct 8, 2026
5ee6873
feat(panel): run judging on the shared database
aamoghS Oct 8, 2026
e2d1bf5
fix(panel): keep the SQL migrations in the repo
aamoghS Oct 8, 2026
bfd6d02
refactor(panel): fold judging into the monorepo
aamoghS Oct 8, 2026
152e261
feat(panel): run judging inside the portal
aamoghS Oct 8, 2026
95446da
perf(panel): keep judging inside the Neon free plan
aamoghS Oct 8, 2026
24a43fd
feat(panel): tell a judge about a recall or a voided visit
aamoghS Oct 8, 2026
bba0354
feat(panel): judge each hackathon edition from the portal
aamoghS Oct 8, 2026
554b561
feat(judging): rework judging around rooms and add hackathon points
aamoghS Oct 13, 2026
ca24470
Merge remote-tracking branch 'origin/dev' into feat/panel
aamoghS Oct 13, 2026
0c21906
fix(metrics): satisfy lint in metrics service and its test
aamoghS Oct 13, 2026
395ee00
feat(judging): judging tables for general challenges
aamoghS Oct 14, 2026
9984601
feat(hacklytics): mobile header CTA, portal and judge links, hacker s…
aamoghS Oct 14, 2026
e3ffdd1
feat(hackathons): organizer console fixes for reviewing and running a…
aamoghS Oct 14, 2026
8742e0a
feat(check-in): continuous pass scanner and clearer check-in paths
aamoghS Oct 14, 2026
6a592ef
feat(hackathons): event page that follows the hacker through the weekend
aamoghS Oct 14, 2026
1c1c431
feat(teams): manage teams on the Teams tab, read-only submission for …
aamoghS Oct 14, 2026
534b5db
feat(judging): judge desk that holds up on a phone over a long weekend
aamoghS Oct 14, 2026
a08e657
feat(judging): judge applicant flow and judging emails
aamoghS Oct 14, 2026
515a4af
feat(hackathons): clearer judging and results tabs for hackers
aamoghS Oct 14, 2026
8a7bc98
test(api): stub email sends in router tests without loading the trans…
aamoghS Oct 14, 2026
05f8b3f
feat(hackathons): attendance confirmation, pending edits and desk admit
aamoghS Oct 14, 2026
2990173
feat(hackathons): in-app announcements and safer mass email
aamoghS Oct 14, 2026
1eff092
feat(hackathons): next-step strip and a focused nav during the event
aamoghS Oct 14, 2026
fe31f35
perf(judging): CP-SAT builds on the schedule it is given
aamoghS Oct 14, 2026
27c5604
perf(judging): faster greedy scheduler that places tight events
aamoghS Oct 14, 2026
e5b98c6
feat(judging): run CP-SAT on the server when Python is configured
aamoghS Oct 14, 2026
466474f
feat(judging): CP-SAT panel in the schedule planner
aamoghS Oct 14, 2026
b7bf0ed
fix(portal): subtle text meets 4.5:1 contrast in the light theme
aamoghS Oct 14, 2026
cf4e0de
style(hackathons): teams and submit read cleanly on a phone
aamoghS Oct 14, 2026
5f95985
style(judging): tidier rooms and tables admin
aamoghS Oct 14, 2026
038b446
style(auth): sign-in and code entry polish
aamoghS Oct 14, 2026
7a814f4
style(hacklytics): public site polish from a phone render review
aamoghS Oct 14, 2026
618f453
fix(portal): tab strips keep their width on phones; readable states o…
aamoghS Oct 14, 2026
06be1b5
style(hackathons): event page and dashboard polish from a phone review
aamoghS Oct 14, 2026
b40e959
style(hackathons): pass, schedule and points read better on a phone
aamoghS Oct 14, 2026
08b1ffa
style(judging): judge desk polish for phones in a loud hall
aamoghS Oct 14, 2026
a6cd8cd
style(check-in): door scanner and manual check-in polish
aamoghS Oct 14, 2026
e452e63
style(hackathons): judging, results and /hacklytics polish
aamoghS Oct 14, 2026
b151821
feat(hacklytics): globe and blossom favicon
aamoghS Oct 14, 2026
2c130f1
feat(judging): cancel CP-SAT with the request; schedule copy for tables
aamoghS Oct 15, 2026
484414a
fix(hacklytics): address review findings from #477
aamoghS Oct 15, 2026
e60be8d
Merge pull request #479 from DataScience-GT/feat/panel
aamoghS Oct 15, 2026
df9ec60
chore(deps): bump eslint-plugin-turbo from 2.11.3 to 2.11.7 (#482)
dependabot[bot] Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
run: pnpm turbo run build

- name: Upload Hacklytics build
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: hacklytics-out
path: sites/hacklytics2027/out
Expand All @@ -69,7 +69,7 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
name: hacklytics-out
path: sites/hacklytics2027/out
Expand All @@ -94,7 +94,7 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
name: hacklytics-out
path: sites/hacklytics2027/out
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ build
.DS_Store
*.pem
nul
__pycache__/

# Debug
npm-debug.log*
Expand Down
6 changes: 4 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ Edition-scoped event operations. Everything hangs off `hackathon`.

- Editions, interest list, registration, teams, project submission
- Weekend schedule (`hackathon_event`) and badge scans
- Judging (`judge`, `judging_project`, `judge_vote`, `judge_queue`, `hackathon_result`)
- Judge roster (`judge`, `judge_assignment`): applications and approval
- Judging: room-based judging with Devpost import — `judging_*` tables (`judging.ts`). The older pool-dispatch tables (`judging_project`, `judge_vote`, `judge_queue`, `hackathon_result`) are retired and kept for past editions' results
- Points: `hackathon_event` points, staff adjustments and the point store (`points.ts`)
- Announcements and acceptance waves

Hackathon participation is **open to non-members**. Membership is not a registration requirement.
Expand All @@ -68,7 +70,7 @@ Hackathon participation is **open to non-members**. Membership is not a registra
3. Browser calls `/api/trpc/*` via `@trpc/react-query`. Superjson is the transformer.
4. `createContext` loads the NextAuth session (when `db` exists), attaches `userId`, client IP, and the in-process cache.
5. Procedures run through DB-required, sanitizer, content-type, rate-limit / DDoS, and (for mutations) cache invalidation middleware.
6. Role gates (`isAdmin`, `isScanner`, `isJudge`, `isProjectLeader`, `isSuperAdmin`) live in `packages/api/src/middleware/procedures.ts`. There is no `adminProcedure` alias that skips a role check.
6. Role gates (`isAdmin`, `isScanner`, `isProjectLeader`, `isSuperAdmin`) live in `packages/api/src/middleware/procedures.ts`. There is no `adminProcedure` alias that skips a role check.

## Auth

Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Code owners: `.github/CODEOWNERS` assigns `*` to `@aamoghS`.
1. Branch from `dev` unless you are fixing production.
2. Keep club and hackathon concerns separate. Do not add `hackathon_id` to club tables.
3. Put shared rules in the package that every caller can import. Membership grant/link logic belongs in `@query/db/services/membership`, not copied into auth, Stripe, and tRPC.
4. Role checks go through `isAdmin` / `isScanner` / `isJudge` / `isProjectLeader` / `isSuperAdmin`. Do not invent an `adminProcedure` that is only `protectedProcedure`.
4. Role checks go through `isAdmin` / `isScanner` / `isProjectLeader` / `isSuperAdmin`. Do not invent an `adminProcedure` that is only `protectedProcedure`.
5. Dangerous HTML in tRPC input is **rejected**, not stripped. See [Security](./operations/security.md).
6. Prices live in `packages/api/src/services/pricing.ts`. Do not hard-code dollar amounts in UI or Stripe calls.

Expand Down
4 changes: 2 additions & 2 deletions docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
| **Staff** | Active admin whose role is not `volunteer`. |
| **Project leader** | `project_leader` row. Runs **club projects**. Not a staff role. |
| **Club project** | `initiative` row. Members apply to join with a pitch and an optional resume. Never judged. Distinct from a hackathon **project**, which is a judged submission. The UI says "club project"; the table is still `initiative`. |
| **Hackathon project** | Team/solo submission (`hackathon_project`). Promoted into `judging_project` for scoring. |
| **Hackathon project** | Team/solo submission (`hackathon_project`). Promoted into a `judging_entry` for judging, alongside projects imported from Devpost. |
| **Interest** | “Tell me when registration opens” (`hackathon_interest`). Requires a signed-in user. |
| **Current edition** | In-progress hackathon if one exists; otherwise the newest edition that is not `draft` or `announced`. |
| **Announced** | Public landing + interest, registration closed, **not** current for membership resolution. |
| **Wave** | Batch accept of oldest pending applicants; acceptance email is stamped per participant so retries are safe. |
| **Judging queue** | Per-judge ordered tables. `startedAt` is a short claim; `arrivedAt` is the QR scan at the table. |
| **Judging room** | `judging_room`. Judges sit in a room that serves one challenge; projects present to it on the schedule. The QR code on its door seats a judge, or starts a guest judge's session. |
| **Results snapshot** | `hackathon_result` — frozen placing. Live z-score is only used when computing that snapshot. |
| **Bootcamp term** | String like `2026-fall`. Access checks this, not the never-expiring `bootcamp_member` boolean. |
7 changes: 7 additions & 0 deletions docs/operations/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ Without `DATABASE_URL`, `db` is null, sessions fall back to JWT, and tRPC proced
| `RESUME_BUCKET` | Cloud Storage bucket holding resume PDFs (App Hosting sets `dsgt-resumes`). Unset means uploads return 503 rather than failing obscurely. Credentials are ADC — the runtime service account needs `roles/storage.objectAdmin`. See [Resume book](../resume-book.md) |
| `BOOTCAMP_BUCKET` | Cloud Storage bucket holding bootcamp workshop ZIPs (App Hosting sets `dsgt-bootcamp`). Unset means uploads and downloads return 503. Same ADC and same `roles/storage.objectAdmin` as above. Downloads are proxied and gated on the caller's bootcamp term, so the bucket keeps public access prevention on |

## Judging schedule

| Variable | Default / notes |
| --- | --- |
| `JUDGING_CPSAT_PYTHON` | A Python with OR-Tools (`python3` or a path). Set, the schedule section can run `packages/api/scripts/judging-schedule/cpsat.py` on the server (`judging.schedule.solveCpsat`). Unset means CP-SAT is download, run on a laptop, upload |
| `JUDGING_CPSAT_SCRIPT` | Path to `cpsat.py`. Default: found by walking up from the working directory |

## Security / proxy

| Variable | Default / notes |
Expand Down
1 change: 0 additions & 1 deletion docs/operations/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Roles are rows, not JWT claims.
| `isScanner` | Any active `admin` including `volunteer` |
| `isAdmin` | Active admin whose role is **not** `volunteer` |
| `isSuperAdmin` | `super_admin` |
| `isJudge` | Active `judge` for the resolved edition |
| `isProjectLeader` | Active `project_leader` or staff |

Volunteers can staff check-in desks. They cannot delete editions, grant memberships, or pass `isAdmin`.
Expand Down
2 changes: 1 addition & 1 deletion docs/operations/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Config: `packages/api/vitest.config.ts`. Includes `src/**/*.test.ts` and `src/.i
| Security / sanitizer / rate limit | `security.test.ts`, `resilience.test.ts` |
| Judges / participants / initiatives / bootcamp / announcements | matching `*-edge.test.ts` / `bootcamp.test.ts` / `announcements.test.ts` |
| Portal context | `services/portal-context.test.ts`, `routers/user/portal-context.test.ts` |
| Judge helpers | `routers/judge/helpers.test.ts` |
| Judging scoring, scope, room links | `services/judging/*.test.ts` |

Tests use `src/test/create-mock-context.ts` and `.internal-tests/_db-tx-mock.ts` rather than a live database.

Expand Down
11 changes: 6 additions & 5 deletions docs/packages/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ Exports: `.`, `./context`, `./trpc`, `./pricing`, plus a few middleware paths (s
| `member` | `routers/member.ts` | Membership profile, pass, admin grant/revoke/search |
| `hackathon` | `routers/hackathon/*` | Editions, registration, interest, events, content, announcements, staff ops |
| `events` | `routers/events.ts` | Club events and QR check-in |
| `judge` | `routers/judge/*` | Judge portal, rankings/results, admin judging |
| `judge` | `routers/judge/*` | Judge roster: apply, approve, add, remove |
| `judging` | `routers/judging/*` | Room judging: `admin`, `schedule`, `desk`, `hacker`, `results` |
| `points` | `routers/points/*` | Hackathon points: `admin`, `store`, `me` |
| `stripe` | `routers/stripe.ts` | Checkout, PaymentIntent, link, reconcile |
| `audit` | `routers/audit.ts` | Audit log list (admin) |
| `team` | `routers/team.ts` | Teams and project submission |
Expand All @@ -37,7 +39,6 @@ Defined in `src/trpc.ts` and `src/middleware/procedures.ts`.
| `isScanner` | Active `admin` row | Volunteers included. Badge / door scanning only |
| `isAdmin` | Active staff `admin` | Rejects `volunteer` |
| `isSuperAdmin` | `role === "super_admin"` | Staff create/remove, judge activate/remove, set project leader |
| `isJudge` | Active `judge` for the resolved hackathon | Resolves edition from input `hackathonId` / `projectId` / `queueId`, else current edition |
| `isProjectLeader` | Active `project_leader` **or** staff | Staff can cover a quiet leader; leaders cannot use this to pass `isAdmin` |

There is deliberately **no** `adminProcedure` that equals `protectedProcedure`. That name shipped open admin endpoints in the past.
Expand Down Expand Up @@ -86,11 +87,11 @@ Batch status updates allow up to **2500** ids. The global array cap in `scrubMar

## Judge procedures

**Portal** (`portal.ts`): `isJudge`, assignments, applications, QR start, next table, vote, skip, overtime skip, progress. `toggleJudging` is admin.
**Portal** (`portal.ts`): `isJudge` (for the named or current edition), `myApplications`, `register` (apply to judge).

**Rankings** (`rankings.ts`): `getRankings`, `computeResults`, draft/publish/unpublish. Results are a **frozen snapshot** (`hackathon_result`), not a live z-score on every page load.
**Admin** (`admin.ts`): `list`, `create` (add by email), `setActive` (approve or suspend), `remove` (super admin).

**Admin** (`admin.ts`): CRUD judges, promote submissions into judging tables, initialize queues, assign tracks/projects, table cards, live progress, analytics. `setActive` and `remove` are super admin. `register` is protected (apply to judge).
Judging itself is the `judging` namespace; its shared helpers are in `services/judging/` (`room-link`, `scope`, `scoring`, `config`). `hackathon.getResults` returns published placings from both the retired `hackathon_result` table and `judging_placement`, in one shape.

## Club procedures (selected)

Expand Down
5 changes: 4 additions & 1 deletion docs/packages/db.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ Files in `src/schemas/`, re-exported from `schemas/index.ts`. `drizzle.config.ts
| `members.ts` | `user_profile`, `member`, `membership_history` |
| `admins.ts` | `admin` |
| `hackathons.ts` | `hackathon`, `hackathon_team`, `hackathon_participant`, `hackathon_project`, `hackathon_interest`, `hackathon_event`, `hackathon_event_attendee`, `hackathon_announcement`, `hackathon_announcement_recipient` |
| `judge.ts` | `judge`, `judge_assignment`, `judging_project`, `judge_vote`, `judge_queue`, `hackathon_result` |
| `judge.ts` | `judge`, `judge_assignment` (live roster); `judging_project`, `judge_vote`, `judge_queue`, `hackathon_result` (retired, kept for past editions) |
| `judging.ts` | `judging_*`: config, entries and members, challenges, buildings, rooms and room links, judges, guest sessions, presence, schedule and appointments, rubric, evaluations, deliberation, placements |
| `points.ts` | `hackathon_point_adjustment`, `hackathon_store_item`, `hackathon_store_purchase` |
| `retired.ts` | Enum types the retired panel judging service left in the database, declared so push does not try to drop them |
| `initiatives.ts` | `project_leader`, `initiative`, `initiative_application` |
| `events.ts` | `event`, `event_check_in` |
| `bootcamp.ts` | `bootcamp_workshop` (metadata; the ZIPs are in Cloud Storage). `bootcamp_material` is legacy and unused |
Expand Down
8 changes: 6 additions & 2 deletions docs/sites/hacklytics2027.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ Schedule copy lives in `components/sections/Schedule/data.ts`.

## Interest CTA

`lib/links.ts` is the only outbound destination. The Typeform this replaced was pasted in four files and drifted.
`lib/links.ts` is the only outbound destination. The Typeform URL was once pasted in four files and drifted.

Interest requires a portal account (verified email). The CTA is:
Every Notify me button and link (header, mobile menu, hero, FAQ, footer) points at `INTEREST_URL`, a Typeform, for now. On phones 356px and wider the header keeps a compact Notify me button beside the menu toggle, so the CTA does not hide inside the hamburger menu.

Once registration opens on the portal, swap `INTEREST_URL` back to `PORTAL_INTEREST_URL`, which signs the visitor in first:

```
{PORTAL_ORIGIN}/login?callbackUrl=/hacklytics
```

`callbackUrl` is encoded so it survives the email-code hop through `/verify`. The portal only honors same-origin paths.

The footer also links to the portal for the two audiences that are not waiting on the list: **Hacker portal** (`PORTAL_HACKATHON_URL`, `{PORTAL_ORIGIN}/hacklytics`) and **Judge Hacklytics** (`JUDGE_URL`, sign-in with `callbackUrl=/judge`).

## Deploy

Firebase Hosting target `hacklytics`, public dir `sites/hacklytics2027/out` (`firebase.json`).
Expand Down
8 changes: 4 additions & 4 deletions docs/sites/mainweb.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ Unauthenticated and authenticated product UI. `proxy.ts` marks these prefixes `p
| `/club/bootcamp` | Bootcamp (paid add-on, term-gated) |
| `/initiatives` | Browse / apply |
| `/lead`, `/lead/[id]` | Project leader |
| `/hackathons`, `/hackathons/[id]` | Edition pages (info, schedule, teams, projects, results) |
| `/hackathons/[id]/judge` | Judging for that edition |
| `/hackathons`, `/hackathons/[id]` | Edition pages (info, schedule, teams, projects, judging, points, results) |
| `/hacklytics` | Current Hacklytics interest / portal landing |
| `/submit` | Project submission |
| `/judge`, `/judge/register` | Judge home / apply |
| `/judge/[hackathonId]` | Judge desk for one edition |
| `/scan` | QR scanning |
| `/admin` | Staff home |
| `/admin/hackathons`, `/admin/hackathons/[id]` | Edition admin (attendees, waves, announcements, analytics, events). `[id]` is the name slug (`hacklytics-digital-bloom`), not a percent-encoded name. |
| `/admin/hackathons`, `/admin/hackathons/[id]` | Edition admin (attendees, waves, announcements, analytics, events, judges, points, store). `[id]` is the name slug (`hacklytics-digital-bloom`), not a percent-encoded name. |
| `/admin/members` | Membership admin |
| `/admin/attendees` | Attendee tools |
| `/admin/judging` | Judging admin (sync submissions + assign judges live here) |
| `/admin/judging`, `/admin/judging/[hackathonId]` | Pick an edition, then run its judging: import, rooms, schedule, results |
| `/admin/initiatives` | Initiative / proposal review |
| `/admin/bootcamp` | Bootcamp attendance grid and the weekly workshop table |
| `/admin/staff` | Admin users |
Expand Down
8 changes: 8 additions & 0 deletions monitoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ number of instances is irrelevant:
- `dsgt_members_active`, `dsgt_members_lapsed`
- `dsgt_bootcamp_enrolled{term}`
- `dsgt_payments_by_plan{plan}` — the yearly/semester split
- `dsgt_hackathon_participants{edition,phase,status}`, `dsgt_hackathon_projects`,
`dsgt_hackathon_checkins_today`, `dsgt_hackathon_judging_projects`,
`dsgt_hackathon_votes`, `dsgt_hackathon_judging_active` — only editions that
are `open`, `closed`, or `in_progress`. A completed edition disappears on
the next refresh. Badge scans are hackathon QR rows since midnight Eastern,
not club door check-ins.
- `dsgt_payments_unlinked` — paid, claimed by nobody. This is **not** zero and
is not supposed to be: as of August 2026 it sits around 428 of 443 paid rows,
nearly all from the August–September 2025 and January 2026 drives. Those are
Expand Down Expand Up @@ -85,6 +91,8 @@ The alerts that matter:
- `MembershipGrantFailing` — a payment was recorded and the membership was not.
- `UnlinkedPaymentsClimbing` — the link paths are not claiming payments.
- `ReconcileRecoveringOften` — the backstop is carrying the fast path.
- `HackathonJudgingIdle` — judging is on, tables are assigned, and no scores
have landed for 30 minutes.

To route them into ClickUp, run Alertmanager with a webhook receiver and pipe
its payload to `node scripts/clickup-task.mjs --stdin`. That step is not built
Expand Down
57 changes: 57 additions & 0 deletions monitoring/clickhouse/init/02-hackathon.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
-- Hackathon history. Same reason as the payment tables: aggregate it here,
-- not on the 0.5 GB application database. `export:clickhouse` creates these
-- too, so a volume that already ran 01-schema.sql still picks them up.

CREATE DATABASE IF NOT EXISTS dsgt;

CREATE TABLE IF NOT EXISTS dsgt.hackathon_registrations
(
id String,
hackathon String,
status LowCardinality(String),
registered_at DateTime64(3),
updated_at DateTime64(3)
)
ENGINE = ReplacingMergeTree(updated_at)
ORDER BY (hackathon, id);

CREATE TABLE IF NOT EXISTS dsgt.hackathon_projects
(
id String,
hackathon String,
status LowCardinality(String),
submitted_at Nullable(DateTime64(3)),
updated_at DateTime64(3)
)
ENGINE = ReplacingMergeTree(updated_at)
ORDER BY (hackathon, id);

CREATE TABLE IF NOT EXISTS dsgt.hackathon_scans
(
id String,
hackathon String,
event_name String,
checked_in_at DateTime64(3)
)
ENGINE = ReplacingMergeTree(checked_in_at)
ORDER BY (hackathon, id);

CREATE TABLE IF NOT EXISTS dsgt.hackathon_votes
(
id String,
hackathon String,
score Int32,
voted_at DateTime64(3),
updated_at DateTime64(3)
)
ENGINE = ReplacingMergeTree(updated_at)
ORDER BY (hackathon, id);

CREATE VIEW IF NOT EXISTS dsgt.hackathon_registrations_by_status AS
SELECT
hackathon,
status,
count() AS registrations
FROM dsgt.hackathon_registrations FINAL
GROUP BY hackathon, status
ORDER BY hackathon, status;
Loading
Loading