Releases: Quavon-dev/uptime-pocket
v0.3.0 — Phase 2: Auth + Servers
Phase 2 — Auth + Servers
Phase 2 ships the full auth + server stack. Uptime Pocket can now persist servers across launches, securely store Kuma credentials, and keep a live socket connection to a Kuma instance with the live data flowing into the Monitors tab.
Persistence
- SQLite via
expo-sqlitefor server metadata (id, name, url, auth kind, notification mode, kuma version, connection state, timestamps). Hand-rolled SQL behind a thinserversRepo— the only module that touches theserverstable directly. - Idempotent migration runner (
src/data/db/migrate.ts) readsschema_versionand applies only newer migrations on launch. expo-secure-storefor credentials, namespaced by server id (uptime-pocket.cred.<serverId>). zod-validated on read. Empty/malformed values are rejected on write.
Security model
Server.auth(full strategy) is gone — server records only carryauthKind: 'bearer' | 'password'.- Secrets never enter the in-memory store. To connect to a Kuma instance, the connection manager calls
loadCredentials(serverId)which reads from SecureStore. - Type-level enforcement: the
Servershape has no field that can hold a secret.
Connection management
KumaConnectionManagerclass owns the socket + REST lifecycle:connect / disconnect / pause / resume / recheck / fetchHeartbeats.useKumaConnection()hook keeps the manager in sync withactiveServerIdand cleans up on unmount/server change.- Bridges socket events into the Zustand
monitorsandserversstores. - Live
monitorsstore with per-server maps forstatus,error,monitors, andincidents. - Version detection via
GET /api/statuson connect. Outdated Kuma (< 2.0.0) is surfaced in the server detail screen.
Onboarding flow
- New
/welcomescreen — first-launch CTA with 4 feature highlights and an "Add your Kuma server" button. OnboardingGateinapp/_layout.tsxwatchesservers.lengthand routes between/welcome(empty) and/(populated). Re-activates if the last server is removed.
Add Server flow
- Rewired with zod validation (URL, name length, credentials presence).
- Refactored from 9
useStatecalls to a singleuseReducer. - Persists to SQLite + SecureStore, probes
/api/statusfor version, markshasOnboarded = trueon success.
Server detail screen (/servers/[id])
- Live connection status banner (idle / connecting / connected / reconnecting / error).
- Outdated-Kuma warning when version < 2.0.0.
- Connection metadata (url, auth kind, version, timestamps).
- Notification mode section.
- Delete confirm dialog (requires typing the server name) — removes from SQLite, SecureStore, and in-memory state.
- "Open in Kuma" deep-link button.
Servers tab
- Real list of persisted servers (no more sample data).
- Live
connectionStatusprop onServerCard— pending color while connecting. - Tap → detail screen. Long-press → set as active.
Monitors tab
- Subscribes to
useMonitorsfor the active server. - Connection status banner ("Connecting…" / "Error: ").
- Filter chips (All / Up / Down) with proper filtering.
- Featured
<MonitorCard>+<MonitorRow>list. - Empty state distinguishes "filtered empty" from "waiting for monitors".
Testing
Jest infrastructure landed in this release:
jest.config.js(jest-expo preset) +jest.setup.ts(in-memory stubs forexpo-secure-storeandexpo-sqlite).- 13 unit tests, all passing:
credentials.test.ts(9 tests): bearer round-trip, password round-trip, namespacing, delete, malformed data, availability.manager.test.ts(4 tests): connect with stored creds, error when no creds, unknown id, disconnect clears state.
Quality gates
All green on the v0.3.0 commit:
npm run typecheck— 0 errorsnpm run lint— cleannpm run lint:doctor— No issues found (69 files scanned)npm test— 13/13 passingnpx expo prebuild --platform ios— succeeds
Known caveats
- Web bundling is blocked by an
expo-sqlitewasm bundler issue (pre-existing, not in our code). iOS and Android builds are unaffected. We don't ship web in this release. npm auditflags 12 pre-existing vulnerabilities (mostlydrizzle-orm,uuid, and Expo transitive deps). None are reachable from our code. We'll address in a follow-up.
v0.2.0 — Phase 1: Design System
Phase 1 — Design System Primitives
The full design system is now in place. See it live in the app: Settings → Design System (or open /design-system). Toggle light/dark in the top right.
New Components
UI Primitives (src/components/ui/):
Button— primary/secondary/ghost/destructive, 3 sizes, with hapticsChip— for filters, with selected-color override (great for status)SegmentedControl— animated sliding indicatorTag— small colored label with optional dotEmptyState/ErrorState— illustrated placeholdersicons.tsx— Lucide wrapper withmonitorTypeIcon()helper
Monitor Components (src/components/monitor/):
MonitorCard— large card with stats, heartbeat pulse, type iconMonitorRow— dense list row for many-monitor lists
Server Components (src/components/server/):
ServerCard— server display with active badge, monitor count, notification modeServerSwitcher— modal-style switcher
Chart Components (src/components/chart/):
ResponseTimeChart— SVG line chart with Reanimated 4 fade-inUptimeBar— segmented color-coded uptime indicator
New Screens
/design-system— Storybook of every component in light/dark/monitors/[monitorId]— monitor detail with chart, uptime bar, actions/servers/switch— server switcher modal
Wired Up
- Monitors tab uses
MonitorCard(featured) +MonitorRow(list) with sample data - Settings tab has Design system link + theme switcher
- i18n extended with all new strings
Icons
Added lucide-react-native@1.17.0 for cross-platform icon consistency. The monitorTypeIcon() helper maps Kuma monitor types to Lucide icons (HTTP→Globe, ping→Radio, port→Signal, DNS→Hash, database types→Database, etc.).
Quality
- TypeScript: 0 errors
- ESLint: 0 warnings
- Build: 14 routes exported successfully (was 11)
What's next
Phase 2 — Auth & Persistence (~weeks 3-4):
- Persist server credentials to
expo-secure-store(iOS Keychain / Android Keystore) - Real Kuma connection: REST + socket.io with reconnection
- Kuma version detection + outdated warning
- Edit/remove server UI
v0.1.0 — Phase 0: Foundation
Phase 0 — Foundation
The first cut of Uptime Pocket. A working Expo SDK 56 app with iOS 26 Liquid Glass, Material 3 Expressive on Android, and the design system to back it.
What's working
- ✅ Expo SDK 56 + Expo Router 56 (typed routes, file-based)
- ✅ NativeWind v4 + Tailwind CSS 3
- ✅ Reanimated 4.3 + Gesture Handler
- ✅ expo-glass-effect (iOS 26+) with BlurView fallback for older iOS
- ✅ 4-tab native navigation (Monitors / Incidents / Servers / Settings)
- ✅ Add Server form with bearer token + username/password auth
- ✅ Status pill + heartbeat pulse (Reanimated 4 sine wave)
- ✅ Liquid Glass surface with iOS 26 detection
- ✅ Design tokens (colors, typography, spacing, motion)
- ✅ i18n (English) with structure for more languages
- ✅ Domain types + status logic + formatters
- ✅ Kuma REST client + socket.io client + auth strategies
- ✅ Full docs: architecture, auth, notifications, design system
Quality
- TypeScript: 0 errors
- ESLint: 0 warnings
- Build:
npx expo exportsucceeds for web target - All 11 routes bundled
What's next
Phase 1 — Design system primitives (weeks 2-3):
- MonitorCard, MonitorRow
- ResponseTimeChart (SVG + Reanimated path animation)
- UptimeBar
- ServerCard, ServerSwitcher
- All in dark + light + iOS 26 / iOS 17 / Android
- Storybook page in the app
See docs/architecture.md and the build plan in PR/issue discussions.