# 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.*