NAFA (Neurodiverse App for Adventurers) uses a ReScript + Deno architecture:
-
ReScript for type-safe client code with TEA (The Elm Architecture) pattern
-
Deno for server runtime and package management
-
Shared types for compile-time guarantees across the stack
| Feature | Status | Location |
|---|---|---|
Journey Plan View |
✅ Complete |
|
Sensory Annotations |
✅ Complete |
|
Accessibility Settings |
✅ Complete |
|
Offline Mode |
✅ Complete |
|
Domain Types |
✅ Complete |
|
Routing |
✅ Complete |
|
Deno Server |
✅ Complete |
|
CLI Demo |
✅ Complete |
|
nafa-app/
├── client/ # Browser SPA (ReScript)
│ ├── src/
│ │ ├── Main.res # App entry with TEA pattern
│ │ └── Page/
│ │ ├── JourneyView.res # Journey display
│ │ ├── Annotate.res # Sensory annotation form
│ │ ├── Accessibility.res # A11y settings
│ │ └── Offline.res # Offline mode management
│ └── rescript.json
│
├── server/ # Deno API server
│ ├── src/
│ │ ├── main.js # HTTP server with REST API
│ │ └── demo.js # CLI demo runner
│ └── deno.json
│
├── shared/ # Shared types
│ ├── src/
│ │ ├── Domain.res # Core domain types
│ │ └── Route.res # Type-safe routing
│ └── rescript.json
│
├── nickel-rituals/ # Badge/tier configuration
├── scripts/ # Build scripts
├── Justfile # Task runner
└── PLAN.adoc # This file┌─────────────────────────────────────────────────────────────────┐
│ nafa-app │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────────┐ ┌────────────────┐ │
│ │ Deno │ │ ReScript │ │ @rescript/core│ │
│ │ │ │ │ │ │ │
│ │ HTTP server │ │ TEA pattern │ │ Standard lib │ │
│ │ JSR imports │ │ Type-safe views │ │ Belt, Core │ │
│ └─────────────┘ └──────────────────┘ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘These external packages are planned but not yet available:
| Package | Purpose | Status |
|---|---|---|
|
Type-safe URL parsing (Parser, Navigation, Link) |
Branch exists, not published to JSR |
|
TEA integration via |
Needs GitHub repo creation |
|
Full TEA framework for browser |
Available on npm, not yet integrated |
|
Note
|
The MVP is fully functional without these dependencies. They will enable richer browser-based routing when published. |
# Run the CLI demo
just mvp-demo
# Start the API server (requires Deno)
just mvp-server
# Development mode with watch
just mvp-dev
# Build ReScript modules
just mvp-build
# Type-check server files
just mvp-checktype sensoryLevel = int // 0-10 scale
type sensoryProfile = {
noise: sensoryLevel,
light: sensoryLevel,
crowd: sensoryLevel,
}type transportMode = Walk | Bus | Train | Tram | Metro
type journeySegment = {
id: string,
transportMode: transportMode,
fromLocation: string,
toLocation: string,
durationMinutes: int,
sensoryWarning: option<string>,
sensoryLevels: option<sensoryProfile>,
}
type journeyStatus = Planning | Active | Paused | Completed
type journey = {
id: string,
title: string,
segments: array<journeySegment>,
status: journeyStatus,
estimatedMinutes: int,
sensoryAnnotations: array<sensoryAnnotation>,
}type textSize = Small | Medium | Large | ExtraLarge
type contrastMode = Standard | HighContrast | DarkHighContrast
type motionPreference = Full | Reduced | None
type hapticPreference = Off | Subtle | Standard | Strong
type accessibilityPrefs = {
textSize: textSize,
contrastMode: contrastMode,
motionPreference: motionPreference,
screenReaderVerbosity: screenReaderVerbosity,
hapticFeedback: hapticPreference,
reduceTransparency: bool,
boldText: bool,
monoAudio: bool,
}type connectivityStatus = Online | Offline | Connecting | Unstable
type syncStatus = Synced | Pending | Syncing | Conflict | Error(string)
type cached<'a> = {
data: 'a,
cachedAt: float,
syncStatus: syncStatus,
version: int,
}
type offlinePrefs = {
enableOfflineMode: bool,
autoSync: bool,
syncOnWifiOnly: bool,
maxCacheAgeDays: int,
prefetchUpcomingJourneys: bool,
}-
✓ Create directory structure (client/, server/, shared/)
-
✓ Initialize rescript.json for each package
-
✓ Set up shared type definitions (Domain.res, Route.res)
-
✓ Configure deno.json for server
-
✓ Implement journey view with TEA pattern
-
✓ Implement sensory annotation flow
-
✓ Implement accessibility settings
-
✓ Implement offline mode management
-
✓ Create Deno HTTP server with REST API
-
✓ Create CLI demo runner
-
✓ Remove legacy Elm files (src/*.elm)
-
✓ Remove malformed files (elm-ui, assets)
-
✓ Remove empty directories (elixir-backend)
-
❏ Publish
@cadre/routerto JSR -
❏ Create and publish
@cadre/tea-router -
❏ Integrate rescript-tea for browser runtime
-
❏ Add browser entry point (index.html)
-
❏ Implement real API integration (replace mocks)
-
❏ Add authentication/session management
-
❏ Server-side routing (Stage 3)
-
❏ CRDT state for real-time features
-
Native TypeScript/JavaScript support
-
Built-in formatter and linter
-
Secure by default (explicit permissions)
-
JSR for modern package management
-
No node_modules bloat
-
Sound type system (no
anyescape hatch) -
Exhaustive pattern matching
-
Guaranteed null-safety with
option<T> -
Compiles to clean JavaScript
-
TEA pattern feels natural
-
Browser Integration: Add
index.htmland wire up ReScript to DOM -
Real Data: Replace mock journey with API calls
-
Persistence: Implement IndexedDB for offline storage
-
Testing: Add unit tests for domain logic
-
CI/CD: Configure build pipeline for ReScript + Deno