action-requests-demo.jamey..../README.md

216 lines
6.9 KiB
Markdown
Raw Normal View History

# Phoenix LiveView Action Requests Demo
A demonstration of how Phoenix LiveView can replace complex multi-framework stacks (Django + React, Rails + React, etc.) with a single, elegant solution for building interactive, real-time data tables.
## What This Demo Shows
This project implements a fully-featured data table with **filtering, sorting, and pagination** in a fraction of the code required by traditional stack combinations. What typically requires:
- Backend API (Django/Rails)
- Frontend framework (React/Vue)
- State management (Redux/Zustand)
- API client libraries (Axios/Fetch)
- TypeScript type definitions
- Multiple build tools and configs
...is accomplished here in **one Phoenix LiveView module** with progressive enhancement, real-time updates, and URL-based state management built in.
## Why This Matters
### Compared to Django + React (or similar stacks):
| Aspect | Django + React | Phoenix LiveView |
|--------|---------------|------------------|
| **Codebase** | Split across backend/frontend | Single unified codebase |
| **Languages** | Python + JavaScript/TypeScript | Elixir |
| **Files needed** | Views, serializers, API endpoints, React components, state management, type definitions | 1 LiveView module + 1 context |
| **State sync** | Manual API calls, polling, or WebSocket setup | Automatic via LiveView |
| **Real-time** | Requires channels/WebSockets setup | Built-in |
| **Progressive enhancement** | Requires separate server-side rendering setup | Native |
| **URL state** | Manual query param handling on both ends | Declarative with `handle_params/3` |
| **Deployment** | Two separate services | Single Elixir application |
| **Build complexity** | Webpack/Vite + Python packaging | Mix (built-in) |
### Performance Benefits
- **Reduced latency**: No API round-trips, server renders diffs only
- **Minimal bandwidth**: LiveView sends HTML diffs, not full JSON payloads
- **Efficient updates**: Only changed DOM elements are updated
- **No client-side state bugs**: Source of truth lives on the server
### Maintainability Benefits
- **Single mental model**: No context switching between languages/frameworks
- **Fewer dependencies**: No npm packages, no frontend framework updates
- **Type safety**: Elixir's pattern matching catches errors at compile time
- **Simpler testing**: Test the LiveView, not API + frontend + integration
## Features Implemented
### Core Functionality
-**Search/Filter**: Fuzzy text search on patient names
-**Status Filter**: Dropdown (All, Resolved, Unresolved)
-**Assignment Filter**: Dropdown (All, Mine, Assigned, Unassigned)
-**Sorting**: All columns with ascending/descending indicators
-**Pagination**: 25 records per page with full navigation
-**URL State**: All filters/sorting/pagination in URL (bookmarkable/shareable)
-**Progressive Enhancement**: Works with and without JavaScript
### Technical Highlights
- **Single LiveView module** handles all user interactions
- **Flop library** for efficient query building
- **SQLite database** with proper indexes
- **Real-time updates** without polling or manual WebSocket setup
- **Responsive design** with Tailwind CSS + DaisyUI
- **Theme support** with light/dark modes
## Database Schema
```elixir
# action_requests table
id :binary_id, primary_key: true
patient_name :string
status :string
assigned_user_id :integer
delivery_scheduled_at :naive_datetime
inserted_at :utc_datetime
updated_at :utc_datetime
# Indexes
- patient_name
- status
- assigned_user_id
- inserted_at
```
## Tech Stack
- **Phoenix 1.8+** - Web framework
- **LiveView** - Real-time server-rendered interactions
- **Flop** - Filtering, ordering, and pagination
- **Ecto** - Database wrapper and query builder
- **SQLite** - Embedded database (zero-config)
- **Tailwind CSS + DaisyUI** - Styling
- **Elixir** - Language
## Getting Started
### Prerequisites
- Elixir 1.15+
- Erlang/OTP 26+
### Setup
```bash
# Install dependencies and setup database
mix setup
# Start the Phoenix server
mix phx.server
# Or start inside IEx
iex -S mix phx.server
```
Visit [`localhost:4000`](http://localhost:4000) in your browser.
### Seeding Data
The database is automatically seeded with 1,000,000 sample records on first run. To reset:
```bash
mix ecto.reset
```
## Code Structure
```
lib/
├── action_requests_demo/
│ ├── action_requests/
│ │ └── action_request.ex # Schema definition
│ └── action_requests.ex # Context with query logic
└── action_requests_demo_web/
├── live/
│ └── action_requests_live.ex # Main LiveView (filtering, sorting, pagination)
└── router.ex # Single route
```
## Progressive Enhancement
This app works perfectly **without JavaScript**:
1. Forms use `method="get"` and `action="/"`
2. Filter changes trigger full page reloads via form submission
3. All state persists in URL query parameters
When JavaScript is enabled:
1. Forms trigger LiveView events instead of page reloads
2. LiveView patches the URL and re-renders
3. Updates happen in real-time with minimal data transfer
**The same code handles both modes** via `handle_params/3` - no duplicate logic required.
## Testing
```bash
# Run all tests
mix test
# Run with coverage
mix test --cover
```
31 comprehensive tests covering all filtering, sorting, and pagination scenarios.
## Key Implementation Details
### Special Filter Logic
- **"Mine"**: `assigned_user_id = current_user_id` (mocked as 1)
- **"Assigned"**: `assigned_user_id IS NOT NULL`
- **"Unassigned"**: `assigned_user_id IS NULL`
### URL Format
All state is in the URL for bookmarking/sharing:
```
/?status=resolved&assignment=mine&patient_name=john&page=2&order_by=patient_name&order_directions=asc
```
### Default Behavior
- Sort: `inserted_at DESC` (newest first)
- Per page: 25 records
- Current user: ID 1 (for demo purposes)
## Why Elixir/Phoenix?
This demo showcases Elixir's strengths:
1. **Concurrency**: BEAM VM handles thousands of concurrent connections effortlessly
2. **Fault tolerance**: Process isolation means one user's error won't crash others
3. **Low latency**: LiveView's stateful connections eliminate API overhead
4. **Developer productivity**: Write less code, ship faster, maintain easier
5. **Scalability**: Vertical and horizontal scaling built into the platform
## Production Considerations
This is a **demo application**. For production use, consider:
- Authentication/authorization (currently mocked)
- Rate limiting
- Database connection pooling configuration
- CDN for static assets
- Load balancing for multiple nodes
- Monitoring and observability
## Learn More
- **Phoenix Framework**: https://www.phoenixframework.org/
- **Phoenix LiveView**: https://hexdocs.pm/phoenix_live_view
- **Flop**: https://hexdocs.pm/flop
- **Elixir**: https://elixir-lang.org/
## License
This demonstration project is provided as-is for educational purposes.