Thanks to visit codestin.com
Credit goes to github.com

Skip to content

alexmchardy/soap

Repository files navigation

SOAP Notes - Offline-First Medical Documentation

A production-ready React TypeScript application for creating and managing SOAP (Subjective, Objective, Assessment, Plan) medical notes with offline-first capabilities and automatic synchronization.

Features

  • Offline-First Architecture: Fully functional without internet connectivity
  • Real-time Validation: Form validation with helpful error messages
  • IndexedDB Storage: Robust offline data persistence
  • Automatic Sync: Background synchronization when connection is restored
  • Retry Logic: Exponential backoff for failed sync attempts
  • Material-UI: Clean, accessible, and responsive design
  • TypeScript: Full type safety throughout the application

Tech Stack

  • Frontend: Next.js 15 + React 19 + TypeScript
  • UI Library: Material-UI (MUI) v7
  • Validation: Zod schema validation
  • Storage: IndexedDB for offline persistence
  • API: json-server for mock backend
  • Build Tool: Turbopack for fast development

Quick Start

Prerequisites

  • Node.js 18+ and yarn
  • Modern browser with IndexedDB support

Installation

# Clone the repository
git clone <repository-url>
cd soap

# Install dependencies
yarn install

# Start development servers (app + mock API)
yarn dev:all

The application will be available at:

Alternative Commands

# Start only the Next.js app
yarn dev

# Start only the mock API server
yarn api

# Build for production
yarn build

# Start production server
yarn start

Architecture Overview

Project Structure

src/
├── components/          # React components
│   ├── forms/          # Form components
│   └── ui/             # UI components (status, queue)
├── hooks/              # Custom React hooks
├── lib/                # Core utilities and services
│   ├── api.ts          # API client with error handling
│   ├── storage.ts      # IndexedDB wrapper
│   ├── sync.ts         # Sync orchestrator
│   ├── utils.ts        # Utility functions
│   ├── validation.ts   # Zod schemas
│   └── theme.ts        # Material-UI theme
├── stores/             # State management
│   └── AppContext.tsx  # React Context for global state
└── types/              # TypeScript type definitions
    └── soap.ts         # SOAP note interfaces

Key Components

Data Flow:

  1. User creates SOAP note → Saved to IndexedDB with 'pending' status
  2. Sync orchestrator detects pending notes → Attempts API sync
  3. Success: Note marked as 'synced' | Failure: Note marked as 'error' with retry logic

Offline Strategy:

  • All notes stored locally in IndexedDB
  • App fully functional offline
  • Automatic sync when connection restored
  • Failed syncs queued with exponential backoff retry

Error Handling:

  • Graceful degradation for network failures
  • User-friendly error messages
  • Retry mechanisms with visual feedback
  • Partial sync failure handling

Form Validation

The SOAP note form includes comprehensive validation:

  • Patient Name: Required, non-empty string
  • Patient ID: Required, positive integer
  • Date: Required, valid ISO date format
  • Weight: Required, positive number with unit selection (kg/lb)
  • Heart Rate: Required, integer between 20-300 bpm
  • History/Assessment/Plan: Required, non-empty text fields

Offline Behavior

Storage Strategy

  • Primary Storage: IndexedDB for structured data and reliability
  • Data Structure: Notes stored with sync status and metadata
  • Persistence: Data survives browser restarts and updates

Sync Process

  1. Connection Detection: Uses navigator.onLine + API health checks
  2. Queue Management: Failed syncs remain in queue with error details
  3. Retry Logic: Exponential backoff (1s, 2s, 4s, 8s, 16s, 30s max)
  4. Partial Failures: Individual note failures don't block other syncs

User Experience

  • Status Indicators: Clear sync status (Offline, Pending, Synced, Error)
  • Queue Visibility: Expandable sync queue with retry actions
  • Manual Sync: "Sync Now" button for user-initiated sync
  • Error Recovery: Individual retry buttons for failed items

API Contract

The application expects a REST API with these endpoints:

POST /notes     - Create new note (returns note with server-assigned ID)
GET /notes      - List all notes
PUT /notes/:id  - Update existing note
DELETE /notes/:id - Delete note

Sample API Response

{
  "id": "2a46",
  "patientName": "John Doe",
  "patientId": 12345,
  "date": "2024-01-15",
  "history": "Patient reports headache...",
  "weightValue": 70.5,
  "weightUnit": "kg",
  "heartRate": 72,
  "assessment": "Mild tension headache...",
  "plan": "Rest and hydration...",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "syncedAt": "2024-01-15T10:30:05.000Z"
}

Testing the Application

Offline Testing

  1. Open browser developer tools
  2. Go to Network tab → Check "Offline"
  3. Create SOAP notes (should work normally)
  4. Check sync queue shows pending items
  5. Uncheck "Offline" → Notes should sync automatically

Error Testing

  1. Stop the json-server (Ctrl+C)
  2. Try to sync notes → Should show error status
  3. Restart json-server → Retry should work

Development Notes

Type Safety

  • Full TypeScript coverage with strict mode
  • Runtime validation with Zod schemas
  • Type-safe API client with error handling

Performance Considerations

  • IndexedDB for efficient offline storage
  • Debounced validation to reduce re-renders
  • Lazy imports for utility functions
  • Background sync to avoid blocking UI

Accessibility

  • Semantic HTML structure
  • Proper form labels and ARIA attributes
  • Keyboard navigation support
  • Screen reader friendly error messages

What's Next

With more time, I would implement:

Stretch Features

  • Service Worker: Background sync for true offline-first experience
  • Batch Sync: Sync multiple notes in single API call
  • Conflict Resolution: Handle concurrent edits from multiple devices
  • Diagnostics Panel: Sync statistics and debugging information
  • Data Export: Export notes to various formats (PDF, CSV)
  • Search & Filter: Find notes by patient, date, or content

Production Enhancements

  • Authentication: User login and access control
  • Real Database: Replace json-server with production backend
  • Error Monitoring: Sentry or similar error tracking
  • Analytics: Usage tracking and performance monitoring
  • Caching Strategy: Implement proper HTTP caching
  • Progressive Enhancement: Enhanced features for modern browsers

Troubleshooting

Common Issues

Build Errors: Ensure all dependencies are installed with yarn install

Sync Not Working: Check that json-server is running on port 4000

IndexedDB Issues: Try clearing browser data or test in incognito mode

Form Validation: Check browser console for detailed validation errors

Browser Support

  • Modern browsers with ES2017+ support
  • IndexedDB support required for offline functionality
  • Tested on Chrome 90+, Firefox 88+, Safari 14+

TODO: If there were more time

  • Testing, testing, testing!
  • Get eslint working
  • Fine tune server sync
  • Better testing of error states
  • Integrate react-query for more terse and declarative server sync and state mgmt code
  • Make the UI less ugly (tighter spacing, colors, fonts)

About

SOAP Notes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •