9.2 KiB
POWR App Architecture
Last Updated: 2025-03-25
Status: Active
Purpose
This document provides an overview of the POWR app's architecture, including key design decisions, component organization, and technical patterns used throughout the application.
Architecture Overview
POWR is built as a React Native application using Expo, with a local-first architecture that prioritizes offline functionality while supporting Nostr protocol integration for social features.
Key Architectural Principles
- Local-First Design: Primary data stored locally with cloud synchronization
- Component-Based UI: Modular React components with clear responsibilities
- State Management Separation: Business logic separated from UI components
- Clean Service Layer: Service abstractions for data access and operations
- Protocol Integration: Nostr protocol integration for social features
- Mobile-Optimized Performance: Performance considerations for mobile constraints
High-Level Architecture
┌─────────────────────────────────────────────────────────────┐
│ UI Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Workout │ │ Library │ │ Social │ ... │
│ │ Components │ │ Components │ │ Components │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────┴────────────────────────────────┐
│ State Management │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Workout │ │ Library │ │ Nostr │ ... │
│ │ Store │ │ Store │ │ Store │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────┴────────────────────────────────┐
│ Service Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Workout │ │ Template │ │ Social │ ... │
│ │ Services │ │ Services │ │ Services │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────┴────────────────────────────────┐
│ Data Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SQLite │ │ Nostr NDK │ │ Cache │ ... │
│ │ Database │ │ Interface │ │ System │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Key Architectural Components
UI Layer
The UI layer consists of React components organized by feature domains and following a component composition pattern:
- Feature Screens: Top-level screens for each major feature area
- Composite Components: Reusable components combining multiple base components
- Base Components: Simple, reusable UI elements with minimal logic
- UI Primitives: Foundational styled components following design system
State Management
State management uses a combination of approaches:
- Zustand Stores: For global application state (auth, workouts, etc.)
- React Context: For feature-specific shared state
- Local Component State: For UI-specific ephemeral state
- Custom Hooks: For encapsulating state logic and side effects
Service Layer
Services provide an abstraction over data operations:
- Data Services: Handle CRUD operations for specific entity types
- Integration Services: Manage external system integration (e.g., Nostr)
- Utility Services: Provide cross-cutting functionality (logging, analytics)
- Process Services: Orchestrate complex operations across multiple services
Data Layer
The data layer handles persistent storage and external data access:
- SQLite Database: Primary storage for local data
- NDK Interface: Nostr protocol integration
- Caching System: Performance optimization for frequently used data
- Offline Queue: Management of operations during offline periods
Key Design Patterns
Repository Pattern
Data access is abstracted through repositories that provide domain-specific interfaces to the underlying storage:
// Example repository
class WorkoutRepository {
// Get all workouts
async getAll(): Promise<Workout[]> {...}
// Get workout by ID
async getById(id: string): Promise<Workout | null> {...}
// Save a workout
async save(workout: Workout): Promise<void> {...}
// Delete a workout
async delete(id: string): Promise<void> {...}
}
Service Pattern
Business logic is encapsulated in services that operate on the domain model:
// Example service
class WorkoutService {
constructor(
private workoutRepo: WorkoutRepository,
private exerciseRepo: ExerciseRepository
) {}
// Complete a workout
async completeWorkout(workout: Workout): Promise<void> {
// Business logic here
workout.completedAt = new Date();
await this.workoutRepo.save(workout);
// Additional operations
}
}
State Machine Pattern
Complex state transitions use explicit state machines to manage allowed transitions and side effects:
// Example state machine for auth
const authStateMachine = {
unauthenticated: {
login: 'authenticating',
createAccount: 'authenticating'
},
authenticating: {
success: 'authenticated',
error: 'unauthenticated'
},
authenticated: {
logout: 'deauthenticating'
},
deauthenticating: {
always: 'unauthenticated'
}
};
Adapter Pattern
External systems are integrated through adapters that normalize the interface:
// Example adapter for Nostr
class NostrAdapter implements SocialPlatformAdapter {
// Post a message
async postMessage(content: string): Promise<string> {
// Nostr-specific implementation
}
// Get messages from following
async getFollowingFeed(): Promise<Message[]> {
// Nostr-specific implementation
}
}
Folder Structure
The application code is organized by feature and technical concern:
/app - App routes and pages
/(tabs) - Main tab screens
/(workout) - Workout flow screens
/(social) - Social flow screens
/components - React components
/ui - Base UI components
/workout - Workout-specific components
/social - Social-specific components
/lib - Core application code
/db - Database services
/hooks - Custom React hooks
/stores - State management
/types - TypeScript type definitions
/utils - Utility functions
Related Documentation
- Authentication - Authentication architecture details
- State Management - State management approach
- NDK Integration - NDK implementation details
- MVP and Targeted Rebuild - Implementation strategy