bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
398 lines
13 KiB
Markdown
398 lines
13 KiB
Markdown
# quiXzoom — Internationell Standard v1
|
|
**LÅST 2026-06-15 · Beslutat av Erik Svensson**
|
|
**Detta är single source of truth. Inga dubbletter tillåts.**
|
|
|
|
---
|
|
|
|
## 1. DOMÄNER — KANONISK LISTA
|
|
|
|
| Domän | DNS | Vad den gör | Status |
|
|
|-------|-----|-------------|--------|
|
|
| `quixzoom.com` | CloudFront (108.157.229.x) | Apex → 301 till `www.quixzoom.com` | ✅ Live |
|
|
| `www.quixzoom.com` | CloudFront (108.157.229.x) | Publik webbsajt (zoomer-start.html som entry) | ✅ Live |
|
|
| `api.quixzoom.com` | server-2 direkt (16.170.83.169) | REST API — enda ingångspunkt för all klienttrafik | ✅ Live |
|
|
| `app.quixzoom.com` | CloudFront (dewrtqzc20flx) | iOS/web-app (S3/CloudFront) | ✅ DNS live, CloudFront aktiv |
|
|
|
|
### Legala sidor (på quixzoom.com/www.quixzoom.com)
|
|
Serveras direkt av nginx som statiska filer (krav för App Store):
|
|
|
|
| URL | Fil |
|
|
|-----|-----|
|
|
| `quixzoom.com/privacy` | `/opt/amos/public/quixzoom/privacy.html` |
|
|
| `quixzoom.com/terms` | `/opt/amos/public/quixzoom/terms.html` |
|
|
| `quixzoom.com/support` | `/opt/amos/public/quixzoom/support.html` |
|
|
| `www.quixzoom.com/privacy` | samma |
|
|
| `www.quixzoom.com/terms` | samma |
|
|
| `www.quixzoom.com/support` | samma |
|
|
| `www.quixzoom.com/reviews` | `/opt/amos/public/quixzoom/reviews.html` |
|
|
|
|
### CORS — godkända origins
|
|
```
|
|
https://app.quixzoom.com
|
|
https://www.quixzoom.com
|
|
https://quixzoom.com
|
|
https://api.quixzoom.com
|
|
+ waitlist-domäner (quixzoom.se/de/fr/nl/co.uk/fi/dk/es/it/eu/asia/be/ch/jp)
|
|
```
|
|
|
|
### ❌ INTE AKTIVA — ska INTE refereras till
|
|
- `quixzoom-api.wavult.com` — 301 till api.quixzoom.com (legacy, behålls bara för redirect)
|
|
- `amos.wavult.com/api/qz/` — gammal route, ska EJ användas
|
|
|
|
---
|
|
|
|
## 2. TJÄNSTER — AKTIVA (server-2, systemctl)
|
|
|
|
| Tjänst | Port | Runtime | Syfte |
|
|
|--------|------|---------|-------|
|
|
| `quixzoom-api.service` | 3209 | Node.js / systemctl | Huvud-API: auth, missions, payments, KYC, onboarding |
|
|
| `aamos-quixzoom-engine.service` | 3390 | Rust / systemctl | Optisk analys, bildbehandling |
|
|
| `aamos-billing-engine.service` | 3392 | Rust / systemctl | Stripe-betalningar |
|
|
| `qz-webhook.service` | 9100 | Node.js / systemctl | CI/CD deploy webhook (intern, ej publik) |
|
|
|
|
**Ingen PM2 för quiXzoom.** Alla fyra kör systemctl. ✅
|
|
|
|
---
|
|
|
|
## 3. NGINX — ROUTING (kanonisk)
|
|
|
|
### api.quixzoom.com (server-2 origin, 443)
|
|
```
|
|
/api/qz/engine/ → 127.0.0.1:3390 (quixzoom-engine Rust)
|
|
/api/qz/ → 127.0.0.1:3209 (quixzoom-api Node)
|
|
/health → 127.0.0.1:3209/health
|
|
/ → 404 JSON (lockdown — inget okänt passerar)
|
|
```
|
|
|
|
### www.quixzoom.com (CloudFront origin → nginx om origin-hit, 443)
|
|
```
|
|
/api/qz/ → 127.0.0.1:3209 (quixzoom-api)
|
|
/api/quixzoom/ → 127.0.0.1:3209 (legacy alias — se §7)
|
|
/privacy|/terms|/support|/reviews → statiska HTML-filer
|
|
/ → /opt/amos/public/quixzoom/ (zoomer-start.html)
|
|
```
|
|
|
|
### quixzoom.com (apex, 443)
|
|
```
|
|
/privacy|/terms|/support → statiska HTML-filer
|
|
/ → 301 → https://www.quixzoom.com$uri
|
|
```
|
|
|
|
---
|
|
|
|
## 4. API — KANONISKA ENDPOINTS
|
|
|
|
**Base URL:** `https://api.quixzoom.com`
|
|
**Alla routes under:** `/api/qz/`
|
|
|
|
### Auth (Zoomers)
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| POST | `/api/qz/auth/register` | Registrera zoomer |
|
|
| POST | `/api/qz/auth/login` | Logga in zoomer |
|
|
| GET | `/api/qz/auth/me` | Profil (auth krävs) |
|
|
| POST | `/api/qz/auth/refresh` | Förnya JWT |
|
|
| PATCH | `/api/qz/auth/me` | Uppdatera profil |
|
|
| GET | `/api/qz/auth/wallet` | Zoomer-plånbok |
|
|
|
|
### Onboarding (Orderers/B2B)
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| GET | `/api/qz/onboarding/price-calc` | Live prisberäkning |
|
|
| POST | `/api/qz/onboarding/create-org` | Skapa organisation |
|
|
|
|
### Orderers (B2B)
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| POST | `/api/qz/orderers/register` | Registrera orderer |
|
|
| POST | `/api/qz/orderers/login` | Logga in orderer |
|
|
| GET | `/api/qz/orderers/me` | Orderer-profil |
|
|
| POST | `/api/qz/orderers/missions` | Skapa mission |
|
|
| GET | `/api/qz/orderers/missions` | Lista mina missions |
|
|
| GET | `/api/qz/orderers/missions/:id` | Hämta mission |
|
|
|
|
### Missions (Zoomers)
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| GET | `/api/qz/missions` | Lista tillgängliga missions |
|
|
| GET | `/api/qz/missions/near` | Geo-filtrerade missions |
|
|
| GET | `/api/qz/missions/stats` | Statistik |
|
|
| GET | `/api/qz/missions/leaderboard` | Topplista |
|
|
| GET | `/api/qz/missions/claims/active` | Aktiva claims (auth) |
|
|
| POST | `/api/qz/missions/claims` | Claima mission (auth) |
|
|
| PATCH | `/api/qz/missions/claims/:id` | Uppdatera claim (auth) |
|
|
| GET | `/api/qz/missions/:id` | Hämta mission |
|
|
| POST | `/api/qz/missions` | Skapa mission (auth) |
|
|
| PATCH | `/api/qz/missions/:id/claim` | Claima via patch (auth) |
|
|
| POST | `/api/qz/missions/:id/submit` | Skicka in (auth) |
|
|
| POST | `/api/qz/missions/:id/approve` | Godkänn (auth) |
|
|
|
|
### Payments
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| GET | `/api/qz/payments/status` | Betalningstatus |
|
|
| POST | `/api/qz/payments/checkout` | Stripe checkout (orderer auth) |
|
|
| POST | `/api/qz/payments/webhook` | Stripe webhook (intern) |
|
|
| POST | `/api/qz/payments/refund` | Återbetalning (orderer auth) |
|
|
| POST | `/api/qz/payments/stripe-connect` | Koppla Stripe (zoomer auth) |
|
|
| GET | `/api/qz/payments/stripe-connect/status` | Connect-status (zoomer auth) |
|
|
| GET | `/api/qz/payments/balance` | Saldo (orderer auth) |
|
|
| POST | `/api/qz/payments/credits/add` | Lägg till credits (admin) |
|
|
| GET | `/api/qz/payments/fees` | Avgiftsstruktur (publik) |
|
|
| GET | `/api/qz/payments/wallet` | Zoomer-plånbok |
|
|
|
|
### Payouts
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| GET | `/api/qz/payouts/status` | Utbetalningsstatus |
|
|
| GET | `/api/qz/payouts/currencies` | Valutor |
|
|
| POST | `/api/qz/payouts/request` | Begär utbetalning (auth) |
|
|
| GET | `/api/qz/payouts/history` | Historik (auth) |
|
|
| GET | `/api/qz/payouts/pending` | Väntande (auth) |
|
|
| POST | `/api/qz/payouts/batch` | Batch-utbetalning (auth) |
|
|
|
|
### KYC
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| POST | `/api/qz/kyc/challenge` | Starta KYC (auth) |
|
|
| POST | `/api/qz/kyc/upload/:type` | Ladda upp dokument (auth) |
|
|
| POST | `/api/qz/kyc/verify-doc` | Verifiera dokument (auth) |
|
|
| POST | `/api/qz/kyc/verify` | Verifiera identity (auth) |
|
|
| GET | `/api/qz/kyc/status/:session_id` | KYC-status (auth) |
|
|
| GET | `/api/qz/kyc/me` | Min KYC-status (auth) |
|
|
| GET | `/api/qz/kyc/admin/reviews` | Admin: granska (admin) |
|
|
|
|
### Waitlist
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| POST | `/api/qz/waitlist` | Anmäl dig till waitlist |
|
|
| GET | `/api/qz/waitlist/count` | Antal på waitlist |
|
|
|
|
### Notifications
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| GET | `/api/qz/notifications` | Hämta notiser (auth) |
|
|
| PATCH | `/api/qz/notifications/read-all` | Markera alla lästa (auth) |
|
|
| PATCH | `/api/qz/notifications/:id` | Uppdatera notis (auth) |
|
|
|
|
### Storage
|
|
| Method | Path | Beskrivning |
|
|
|--------|------|-------------|
|
|
| POST | `/api/qz/storage/upload` | Ladda upp fil (auth, rate-limited) |
|
|
|
|
### Identity/GDPR
|
|
```
|
|
/api/qz/identity — GDPR-samtycke + KYC fas 1
|
|
```
|
|
|
|
### LandveX-integration
|
|
```
|
|
/api/qz/landvex — Intern webhook från LandveX → missions
|
|
```
|
|
|
|
### Health
|
|
```
|
|
GET /health → {"status":"ok","service":"quixzoom-api"}
|
|
```
|
|
|
|
### ❌ DISABLED
|
|
```
|
|
/api/onboarding → 410 Gone (gammal path, permanent disabled)
|
|
```
|
|
|
|
---
|
|
|
|
## 5. ZOOMER-FLÖDE (Onboarding)
|
|
|
|
```
|
|
1. Zoomer besöker www.quixzoom.com
|
|
└─ serveras: /opt/amos/public/quixzoom/zoomer-start.html
|
|
|
|
2. Klickar "Bli Zoomer"
|
|
└─ navigerar till: join.html ELLER zoomer-onboarding-flow.html
|
|
|
|
3. Registrering
|
|
└─ POST /api/qz/auth/register
|
|
└─ Svarar: JWT access_token + refresh_token
|
|
|
|
4. KYC (identitetsverifiering)
|
|
└─ POST /api/qz/kyc/challenge
|
|
└─ POST /api/qz/kyc/upload/:type
|
|
└─ POST /api/qz/kyc/verify
|
|
|
|
5. Acceptera villkor
|
|
└─ /api/qz/identity (GDPR-samtycke)
|
|
|
|
6. Redo — kan se och claima missions
|
|
└─ GET /api/qz/missions/near
|
|
|
|
7. Utbetalning
|
|
└─ POST /api/qz/payments/stripe-connect (koppla Stripe)
|
|
ELLER
|
|
└─ swish_number i profil → direktutbetalning
|
|
```
|
|
|
|
**Entry-points (HTML):**
|
|
- `www.quixzoom.com` → `zoomer-start.html` (primär, iOS-native design)
|
|
- `www.quixzoom.com/join.html` → alternativ entry
|
|
- `www.quixzoom.com/zoomer-onboarding-flow.html` → fullständigt flöde
|
|
|
|
---
|
|
|
|
## 6. ORDERER-FLÖDE (Onboarding B2B)
|
|
|
|
```
|
|
1. Orderer hittar quiXzoom (via LandveX-kanal)
|
|
|
|
2. Registrering
|
|
└─ POST /api/qz/orderers/register
|
|
└─ Svarar: orderer JWT
|
|
|
|
3. Prisberäkning
|
|
└─ GET /api/qz/onboarding/price-calc
|
|
|
|
4. Skapa organisation
|
|
└─ POST /api/qz/onboarding/create-org
|
|
|
|
5. Betala för mission
|
|
└─ POST /api/qz/payments/checkout (Stripe)
|
|
|
|
6. Skapa mission
|
|
└─ POST /api/qz/orderers/missions
|
|
└─ Eller automatiskt via LandveX-webhook
|
|
|
|
7. Granska resultat
|
|
└─ GET /api/qz/orderers/missions/:id
|
|
└─ POST /api/qz/missions/:id/approve
|
|
```
|
|
|
|
**Kundrelation:** Orderers har avtal med **LandveX AB** — quiXzoom är back-end. Kunden ser LandveX, inte quiXzoom (B2B-flödet är internt).
|
|
|
|
---
|
|
|
|
## 7. OFFBOARDING — ZOOMER
|
|
|
|
```
|
|
1. Zoomer begär borttagning
|
|
└─ PATCH /api/qz/auth/me (deaktivera konto)
|
|
|
|
2. Utestående utbetalningar
|
|
└─ GET /api/qz/payouts/pending → betala ut allt
|
|
└─ POST /api/qz/payouts/request
|
|
|
|
3. GDPR-rensning
|
|
└─ /api/qz/identity (withdraw consent → data deletion)
|
|
|
|
4. Konto inaktiverat
|
|
└─ JWT invalideras vid nästa request
|
|
```
|
|
|
|
---
|
|
|
|
## 8. OFFBOARDING — ORDERER
|
|
|
|
```
|
|
1. Stäng aktiva missions
|
|
└─ PATCH /api/qz/orderers/missions (status → closed)
|
|
|
|
2. Utestående betalningar
|
|
└─ GET /api/qz/payments/balance → begär återbetalning
|
|
└─ POST /api/qz/payments/refund
|
|
|
|
3. Organisation inaktiveras
|
|
└─ Via admin (Erik/Bernt direkt i DB)
|
|
```
|
|
|
|
---
|
|
|
|
## 9. DEPLOY-FLÖDE
|
|
|
|
```
|
|
Johan pushar kod till Gitea
|
|
│
|
|
▼
|
|
qz-webhook.service (:9100) tar emot
|
|
│
|
|
▼
|
|
deploy.sh
|
|
• git pull
|
|
• npm ci
|
|
• systemctl restart quixzoom-api
|
|
│
|
|
▼
|
|
nginx → quixzoom-api live
|
|
```
|
|
|
|
**Inga Docker. Inga K8s. Ingen PM2. Allt är systemctl.**
|
|
|
|
---
|
|
|
|
## 10. SÄKERHET — FASTA REGLER
|
|
|
|
1. **Credentials:** ALDRIG i source code. `.env` eller AWS Secrets Manager.
|
|
2. **API lockdown:** `api.quixzoom.com/` returnerar 404 JSON på okända paths.
|
|
3. **Rate limits:** 60 req/min globalt, 10/min login, 5/min register.
|
|
4. **CORS:** Strängt — bara godkända origins i `ALLOWED_ORIGINS`.
|
|
5. **Auth:** JWT RS256 (ouroboros-identity, port 3207).
|
|
6. **KYC:** Krävs för utbetalning.
|
|
|
|
---
|
|
|
|
## 11. STATISKA FILER — /opt/amos/public/quixzoom/
|
|
|
|
**Primära (production-kritiska):**
|
|
| Fil | Syfte |
|
|
|-----|-------|
|
|
| `zoomer-start.html` | Entry-point, www.quixzoom.com index |
|
|
| `join.html` | Registreringsflöde (alternativ entry) |
|
|
| `zoomer-onboarding-flow.html` | Fullständigt onboarding-flöde |
|
|
| `privacy.html` | Integritetspolicy (App Store krav) |
|
|
| `terms.html` | Användarvillkor (App Store krav) |
|
|
| `support.html` | Support-sida (App Store krav) |
|
|
| `reviews.html` | Recensioner |
|
|
| `i18n.js` | Internationalisering (JS) |
|
|
|
|
**Övriga (dashboard/intern):**
|
|
`customer-dashboard.html`, `zoomer-app.html`, `zoomer-profile.html`, `zoomer-earnings.html`, `mission-detail.html`, `mission-map.html`, `map.html`, `admin.html`, `analytics.html`, `revenue.html`, `launch-status.html` m.fl.
|
|
|
|
---
|
|
|
|
## 12. PÅGÅENDE / ÖPPNA ÅTGÄRDER
|
|
|
|
| Prioritet | Issue | Status |
|
|
|-----------|-------|--------|
|
|
| 🔴 | `/api/quixzoom/` legacy alias i nginx + HTML-filer bör migreras till `/api/qz/` | Öppen — blockas av app-uppdatering |
|
|
| 🔴 | `credentials i index.mjs` — AWS_ACCESS_KEY_ID i källkod | Ska städas av Johan/Sven |
|
|
| 🟡 | `app.quixzoom.com` — vad serveras via CloudFront/S3? | Verifiera innehåll |
|
|
| 🟡 | `www.quixzoom.com` via CloudFront — origin fallback till server-2 OK? | Verifiera CloudFront-config |
|
|
| 🟡 | BankID-integration för KYC | Inte live — leverantörsavtal saknas |
|
|
| 🟡 | Stripe Connect live-keys | Inte live — Delaware-konto hanterar |
|
|
| 🟢 | Gamla PM2-processer för quixzoom (id 7, 14) → städades 2026-06-14 | ✅ Klart |
|
|
|
|
---
|
|
|
|
## 13. VAD SOM INTE FINNS / INTE ANVÄNDS
|
|
|
|
| Sak | Notering |
|
|
|-----|----------|
|
|
| `missions-service` (port 7060) | Existerar EJ — nginx-route borttagen |
|
|
| `regulatory-service` (port 7050) | Existerar EJ — nginx-route borttagen |
|
|
| Kong API Gateway | Avvecklat. Alla requests via nginx direkt. |
|
|
| MSK Kafka | Inte kopplat till quiXzoom. Ska avvecklas (kostnadsanalys). |
|
|
| `/api/onboarding` | 410 Gone — permanent disabled i koden |
|
|
| `vault.aamos.systems` | Nedlagd. Secrets i AWS Secrets Manager. |
|
|
|
|
---
|
|
|
|
## 14. BETALNINGSSTRUKTUR (LÅST 2026-06-14)
|
|
|
|
- **Stripe-konto:** kopplat till Delaware-entiteten (QuiXzoom Inc)
|
|
- **Fakturering:** LandveX AB saluför quiXzoom EU-intäkter via IP-avtal
|
|
- **Intäkter FY 2026/2027:** bokförs i LandveX AB
|
|
- **Inga kontobyten** utan Eriks explicita beslut
|
|
|
|
---
|
|
|
|
*Nästa revision: vid strukturförändring. Ägare: Erik Svensson / Bernt.*
|
|
*Versionsnummer ökas vid varje låst revision.*
|