mirror of
https://github.com/wahyd4/heygo.git
synced 2026-08-09 05:15:52 +10:00
- POST /api/auth/dev-login creates/finds user, promotes to admin, sets session cookie - POST /api/auth/dev-logout clears session cookie - Dev login page at #/dev-login in the SPA - Fix: getSessionCookieAttributes omits Secure over HTTP (local dev fix) - Guarded: only works when PUBLIC_HOST=localhost, returns 403 otherwise - Justfile: dev-admin and dev-logout commands - README: local admin login instructions
203 lines
7.5 KiB
Markdown
203 lines
7.5 KiB
Markdown
# Heygo
|
|
|
|
Heygo is an independent Cloudflare React + Workers scaffold for a future shortlinks app.
|
|
|
|
This repository lives at `/home/ai-bot/code/heygo` and is intentionally separate from the old Linux/Django Links repository. The old Links repository under `/home/ai-bot/code/links` is read-only reference material only and must not be modified by this project.
|
|
|
|
## Quick start (local)
|
|
|
|
> Prerequisites: Node.js 18+, npm, and [just](https://github.com/casey/just) installed.
|
|
|
|
```bash
|
|
git clone https://github.com/wahyd4/heygo.git
|
|
cd heygo
|
|
npm install
|
|
just build # build React SPA into dist/client
|
|
just migrate-local # apply D1 schema to local SQLite
|
|
just dev # start Worker on http://localhost:8787
|
|
```
|
|
|
|
Open `http://localhost:8787` in your browser — the SPA and API are both served by the Worker.
|
|
|
|
### Sign in as admin locally
|
|
|
|
OAuth isn't available in local dev. Use the dev-only login instead:
|
|
|
|
1. Start the worker: `just dev`
|
|
2. Open `http://localhost:8787/#/dev-login` in your browser
|
|
3. Enter your email (pre-filled with `wahyd4@gmail.com`) and click "Sign in as admin"
|
|
|
|
Or via CLI:
|
|
|
|
```bash
|
|
just dev-admin # creates admin user + session
|
|
just dev-admin other@example.com # different email
|
|
just dev-logout # clears the session cookie
|
|
```
|
|
|
|
This endpoint is guarded: it only works when `PUBLIC_HOST=localhost` (or `APP_BASE_URL`
|
|
contains `localhost`). In dev/prod deployments it returns 403. The dev login bypasses
|
|
OAuth, finds-or-creates the user, promotes them to admin, and sets a `heygo_session`
|
|
cookie — exactly what a real OAuth callback would do, minus the provider.
|
|
|
|
### Just commands
|
|
|
|
Run `just` (no args) to list all recipes. The most common ones:
|
|
|
|
| Command | What it does |
|
|
| --- | --- |
|
|
| `just build` | Type-check TypeScript + build React SPA into `dist/client` |
|
|
| `just dev` | Start Cloudflare Worker locally on port 8787 (API + SPA) |
|
|
| `just dev-ui` | Start Vite dev server on port 5173 with HMR (frontend only) |
|
|
| `just test` | Run the full Vitest suite (134 tests) |
|
|
| `just test-watch` | Run tests in watch mode |
|
|
| `just smoke` | Build, migrate, start worker, curl health — quick end-to-end check |
|
|
| `just typecheck` | Type-check without emitting |
|
|
|
|
### Local D1 database helpers
|
|
|
|
| Command | What it does |
|
|
| --- | --- |
|
|
| `just migrate-local` | Apply D1 migrations to local SQLite |
|
|
| `just db-tables` | List all tables in local D1 |
|
|
| `just db-links` | List all links in local D1 |
|
|
| `just db-query "SELECT …"` | Run arbitrary SQL on local D1 |
|
|
| `just add-link <alias> <url>` | Insert a test public shortlink |
|
|
| `just rm-link <alias>` | Delete a link by alias |
|
|
| `just db-reset` | Drop local D1 and re-apply migrations |
|
|
|
|
### First-time local setup
|
|
|
|
```bash
|
|
npm install
|
|
just build
|
|
just migrate-local
|
|
|
|
# optional: add a test shortlink to try it out
|
|
just add-link claude https://claude.ai
|
|
|
|
# start the Worker
|
|
just dev
|
|
```
|
|
|
|
Then test it:
|
|
|
|
```bash
|
|
curl -I http://localhost:8787/claude # → 302 redirect to claude.ai
|
|
curl http://localhost:8787/missing # → 404 HTML page
|
|
curl http://localhost:8787/api/health # → {"ok":true,"service":"heygo-worker"}
|
|
```
|
|
|
|
Open `http://localhost:8787` for the SPA management UI.
|
|
|
|
### How local dev works
|
|
|
|
- `just dev` runs `wrangler dev` which starts a local Cloudflare Workers runtime (Miniflare) with a local D1 SQLite database at `.wrangler/state/`.
|
|
- The Worker serves the built React SPA from `dist/client/` (hence `just build` is required first).
|
|
- The Worker API handles `/api/*` routes, public shortlink redirects, and private shortlink redirects.
|
|
- Local `wrangler.jsonc` sets `PUBLIC_HOST=localhost` and `PRIVATE_HOST=localhost`, so both public and private routes resolve on the same port. This is fine for testing APIs, the SPA, and public redirects. Private shortlink auth flows are covered by unit tests (`tests/private-redirect.test.ts`).
|
|
- To iterate on the React frontend with hot reload, use `just dev-ui` (Vite on port 5173) in a separate terminal. Note: Vite and the Worker run on different ports, so `/api/*` calls from Vite won't reach the Worker unless you set up a proxy.
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
just build # tsc --noEmit && vite build
|
|
just test # vitest run
|
|
```
|
|
|
|
- `just build` type-checks the TypeScript project and builds the React SPA into `dist/client` for Workers Assets.
|
|
- `just test` runs Vitest tests against the Worker API handler.
|
|
|
|
## Deployment
|
|
|
|
Heygo ships as a single Cloudflare Worker fronted by two custom domains: a
|
|
**public** shortlink host and a **private** shortlink host. There are two
|
|
environments, each with its own D1 database, KV namespace, Worker, and domains.
|
|
|
|
| Environment | Public host | Private host | Worker | D1 database |
|
|
| --- | --- | --- | --- | --- |
|
|
| dev | `dev.heygo.cc` | `my.dev.heygo.cc` | `heygo-dev` | `heygo-shortlinks-dev` |
|
|
| prod | `heygo.cc` | `my.heygo.cc` | `heygo` | `heygo-shortlinks` |
|
|
|
|
The Worker reads `PUBLIC_HOST`, `PRIVATE_HOST`, `APP_BASE_URL`, and
|
|
`COOKIE_DOMAIN` from env vars (set in each wrangler config), so the same code
|
|
serves every environment without hardcoded hostnames.
|
|
|
|
### Prerequisites
|
|
|
|
- A Cloudflare account with the `heygo.cc` zone added.
|
|
- A Cloudflare API token with D1, Workers KV, Workers Scripts, and Workers
|
|
Routes permissions.
|
|
- Terraform >= 1.5 installed.
|
|
|
|
### 1. Provision infrastructure with Terraform
|
|
|
|
The `terraform/` directory provisions the D1 database, KV namespace, and both
|
|
Worker custom domains. See `terraform/README.md` for full details.
|
|
|
|
```bash
|
|
export CLOUDFLARE_API_TOKEN=*** # fill account_id + zone_ids in tfvars first
|
|
just infra-init
|
|
just infra-plan-dev # review, then:
|
|
just infra-apply-dev
|
|
just infra-plan-prod # review, then:
|
|
just infra-apply-prod
|
|
```
|
|
|
|
### 2. Copy Terraform outputs into Wrangler configs
|
|
|
|
After `just infra-apply-dev`, read the created resource IDs:
|
|
|
|
```bash
|
|
just infra-output dev
|
|
```
|
|
|
|
Paste the printed `d1_database_id` into `wrangler.dev.jsonc`
|
|
(`d1_databases[].database_id`) and `kv_namespace_id` into
|
|
`wrangler.dev.jsonc` (`kv_namespaces[].id`). Repeat for prod outputs into
|
|
`wrangler.prod.jsonc`. The placeholder `00000000-...` IDs are there until you
|
|
fill them in.
|
|
|
|
### 3. Apply D1 migrations to remote
|
|
|
|
```bash
|
|
just migrate-dev
|
|
just migrate-prod
|
|
```
|
|
|
|
### 4. Deploy the Worker
|
|
|
|
```bash
|
|
just deploy-dev # builds + deploys to dev.heygo.cc + my.dev.heygo.cc
|
|
just deploy-prod # builds + deploys to heygo.cc + my.heygo.cc
|
|
```
|
|
|
|
### Dev environment
|
|
|
|
The dev environment uses `dev.heygo.cc` (public) and `my.dev.heygo.cc` (private),
|
|
both under the `.heygo.cc` cookie domain. Session cookies set by the app UI on
|
|
`dev.heygo.cc` are automatically visible to `my.dev.heygo.cc`, so private
|
|
shortlink auth works out of the box — no extra configuration needed.
|
|
|
|
Prod works the same way: `heygo.cc` and `my.heygo.cc` share `.heygo.cc`.
|
|
|
|
### All deployment commands
|
|
|
|
| Command | What it does |
|
|
| --- | --- |
|
|
| `just infra-init` | `terraform init` |
|
|
| `just infra-plan-dev` | Review infra changes for dev |
|
|
| `just infra-apply-dev` | Apply infra for dev |
|
|
| `just infra-plan-prod` | Review infra changes for prod |
|
|
| `just infra-apply-prod` | Apply infra for prod |
|
|
| `just infra-output <dev\|prod>` | Show Terraform outputs (D1 ID, KV ID) |
|
|
| `just migrate-dev` | Apply D1 migrations to remote dev database |
|
|
| `just migrate-prod` | Apply D1 migrations to remote prod database |
|
|
| `just deploy-dev` | Build + deploy Worker to dev |
|
|
| `just deploy-prod` | Build + deploy Worker to prod |
|
|
|
|
## Current API skeleton
|
|
|
|
- `GET /api/health` returns JSON health status from the Worker.
|
|
- Unknown `/api/*` routes return JSON `404` responses.
|