Files
0pt/README.md
admin 45b2d65d42
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / security (push) Successful in 14s
Security Scan (SIAX Cloud) / security (push) Successful in 23s
CI (SIAX Cloud) / integration (push) Successful in 25s
CI (SIAX Cloud) / quality (push) Successful in 34s
feat(toolchain): 0pt-pilot — mise task-kontrakt (node 22.13.0/pnpm 9.15.9) + lefthook + template-pin + README/AGENTS (W3, pilot 2/3)
2026-09-14 22:59:02 +02:00

118 lines
7.4 KiB
Markdown

# 0pt — your data
Data services on demand for the Nordics + Europe. Compose a data job, pay 50 % to start,
watch production live, validate with full provenance, deliver anywhere. Owned by **SIAX
Technology AB**. Honest accuracy is the moat: every field carries source, freshness and
confidence; nothing is guessed.
**Live:** https://0pt.app · **Contract:** [`CLAUDE.md`](CLAUDE.md) + [`docs/`](docs/)
> **Architecture (verified against code, not aspirational):**
> [`docs/architecture/ARCHITECTURE.md`](docs/architecture/ARCHITECTURE.md).
> It documents the real API surface, the real persistence story, and the known
> security gaps — including several places where this README is optimistic. Read
> it before trusting any capability claim below. Repo identity + estate
> classification: [`siax.repo.json`](siax.repo.json) +
> [`siax.config.json`](siax.config.json). Compliance state:
> [`docs/compliance/`](docs/compliance/) (INVENTORY, RELATIONS, OSS-INVENTORY,
> GOLDEN-STANDARD-REPORT, BACKLOG, SLUTRAPPORT).
## Two planes (see [docs/02-architecture.md](docs/02-architecture.md))
- **Edge (Vercel, this app)** — marketing, catalog, the order lifecycle, customer portal,
admin portal, and the API route handlers. Defers to the data engine when `ENGINE_URL` is set.
- **Engine (`services/api`, runs on a VPS)** — FastAPI orchestrator + worker pipeline doing
the **compliant** sourcing (official API → bulk → authorized web → licensed → else level 0).
Never on Vercel (long jobs). Bypass/stealth/proxy-rotation/fake-account paths are excluded
by design (CLAUDE.md §1).
## Routes
| Area | Routes |
|---|---|
| Marketing | `/` (hero, filosofi, katalog, motorn, visualiseringar, täckning, editorial, bevis, priser, footer) |
| Catalog | `/katalog`, `/katalog/[id]` |
| Sourcing map | `/kallor` |
| Order lifecycle | `/bestall` → `/bestall/forskott` → `/order/[id]` → `/order/[id]/validera` |
| Customer portal | `/portal`, `/portal/subscriptions`, `/portal/files`, `/portal/integrationer`, `/portal/settings` |
| Admin portal | `/admin`, `/admin/sources`, `/admin/jobs`, `/admin/customers` |
| API | `/api/{health,estimates,catalog,sources,orders,orders/[id],subscriptions,admin/metrics,uploads,auth/*,payments/*,webhooks/stripe,connections/db-grant}` |
## Design system
Mono/editorial, light, radius 0, Inter + JetBrains Mono, single red `#e40014`, animated grain,
scroll-reveal motion. **No photography** — imagery is rendered data (`DataArtifact`). Every fact
shows a provenance square (`ProvenanceBadge`). Full spec: [docs/05-design-system.md](docs/05-design-system.md).
## Run locally
**SIAX toolchain-kontrakt (mise):**
```bash
mise install # pinnar node 22.13.0 + pnpm 9.15.9 (se mise.toml [tools])
mise run setup # pnpm install --frozen-lockfile
mise run check # typecheck + lint (snabbt, deterministiskt)
mise run verify # vitest + next build (full svit)
mise run build # deploybar artefakt
```
mise är task-entrypoint (`mise.toml`); gate-logiken bor kvar i
`.gitea/workflows/` och package.json — pinning: `.siax/template-pin.json`.
```bash
pnpm dev # Next.js on http://localhost:3000
# data engine (separate, optional)
cd services/api && pip install -r requirements.txt && uvicorn orchestrator.main:app --reload
```
## Deploy
- **Config target (as of 2026-08-09):** `siax.config.json` declares `deploy.target: "coolify"`,
matching every other SIAX Cloud OS repo (n0d, st0re, aud0, ...) — a Dockerfile "for Coolify"
(already committed, see [`Dockerfile`](Dockerfile)) plus [`.gitea/workflows/cd.yml`](.gitea/workflows/cd.yml)
(renamed from `deploy.yml` 2026-08-10) that POSTs a restart to a Coolify app UUID on
`COOLIFY_TOKEN` push.
- ~~**Actually live right now:** the only running instance of `0pt.app` is still on **Vercel**
(project `0pt`, scope *Simon Axelsson's projects*) — no Coolify app has been provisioned for
this repo yet, so `deploy.yml`'s app UUID is a placeholder that fails the job on purpose until
someone fills it in. Flipping the config declares intent; it does not move traffic.~~ See
[`docs/architecture/ARCHITECTURE.md`](docs/architecture/ARCHITECTURE.md) §5/§8 for the full
"Vercel or fleet" state and what's still open (Coolify app provisioning + DNS cutover — a
separate decision from this config change, since the live Vercel deployment is not being
touched).
- **CORRECTED 2026-09-06 — the bullet above is no longer true. The Coolify deploy hook is LIVE.**
The repo secret `COOLIFY_TOKEN` exists (created 2026-08-31T11:34:34Z) and the repo Actions
variable `COOLIFY_APP_ID` holds a real 24-character UUID, **not** the
`TODO-no-coolify-app-provisioned-yet` literal. Both guard conditions in
[`.gitea/workflows/cd.yml`](.gitea/workflows/cd.yml) therefore pass. Measured on the push to
`main` at `1ff34410` (2026-09-06): job `Deploy to Coolify / deploy` (run 11695, job 26295)
finished **success** with `coolify deploy HTTP 200` in its log. **Every merge into `main` now
fires a real redeploy against `cloud.siax.io` — know what you are shipping before you merge.**
**Probed 2026-09-06 08:00 UTC:** `0pt.app` still answers from **Vercel** (`server: Vercel`, `x-vercel-id: arn1::…`) and returns **HTTP 402 `DEPLOYMENT_DISABLED` — "Payment required"** on both `/` and `/api/health`. So the public domain is *down*, DNS has **not** been cut over to Coolify, and the Coolify app — whatever state it is in — serves no `0pt.app` traffic. Two separate facts, both true at once: the deploy hook fires for real, and the product domain is dark behind an unpaid Vercel deployment.
Still not established: whether the Coolify app itself builds and starts — the deploy endpoint
returning 200 only means the request was accepted, not that a container came up healthy.
- **Engine + DB + embeds** → one VPS via [`infra/docker-compose.yml`](infra/docker-compose.yml) (Postgres+pgvector, Redis, api, worker, NocoDB, Metabase, Caddy).
- Env inventory: [`.env.example`](.env.example).
- **Auth on `/api/0pt/*` is fail-closed**: with `AUTH_ENFORCE` unset the middleware
REQUIRES a verified Zitadel Bearer token (401 without one). Only the literal
`AUTH_ENFORCE=false` disables it, and that is refused when `NODE_ENV=production`
(the process throws at startup rather than serving anonymously).
**Caveat (live-verified 2026-08-10):** the deployed instance still answers
`GET /api/0pt` with 200 anonymously — the middleware appears not to run in
production (gap S1, root cause unknown). Do not rely on this being enforced
until an anonymous request gets a real 401.
- **Fonts:** self-hosted via `@fontsource-variable/inter` +
`@fontsource-variable/jetbrains-mono` (no Google Fonts / `next/font/google`).
- **API contract (SSOT):** [`contracts/openapi.yaml`](contracts/openapi.yaml).
## Status
Frontend, full order lifecycle, customer + admin portals, edge API, payment/auth/embed
infrastructure, the compliant data engine, schema and infra are all in place and building green.
Integrations are env-guarded and activate when their keys/DB are provided:
1. **Database** — Vercel → Storage → Postgres (sets `POSTGRES_URL`) → durable persistence (schema in [`sql/001_init.sql`](sql/001_init.sql)).
2. **Stripe + Resend** keys → payments + email.
3. **VPS** for the engine → set `ENGINE_URL`.
4. **`AUTH_SECRET` + `DEV_LOGIN_KEY`** → login (full OAuth via Auth.js lands with the DB).
© 2026 SIAX Technology AB. Not affiliated with Protosell.