Simon AxelssonandClaude Opus 5 1322d26fac
Security Scan (SIAX Cloud) / security (push) Successful in 17s
CI (SIAX Cloud) / security (push) Successful in 25s
CI (SIAX Cloud) / integration (push) Failing after 31s
CI (SIAX Cloud) / quality (push) Successful in 34s
fix(ci): make the required security gate capable of failing
Branch protection on `main` requires exactly two status contexts:

    CI (SIAX Cloud) / security (push)
    CI (SIAX Cloud) / quality (push)

The `security` half could not fail. All three Trivy invocations in this
repo ran with `--exit-code 0`, so the scanner reported findings to stdout
and then exited 0 regardless.

Measured on main @4514d97, 2026-09-08, same scanner (Trivy 0.73.0), same
target, only the flag differing:

  A  --exit-code 0, clean tree                        -> exit 0
  B  --exit-code 0, planted AWS secret access key     -> exit 0  (DETECTED
     as CRITICAL in the report, gate still green)
  C  --exit-code 1, same planted secret               -> exit 1
  D  --exit-code 1, probe removed                     -> exit 0

B is the defect: the required context reported success while the scanner
had a CRITICAL secret in hand. D is why this is safe to land now -- the
tree is clean today, so flipping the flag does not open the gate red.
(PR #19 measured 19 HIGH findings on 2026-08-11; those dependencies have
since been updated on main, 142 commits later.)

The other required context, `quality`, was verified real and left alone:
a planted type error fails `pnpm run typecheck` (exit 2) and a planted
failing assertion fails `pnpm run test` (exit 1, 945 passed baseline).

nightly.yml carried the same flag. A nightly scan exists to catch CVEs
published against code that did not change; with `--exit-code 0` it could
never raise that alarm.

Not fixed here, needs an owner decision: services/scrapers/requirements.txt
uses `>=` ranges only. Trivy's pip scanner cannot resolve unpinned
specifiers, so it omits the file from the scan entirely -- it never appears
as a target. Pinning those same floors with `==` surfaces 3 HIGH findings
(aiohttp CVE-2025-69223, aiohttp CVE-2026-69244, lxml CVE-2026-41066).
Deliberately NOT suppressed with `--skip-dirs`, which would turn a
measurable blind spot into declared policy.

Job names are unchanged, so both required context strings are preserved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 01:16:08 +02:00
2026-06-24 14:47:12 +00:00
2026-06-24 14:47:12 +00:00
2026-06-24 14:47:12 +00:00
2026-06-24 14:47:12 +00:00
2026-09-06 03:01:40 +00:00
2026-09-06 03:01:40 +00:00
2026-06-24 14:47:12 +00:00
2026-06-24 14:51:57 +00:00

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 + docs/

Architecture (verified against code, not aspirational): 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.config.json. Compliance state: docs/compliance/ (INVENTORY, RELATIONS, OSS-INVENTORY, GOLDEN-STANDARD-REPORT, BACKLOG, SLUTRAPPORT).

Two planes (see 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.

Run locally

pnpm install
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) plus .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 §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 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 (Postgres+pgvector, Redis, api, worker, NocoDB, Metabase, Caddy).
  • Env inventory: .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.

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).
  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.

S
Description
No description provided
Readme
26 MiB
Languages
TypeScript 90.3%
Python 5.5%
JavaScript 2.1%
PLpgSQL 1.4%
Shell 0.3%
Other 0.4%