NOTE

Mr. Gordon generated most of this documentation using the OpenAI ChatGPT large language model. He edited the results for clarity and to add some additional context.

Schema

Here is an overall look at the schema of this database:

Details

In a “Choose Your Own Adventure” experience, the narrative consists of pages (nodes) connected by choices (edges), forming a directed graph. Each page contains text (and optionally an image), and each edge represents a decision that moves the reader from one page to another.

🔗 Core Tables

1. page

page — the nodes of the graph

Each record represents a single page in the adventure.

ColumnDescription
idPrimary key. Unique identifier for the page.
narrativeThe story text on the page.
imageOptional image associated with the page.
ending_contextText shown only if the page is a final outcome.
ending_type_idOptional reference to ending_type (e.g., “happy”, “bad”, etc.).

➡️ This table defines all the points in the story that a user can visit.


2. edge

edge — the directed links (choices) between pages

Each edge represents a choice that the reader can make to go from one page to another.

ColumnDescription
idPrimary key.
promptThe text the user sees for the choice (e.g., “Open the door”).
from_pageForeign key to page(id) – the page the choice starts from.
to_pageForeign key to page(id) – the page it leads to.

➡️ This table defines the edges of the graph, forming directed links between pages.


3. ending_type

ending_type — categorizes ending pages

ColumnDescription
idPrimary key.
labelName of the ending type (e.g., “Outstanding”, “Favourable”).
colorAssociated color for UI display (e.g., red for “bad ending”).

Used to annotate the directed graph that you can generate to check whether you have populated the database correctly – that is – to see whether the directed graph you have programmed into the database matches your plan made on paper:

Available values are:

Once your team has followed the steps above, you will obtain a directed graph with categorized endings as follows:


🧍‍♂️ Reader Tracking Tables

These tables allow the app to track and personalize a user’s journey through the story.

4. reader

reader — represents a user of the app

Each record stores information about a reader and their last page visited.

ColumnDescription
idPrimary key.
nameOptional display name.
user_idTied to Supabase authentication.
prefers_dark_modeUI setting.
last_page_read_idForeign key to page(id) — useful for “continue reading”.

➡️ Each reader can resume from their last visited page.


5. reader_page

reader_page — records the pages visited by each reader

This table tracks the unique path each reader has taken.

ColumnDescription
reader_idForeign key to reader(id).
page_idForeign key to page(id).
user_idFor enforcing security (matches auth.uid()).

➡️ Enables per-user navigation history, achievements, or visualizing a path.


🔐 Row-Level Security and Access Control

Policies and row-level security ensure:

  • All users can read the story structure (pageedgeending_type).

  • Only authenticated users can see and write their own reader and reader_page records, using auth.uid() for filtering.


✅ Summary: A Directed Graph Implementation

Graph ConceptRepresented By
Nodepage
Directed Edgeedge (from_page → to_page)
Terminal Node (Ending)page + ending_type
Visitorreader
Traversal Pathreader_page

This schema allows students to extend the app by layering features like bookmarks, alternate endings, visual graphs, user stats, or even branching story creation tools — all thanks to this solid directed graph foundation.