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+
- Supabase CLI
-
Clone the repository
git clone https://github.com/mkutay/dndsoc.git cd dndsoc
-
Install dependencies
bun install
-
Setup DB
supabase start supabase db reset --local
This starts up the Supabase local server with the migrations under
/supabase/migrations
and 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.example
file in.env.local
with the information given by thesupabase start
command.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.
BUILDING=true bun run build
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
ActionResult
type
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)
│ └── [feature]/ # Feature-specific components (specialized gear)
├── 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 command to add the new changes into the repo.
supabase db diff -f add_new_feature
After 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!