aboutsummaryrefslogtreecommitdiff
path: root/web/ui/README.md
blob: f00e22c95115e2417e7face72c08ba57be9faaa4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Tidy Index — Dashboard

A minimal SvelteKit dashboard for managing Tidy Index API keys, plans, and
account info. Designed to share a visual system with the marketing site in
`../landing/`.

## Quick start

```bash
npm install
cp .env.example .env
# Generate and paste a JWT_SECRET:
openssl rand -base64 48
npm run seed   # optional — populates fake usage data
npm run dev
```

Dev server runs on http://localhost:5174.

## Stack

- SvelteKit 2 + Svelte 5 (runes)
- better-sqlite3 (file at `./data/dashboard.db`)
- jsonwebtoken (HS256, httpOnly cookie session)
- Plain CSS matching the landing page design system

## Auth model

No passwords, no third-party auth, no required email.

- **Anonymous:** click "Skip — just give me an API key" on `/`. Server
  creates an account with `email = NULL`, sets a signed session cookie,
  drops you on the dashboard.
- **Magic link:** enter an email on `/`. If an account exists for that
  email we re-use it, otherwise we create a new one. We generate a
  single-use token valid for 15 minutes, write it to `magic_links`, and
  log the resulting URL to the server console (email sending is stubbed).

Adding an email to an existing anonymous account on `/dashboard/account`
will merge into any other account already using that email — all keys and
usage events move over, and the anonymous account is deleted.

## Data model

See `src/lib/server/db.ts` for the schema. Four tables:

- `accounts` — id, email (nullable, unique), plan, created_at
- `api_keys` — id, account_id, key_hash, key_prefix, name, scopes, active, timestamps
- `magic_links` — id, account_id, token, expires_at, used
- `usage_events` — id, api_key_id, dataset, timestamp

The `seed` script populates `usage_events` with a few weeks of fake traffic
against the first account in the DB so the Usage tab has something to show.