A comprehensive digital companion for the King's College London Dungeons & Dragons Society. This application serves as an organisational tool to enhance the users' experience, providing features for character management, party organization, campaign tracking, and achievement systems.
Important: This is not a replacement for pen-and-paper play, but rather a magical addon that complements traditional D&D sessions at the university. Think of it as your party's trusted spellbook and chronicle keeper!
The KCL DnD Society App is a Next.js-based web application designed to help everyone. It provides a centralised platform for:
- Character Management: Create, edit, and track PCs
- Party Organisation: Form and manage adventuring parties
- Campaign Tracking: Monitor ongoing campaigns (from humble tavern meetings to epic world-saving quests)
- Achievement System: Award and track achievements for both players, DMs, and PCs
- Journal Entries: Document campaign sessions and important events (the bards will thank you)
- User Roles: Differentiate between players, DMs, and administrators
- Images: Upload and display character and party images (because a picture is worth a thousand words)
- Bun (recommended) or Node.js 18+
- Docker; you can use Docker Desktop or Orb
-
Start Docker
Make sure Docker is running on your machine. If you're using Orb, you can start it with:
orb start
-
Clone the repository
git clone https://github.com/mkutay/dndsoc.git cd dndsoc -
Install dependencies
bun install
-
Setup DB
bunx supabase start bunx supabase db reset --local
This starts up the Supabase local server with the migrations under
/supabase/migrationsand the data in/supabase/seed.sql.You can sign in with three accounts to test the system out:
admin@kcl.ac.uk,player@kcl.ac.uk, anddm@kcl.ac.uk, with the password of123456. Obviously, this is just sample information and is not real. -
Environment Variables
Populate
.env.examplefile in.env.localwith the information given by thesupabase startcommand.cp .env.example .env.local
-
Start the development server
bun dev
-
Build for production
Test the types and run the linter to check for errors overall.
bun run build
-
Run the production server
bun start
-
Close the Supabase server
bunx supabase stop
The application uses a runQuery function for most database operations, providing:
- Consistent error handling across all database interactions.
- Type-safe database queries with full TypeScript support.
- Automatic error logging with caller context.
- Functional programming patterns with ResultAsync.
export const runQuery = <T>(queryBuilder: QueryBuilder<PostgrestSingleResponse<T>>, caller?: string) =>
createClient().andThen(client => supabaseRun(queryBuilder(client), caller));The entire application uses the Neverthrow library for:
- Railway-oriented programming: Explicit error handling without try-catch
- Composable operations: Chain database operations with
.andThen() - Type-safe errors: All error cases are explicitly typed
- Functional transformations: Map over success values while preserving errors
"In TypeScript we trust, for it guards against the chaos of runtime errors"
- Database Types: Auto-generated TypeScript types from Supabase schema
- Form Validation: Zod schemas for runtime type validation
- API Responses: Strongly typed server actions and responses, using
ActionResulttype
src/
├── app/ # Next.js App Router pages (the main quest hub)
│ ├── (auth-pages)/ # Authentication flows (the tavern entrance)
│ ├── achievements/ # Achievement system (your trophy room)
│ ├── admin/ # Admin panel (the throne room)
│ ├── campaigns/ # Campaign management (where epics are born)
│ ├── characters/ # Character profiles (meet the heroes)
│ ├── dms/ # Dungeon Master profiles (the storytellers)
│ ├── journal/ # Session journals (the chronicler's records)
│ ├── my/ # User dashboard (your personal sanctuary)
│ ├── parties/ # Party management (assemble your fellowship)
│ ├── players/ # Player profiles (the adventurers)
│ └── polls/ # Polling system (democratic decisions)
├── components/ # Reusable UI components (your spell components)
│ ├── ui/ # Base UI primitives (the fundamental elements)
│ ├── typography/ # Typography components (the scribes' tools)
├── config/ # Configuration and schemas (the rule books)
├── fonts/ # Custom D&D themed fonts (ancient scripts)
├── lib/ # Client-side database operations (your utility spells)
├── server/ # Server actions and API logic (the server realm)
├── types/ # TypeScript type definitions (the language of the code)
└── utils/ # Utility functions and helpers (handy tools)
Contributions are welcome! Please be respectful and follow obvious design patterns.
If you have changed the schema of the DB, then make sure to run the following two commands to add the new changes (as Supabase migration and database types) into the repo.
bunx supabase db diff -f add_new_featurebunx supabase gen types --lang typescript --local > src/types/database.types.tsAfter that, you are welcome to create a PR, where I'll review your changes.
For more information about the Supabase migrations, see.
Built with <3 for the KCL DnD Society by Kutay and contributors.
May your code compile and your dice roll high!
