Section 05
Tech stack
The agreed stack and the structure that organises it. Defaults are committed where possible; remaining choices are listed in Section 20 — Open Decisions.
5.1 — Mobile app
| Concern | Choice | Notes |
|---|---|---|
| Framework | Flutter | Stable channel. Lock the SDK version in pubspec.yaml. |
| Language | Dart | Sound null safety on. |
| Platforms | iOS, Android | Tablet layouts in scope; not a launch priority. |
| Architecture | Feature‑first clean architecture | One folder per feature; shared concerns in core/. |
| Rendering | CustomPainter | Single painter per canvas surface — see Section 11. |
| State | Riverpod 2.x | Pin major version. Avoid mixing with Provider. |
| Routing | GoRouter | Declarative routes; deep linking enabled. |
| HTTP | Dio | Interceptors for auth, retries, logging. |
| Local DB | Drift | Chosen over Isar — see Section 20. |
| Secure storage | flutter_secure_storage | For auth tokens and receipt cache. |
| IAP | in_app_purchase | StoreKit 2 on iOS, Billing 6+ on Android. |
| Files / cache | path_provider | Bundle cache under app‑support directory. |
| Path parsing | path_drawing | Required to parse SVG path strings — see Section 06. |
| Compression | brotli (Dart) | Used to decompress region payloads. |
| Remote config | GrowthBook or equivalent | For paywall toggles and staged rollouts. |
Suggested module structure
lib/
app/
core/
network/
storage/
analytics/
config/
features/
library/
artwork_detail/
download/
canvas/
palette/
progress/
auth/
paywall/
admin_preview/
settings/
5.2 — Backend
| Concern | Choice |
|---|---|
| Platform | InsForge |
| Database | PostgreSQL (managed via InsForge) |
| API layer | PostgREST‑style auto‑generated APIs + edge functions for write paths |
| Authentication | InsForge Auth (email + Apple + Google) |
| Storage | InsForge Storage (S3‑compatible) fronted by a CDN |
| Authorisation | Row‑level security policies — see Section 07 |
InsForge is responsible for user authentication, the catalogue, asset hosting, entitlement records, purchase validation, progress sync, the admin publishing workflow, and the signed‑URL gateway for premium asset access.
5.3 — Asset storage layout
Artwork assets are stored remotely as structured bundles, one folder per artwork:
artworks/
<slug>/
manifest.json
regions.bin.br # binary, brotli-compressed
preview.webp
thumbnail.webp
line_art.svg # optional, reference only
version.txt
The app downloads bundles on demand and caches them under the app‑support directory. Locale variants of manifest.json are not stored alongside the bundle — translatable strings live in PostgreSQL (see Section 07).