Rastrum Rastrum

Architecture

Stack decisions, AI pipeline routing, cost model, and iOS PWA constraints.

# Stack Decisions

Layer Choice Rationale
Frontend SvelteKit Lightweight, SSR+SPA, good offline story for write-heavy PWA
Local DB Dexie (IndexedDB) Offline-first, sync-ready, append-heavy single-author pattern
AI Runtime ONNX Runtime Web On-device inference via WebAssembly, WebGPU fallback
Object Storage Cloudflare R2 S3-compatible, zero egress fees ($150/mo vs $4,710/mo Supabase at 10K MAU)
Backend Supabase Postgres + PostGIS + pgvector + Auth + Realtime + Storage
Maps MapLibre GL JS Open-source, self-hostable, pmtiles on R2 for offline tiles

# AI Identification Pipeline

User uploads media | v Client-side EXIF extraction (exifr) --> GPS, timestamp, device | v Pre-ID quality check --> blur / dark warning | |--- Plant detected? --------> PlantNet Pro API (78K species) | |--- Bird sound? ------------> BirdNET (commercial license) | +--- General image/video ---> Gemini 2.5 Flash-Lite (~$0.001) | +-- conf >= 0.8 --> Result | +-- conf < 0.8 --> Claude Haiku 4.5 (~$0.01) | +-- conf >= 0.7 --> Result | +-- Low conf --> Expert queue Offline fallback: EfficientNet-Lite0 INT8 ONNX (<3MB, top 500 species) + Regional packs (Oaxaca/Yucatan, 10-30MB, lazy-loaded into IndexedDB)

# Cost Model

Scale Monthly Cost Per User
10K MAU ~$2,000 $0.20
50K MAU ~$6,000 $0.12
100K MAU ~$11,500 $0.12

10K MAU breakdown: AI inference $800, object storage $400, compute $500, monitoring and misc $300. Includes Supabase Pro, Cloudflare R2, ~500K Haiku calls, 600K PlantNet Pro calls, and Gemini Flash-Lite first-pass.

# Data Model

Core tables in the Supabase Postgres schema, partitioned monthly via pg_partman. PostGIS geography types for spatial queries, pgvector for semantic species search.

Table Purpose Key Fields
users User accounts and profiles id, display_name, role, language_pref
observations Core observation records with location and environment id, observer_id, observed_at, location (PostGIS), moon_phase, precipitation
species Taxonomic reference with NOM-059 categories id, scientific_name, common_names (jsonb), nom_059_category
media_files Photos, audio, video with EXIF metadata id, observation_id, media_type, r2_key, exif_data (jsonb)
identifications AI and human ID results with confidence scores id, observation_id, taxon_id, confidence, source, is_research_grade
expert_validations Expert review with taxonomic badge verification id, identification_id, validator_id, verdict, notes