Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# Never place database credentials, ML service keys, object-storage secrets,
# or other privileged values in a client-visible variable.
PUBLIC_API_BASE_URL=http://localhost:8000
# The deployed Better Auth service. Override this only when running auth locally.
PUBLIC_AUTH_BASE_URL=https://api.ifyousmellityouwilleventuallydie.tech

# The native Tauri process reads these values. Since they do not use the
# PUBLIC_ prefix, Vite does not expose them to the Svelte webview.
Expand Down
18 changes: 18 additions & 0 deletions api_server/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# PostgreSQL connection used only by the server. Never expose this through Vite.
DATABASE_URL=postgresql://holotrace:change-me@localhost:5432/holotrace

# Public URL at which Caddy exposes the Better Auth routes.
BETTER_AUTH_URL=http://localhost:8001

# Generate a high-entropy value of at least 32 characters.
BETTER_AUTH_SECRET=replace-with-a-random-value-of-at-least-32-characters

# Comma-separated client origins allowed to make credentialed auth requests.
AUTH_TRUSTED_ORIGINS=http://localhost:5173

# Optional defense in depth for Caddy's private forward_auth request.
INTERNAL_AUTH_TOKEN=replace-with-a-separate-random-value

# The Bun service's private listening port.
BIND_HOST=127.0.0.1
PORT=8001
90 changes: 81 additions & 9 deletions api_server/README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,95 @@
# Holotrace API server
# Holotrace authentication API

To install dependencies:
This Bun service owns Holotrace authentication. Better Auth provides the HTTP routes and session cookies, while its
Drizzle adapter stores authentication data in the PostgreSQL `auth` schema. The service also owns authenticated
saved-circuit requests backed by the public-schema `projects` table. The existing Python model API remains separate.

## Local setup

```bash
bun install
cp .env.example .env
bun run db:migrate
bun run dev
```

To run the current scaffold:
Set real values in `.env` before running the server. `BETTER_AUTH_SECRET` must be a high-entropy value with at least
32 characters. Do not expose `DATABASE_URL`, `BETTER_AUTH_SECRET`, or `INTERNAL_AUTH_TOKEN` to the Svelte client.

Useful commands:

```bash
bun run index.ts
bun run check
bun run db:generate
bun run db:migrate
bun run start
```

## Source layout
## Routes

Better Auth is mounted below `/api/auth`. The username plugin adds username login to its standard email-and-password
account flow.

```text
POST /api/auth/sign-up/email
POST /api/auth/sign-in/username
POST /api/auth/sign-out
GET /api/auth/get-session
GET /api/circuits
POST /api/circuits
GET /api/circuits/:id
POST /api/circuits/:id/open
PUT /api/circuits/:id
DELETE /api/circuits/:id
GET /health
GET /internal/authorize
```

Signup requires a display name, email, username, and password. Login requires only the username and password.
Passwords are owned and hashed by Better Auth in `auth.account`; they must never be copied into the legacy `users`
table or sent to the model service.

The auth cookie is `Secure`, `HttpOnly`, and `SameSite=None` so the Tauri webview and local Svelte development origin
can retain a session while calling the deployed HTTPS API. Better Auth's origin checks and the credentialed CORS
allowlist remain enabled; every client origin must be listed in `AUTH_TRUSTED_ORIGINS`.

Circuit routes require a valid Better Auth session. `public.projects.owner` references `auth.user.id`, and every read,
update, or delete includes that owner in its database predicate. Circuit JSON is limited to 12 MB per saved project
to accommodate the captured source image currently embedded in the circuit state. Listing returns lightweight
summaries ordered by `lastOpenedAt`; opening one circuit updates that timestamp before returning its full data.
The app opens a circuit through `POST /api/circuits/:id/open`, keeping the timestamp mutation off the read-only GET
route.

`/internal/authorize` is intended for a reverse proxy's private authentication subrequest. It validates the Better
Auth session cookie and returns `X-Holotrace-User-Id` on success. When `INTERNAL_AUTH_TOKEN` is configured, the proxy
must supply the same value in `X-Internal-Auth-Token`. Do not expose this route directly through the public proxy.

## Keeping the Python API unchanged

In production, route `/api/auth/*` to this service and leave the remaining paths pointed at the Python model API:

```text
src/db/ Drizzle schema
src/circuit/ recognition, OpenCV wire-graph, normalization, and Circuit IR contracts
api.ifyousmellityouwilleventuallydie.tech
/api/auth/* -> Holotrace Bun API
/api/circuits* -> Holotrace Bun API
everything else -> existing Python model API
```

The circuit normalizer belongs to the server boundary. It combines the OpenCV analysis and classifier result, then
returns canonical Circuit IR, source-image layout, and structured review issues to the user-facing application.
This preserves the Python implementation and its existing authorization behavior. To require Better Auth sessions
for the Python routes later, configure Caddy `forward_auth` to call the private `/internal/authorize` endpoint before
proxying a request to Python. Authentication at the proxy only proves who the caller is; project- and
workspace-specific authorization still belongs in an application API boundary.

## Source layout

```text
src/auth.ts Better Auth and username/password configuration
src/authorize.ts Private reverse-proxy authentication endpoint
src/circuits.ts Authenticated saved-circuit CRUD
src/config.ts Runtime environment validation
src/cors.ts Credentialed browser-request CORS handling
src/db/auth-schema.ts Better Auth's isolated Drizzle schema
src/db/index.ts PostgreSQL pool and Drizzle client
src/db/schema.ts Simplified saved-project schema linked to Better Auth users
deploy/ User service and Caddy routing examples
```
Loading
Loading