Modern POS and club management UI built with SvelteKit 5 runes, Supabase, Tailwind, and a11y-first UI primitives.
users
profile table and roles: admin
, staff
, secretary
.src/lib/i18n.ts
with t()
utilities.src/lib/components/ui/*
.$state
, $derived
, $bindable
)src/lib/supabaseClient.ts
– client SDKsrc/lib/server/supabaseAdmin.ts
– server admin SDK (service role; server-only)src/lib/user.ts
– session store and profile loadersrc/routes
– SvelteKit routes (pages + API)admin/*
– admin dashboards (products, orders, registers, users)dashboard/*
, staff/*
, secretary/*
– role-specific pagesapi/admin/users/+server.ts
– admin user management endpointssupabase/*
– local Supabase config and migrationsPrereqs: Bun (or Node), Supabase CLI, Git.
Clone and install
git clone https://github.com/dacrab/clubOS.git
cd clubOS
bun install
Environment
Create .env.local
with (client values are public):
PUBLIC_SUPABASE_URL=... # Project URL
PUBLIC_SUPABASE_ANON_KEY=...
SUPABASE_URL=... # server only
SUPABASE_SERVICE_ROLE_KEY=... # server only
Supabase (optional local stack)
supabase start
supabase db reset # loads schema and seeds as configured
bun run db:seed
Run the app
bun run dev
Quality
bun run check # types + svelte-check + biome + knip
bun run test # vitest
users
(id, username, role) – synced from auth.users
via triggercategories
, products
(image_url in storage), indexes for perfregister_sessions
, orders
, order_items
, register_closings
appointments
, football_bookings
src/routes/admin/products/+page.svelte
– list, create, edit products, image upload to Supabase Storagesrc/routes/admin/orders/+page.svelte
– date-range filters, items per order, money formattingsrc/routes/admin/registers/+page.svelte
– sessions insights and statssrc/routes/api/admin/users/+server.ts
– protected admin endpointsimport { Card, CardContent, CardHeader, CardTitle } from "$lib/components/ui/card";
import { Button } from "$lib/components/ui/button";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "$lib/components/ui/table";
PUBLIC_SUPABASE_URL
, PUBLIC_SUPABASE_ANON_KEY
via $env/static/public
or $env/dynamic/public
.SUPABASE_URL
, SUPABASE_SERVICE_ROLE_KEY
via $env/dynamic/private
.Supabase Keepalive
– pings PUBLIC_SUPABASE_URL
every 6 days to prevent cold power-off.GitGuardian Secrets Scan
– scans commits for secrets (configured as non-blocking with --exit-zero
).CodeQL
– code scanning workflow; set repo Settings → Security → enable Code Scanning default setup for full effect.Dependabot
– weekly updates for npm and GitHub Actions.Required repository secrets:
PUBLIC_SUPABASE_URL
(keepalive)GITGUARDIAN_API_KEY
(secrets scan)type
, SVG with title
, no invalid ARIA, etc.)noUncheckedIndexedAccess
, exactOptionalPropertyTypes
, verbatimModuleSyntax
, ...)bun run check # typecheck + lint + knip
npx ultracite fix # auto-fix formatting & lint issues
bun knip # find unused code
# Supabase helpers
bun run db:seed
supabase db reset
@sveltejs/adapter-vercel
(configurable). Provide PUBLIC_SUPABASE_URL
and PUBLIC_SUPABASE_ANON_KEY
as env vars. For server actions/endpoints, set SUPABASE_URL
and SUPABASE_SERVICE_ROLE_KEY
as private env vars.Everything you need to build a Svelte project, powered by sv
.
If you're seeing this, you've probably already done this step. Congrats!
# create a new project in the current directory
npx sv create
# create a new project in my-app
npx sv create my-app
Once you've created a project and installed dependencies with npm install
(or pnpm install
or yarn
), start a development server:
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
To create a production version of your app:
npm run build
You can preview the production build with npm run preview
.
To deploy your app, you may need to install an adapter for your target environment.