Skip to content

Latest commit

 

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Royal Manager

Royal Manager — RPG habit tracking for consistency and recovery

Asset notice: SFX are CC0-licensed audio from Kenney (commercial use OK, no attribution required). See docs/ASSET_PROVENANCE.md for full provenance.

Royal Manager is an RPG-inspired habit tracker focused on consistency and recovery after failure. Habits become daily quests, and each check-in can be recorded as complete, minimum effort, failed, or skipped.

Current RPG features add five fixed hero classes with visible base combat stats at selection time, local avatars, and a private solo adventure whose deterministic combat reacts to habit outcomes. Missing a full day of habits (outside a rest day) now costs the hero HP in the active adventure run. A Settings page lets each user toggle sound effects, motivational messages, and global checklist presentation, customize the accent color/background/panel opacity, and choose a seriousness level (casual through hardcore) that scales enemy HP and attack in adventure combat. Current interface integrates the approved Stitch handoff with real auth, habit, check-in, progress, and settings data. Multiplayer, guilds, a working economy, complex inventory, payments, and advanced AI remain outside current scope.

Stack

  • Next.js 16, React 19, and TypeScript
  • Tailwind CSS
  • Supabase Auth and Supabase Postgres
  • Drizzle ORM and Drizzle Kit
  • Vitest and Playwright

Engineering policies

Supabase runs locally in Docker. You do not need to install PostgreSQL on the host machine.

Prerequisites

Install:

  • Node.js 20.19.0 or newer;
  • npm;
  • Docker Desktop, Docker Engine, or another Docker-compatible runtime.

When using WSL, enable Docker integration for the project distribution.

Confirm the required tools are available:

node --version
npm --version
docker version

docker version must display both the Client and Server sections. If only the Client appears, start Docker before continuing.

First-time setup

1. Install dependencies

From the repository root:

npm install

2. Start the local Supabase stack

npm run db:start

This starts the required Supabase services in Docker, including PostgreSQL, Auth, the API, Studio, and Mailpit. The first execution may take longer while Docker downloads the service images.

Check the services and obtain the local API credentials:

npm run db:status

3. Configure environment variables

Create the local environment file:

cp .env.example .env.local

Open .env.local and replace:

NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=replace-with-local-publishable-key

with the publishable key shown by npm run db:status.

The default local configuration should look like:

NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=<key printed by npm run db:status>
APP_URL=http://127.0.0.1:3000
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres

Do not commit .env.local. It is ignored by Git. The DATABASE_URL is server-only and must never be exposed in browser code.

4. Apply migrations

npm run db:reset

This recreates the local database, applies every migration from supabase/migrations, and loads supabase/seed.sql.

Warning: db:reset deletes existing data in the local Docker database. Do not run it against an environment containing data you need to preserve.

5. Start the application

npm run dev

Open http://127.0.0.1:3000.

During local development, open http://127.0.0.1:3000/ui for the canonical color tokens, shared components, interaction states, sprites, and responsive patterns. This route deliberately returns 404 in production and is not linked from application navigation. Product components may use layout utilities, but visual color decisions belong in app/globals.css semantic tokens.

Local services

Service Address
Application http://127.0.0.1:3000
Supabase API http://127.0.0.1:54321
PostgreSQL 127.0.0.1:54322
Supabase Studio http://127.0.0.1:54323
Mailpit http://127.0.0.1:54324

Mailpit captures local authentication emails, including password recovery messages. Messages are not sent to real addresses during local development.

Local email confirmation remains disabled by default, so local signup creates a session immediately. To test the hosted-style confirmation flow through Mailpit, set enable_confirmations = true under [auth.email] in supabase/config.toml, restart the local stack, and restore the setting after testing. The checked-in confirmation template targets /auth/confirm.

Hosted authentication configuration

Set the server-only APP_URL deployment variable to the canonical application origin, such as https://app.example.com. Do not include a path, query, hash, or trailing slash.

In the hosted Supabase dashboard:

  1. Set Auth URL Configuration → Site URL to the same canonical origin.

  2. Add the exact ${APP_URL}/auth/confirm and ${APP_URL}/auth/recovery URLs to Redirect URLs.

  3. Replace the Confirm signup email template link with:

    <a href="{{ .RedirectTo }}?token_hash={{ .TokenHash }}&type=email">
      Confirm email address
    </a>
  4. Disable link tracking in the SMTP provider because rewritten confirmation URLs may break authentication.

  5. Copy supabase/templates/recovery.html into the Reset password email template. Use a production SMTP provider for reliable delivery.

After deployment, create a new account and verify that the email uses the production domain, /auth/confirm establishes the cookie session, and the user arrives at /profile/class.

Test the main flow manually

With Supabase and the application running:

  1. Open the application and create an account. Passwords must be at least 10 characters and include an uppercase letter, a lowercase letter, and a number.
  2. If an email message is generated, open Mailpit and use its confirmation link.
  3. Sign in.
  4. Create a habit with a full goal and a minimum goal.
  5. Confirm that the habit appears as a quest on today's dashboard.
  6. Record a complete check-in and confirm that it grants 20 XP.
  7. Record a minimum check-in for another habit and confirm that it grants 10 XP.
  8. Record a failed check-in and confirm that a failure reason is required and no XP is removed.
  9. Confirm that another check-in for the same habit and date is rejected.
  10. Open the weekly review and check the consistency summary.

Automated verification

Run the database tests while Supabase is active:

npm run db:test

Run unit tests and coverage:

npm run test
npm run test:coverage

Run static checks and the production build:

npm run lint
npm run typecheck
npm run build

Run the end-to-end suite:

npm run test:e2e:install
npm run test:e2e

test:e2e:install installs the project-compatible Chromium build and its Linux system libraries. Run it once after installing dependencies and again after Playwright version upgrades. On WSL/Linux, the command uses sudo and may ask for the distribution user's password.

Weekly-review E2E fixtures need a server-only Supabase service role. Against the local Docker stack, tests discover it from supabase status --output json. Hosted or CI runs must set SUPABASE_SERVICE_ROLE_KEY explicitly. Never prefix this variable with NEXT_PUBLIC or expose it to browser code.

Database and migration workflow

The data architecture has two distinct responsibilities:

  • db/schema.ts is the editable source of truth for tables, enums, indexes, constraints, and Row Level Security policies.
  • supabase/migrations contains the versioned SQL that Supabase applies.

After changing db/schema.ts, generate and verify the migration:

npm run db:generate
npm run db:check
npm run db:reset

Drizzle generates the SQL migrations. Generated SQL must be reviewed and committed, but should not be edited manually.

PostgreSQL features that Drizzle cannot model, such as specialized functions, triggers, grants, or RPCs, belong in a custom migration:

npm run db:custom -- --name=descriptive_name

The application accesses data through Supabase so authenticated requests remain protected by Row Level Security. PostgreSQL is the source of truth.

Daily commands

# Start Supabase containers
npm run db:start

# Inspect service status and local credentials
npm run db:status

# Start Next.js
npm run dev

# Stop Supabase containers
npm run db:stop

db:stop stops the services without resetting the local database.

Troubleshooting

Docker is unavailable

If npm run db:start cannot connect to Docker:

  1. start Docker Desktop or the Docker daemon;
  2. verify docker version shows the Server section;
  3. under WSL, verify Docker integration is enabled;
  4. run npm run db:start again.

A local port is already in use

Stop another Royal Manager stack:

npm run db:stop

If the conflict remains, identify the application using ports 3000, 54321, 54322, 54323, or 54324, then stop it or update the corresponding local configuration.

Authentication or API calls fail

Run:

npm run db:status

Confirm that .env.local uses the displayed API URL and publishable key, then restart npm run dev. Next.js reads environment variables when the development server starts.

Database schema is outdated

For disposable local data, recreate the database:

npm run db:reset

Remember that this removes current local records.

Support Royal Manager

If you enjoyed the project, you can leave a small donation on Ko-fi — no strings attached.

Buy Me a Coffee at ko-fi.com

License

The source code in this repository is licensed under MIT. Some assets (AI-generated character sprites, sound effects, and other media under public/assets/ and assets/source/) are covered by separate terms — see Asset provenance for the current status of each.

Project documentation

About

Royal Manager is an RPG-inspired habit tracker focused on consistency and recovery after failure. Habits become daily quests, and each check-in can be recorded as complete, minimum effort, failed, or skipped.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages