Four decisions this document exists to defend: native AR over WebAR, two recognition pipelines instead of one, Stripe Connect with Spain's actual payment rails, and an offline-first tour runtime. Each one came out of research, not guesswork.
| Layer | Choice | Why |
|---|---|---|
| Mobile clients | Swift/SwiftUI (iOS), Kotlin/Jetpack Compose (Android) | Native AR needs native frameworks — ARKit and ARCore aren't cross-platform |
| AR — iOS | ARKit + RealityKit, geo-anchors | Apple's geospatial anchoring for outdoor mural placement |
| AR — Android | ARCore + Geospatial API (VPS) | Google's Visual Positioning Service, same outdoor use case |
| Image recognition | On-device Core ML / ML Kit, cloud fallback | Indoor gallery pieces, where GPS/VPS can't help |
| Backend | Node.js / NestJS, PostgreSQL + PostGIS | PostGIS for geofencing and stop-radius queries |
| CMS / admin | Same backend, role-scoped API | One source of truth for app and console |
| Payments | Stripe Connect (destination charges) | Multi-party payout without Arteria touching bank data |
| Analytics | Firebase Analytics + BigQuery export | Install/session tracking client asked for, queryable funnel |
| Maps | Vector tiles (self-hosted) or Mapbox | Styleable to the design system, offline-cacheable |
The brief asks for one feature — "point your camera, reveal extra content." That's actually two different technical problems wearing the same UI.
Niantic's 8th Wall — the standard WebAR platform — is winding down. Hosted projects go dark February 2027, and Niantic's VPS was explicitly excluded from the open-source release. Any WebAR-based plan for this product has a two-year shelf life at most. We rule it out and build native from day one.
ARCore Geospatial API (Android) / ARKit geo-anchors (iOS), backed by Google's VPS where Street View coverage exists. This is how murals and landmarks get placed precisely in the real world.
On-device ML first (fast, offline-capable), cloud match as fallback. This is the only path indoors — GPS and VPS don't work inside a gallery, so every indoor stop resolves this way, the Smartify/Bloomberg Connects model.
A short code printed on a small plaque at every stop. Always works, zero dependencies. Demoed in ar-fallback.html.
Same content, no overlay. Older devices land here directly — no dead end, ever.
The POC's ar-scan.html simulates this sequence visually — the in-app "how this actually works" panel shows the same ladder to the demo audience.
Madrid's metro kills signal, and crowded plazas throttle it. Every tour is downloadable as a self-contained pack: stop content, audio, map tiles for the tour's bounding box, and the AR image-target index for that route's stops. Geofence arrival detection runs on cached GPS regardless of connectivity; only marketplace actions (checkout, reviews) require a live connection.
Stripe Connect, destination charges. The platform account collects the full payment at checkout; Stripe splits and transfers the artist's share automatically once an order is marked delivered. Artists complete Stripe's own KYC and bank-detail onboarding — Arteria never stores payment credentials or bank data, which keeps PCI scope minimal.
Role-scoped API tokens for the admin console (see the RBAC matrix in users-roles.html), TLS everywhere, encrypted at rest. Location data used for geofencing is processed on-device where possible; server-side location logging is minimized to what tour-completion analytics actually needs, disclosed in-app during onboarding.