A production-ready Phoenix boilerplate with JWT authentication, RBAC authorization, WebSocket support, and multi-frontend architecture.

🚀 Quick Start

Create a new project using Rephi

  1. Install the Rephi project generator

    mix archive.install hex rephi_new
    
  2. Create your new project

    mix rephi.new my_app
    cd my_app
    
  3. Configure environment variables

    cp .env.example .env
    # Edit .env with your database credentials and configuration
    
  4. Setup and run

    mix setup
    mix phx.server
    

    Visit localhost:4000 from your browser.

Prerequisites

  • Elixir 1.14 or higher
  • Erlang 24 or higher
  • PostgreSQL 12 or higher
  • Node.js 18 or higher
  • npm or yarn

Features

  • 🔐 JWT Authentication: Secure token-based authentication system
  • 👮 RBAC Authorization: Complete Role-Based Access Control with hierarchical permissions
  • 🔌 WebSocket Support: Real-time communication via Phoenix Channels
  • ⚛️ Multi-Frontend Architecture: Support for multiple React SPAs (dashboard, admin, e-commerce, landing)
  • 📚 API Documentation: Auto-generated Swagger/OpenAPI documentation
  • 🏗️ Production Ready: Configured for scalability and best practices
  • 🛡️ CSRF Protection: Built-in CSRF token injection for SPAs

Manual Setup (for development)

  1. Clone the repository

    git clone https://github.com/thotenn/rephi.git
    cd rephi
    
  2. Install dependencies

    mix deps.get
    
  3. Configure database

    mix ecto.create
    mix ecto.migrate
    

    Or use the complete setup command:

    mix setup
    
  4. Start Phoenix server

    mix phx.server
    

    Or with interactive shell:

    iex -S mix phx.server
    

    Backend will be available at http://localhost:4000

Frontend Development

Each frontend app is a standalone React application:

cd apps/dashboard
npm install
npm run dev

Building Frontends

# Build all frontends
mix frontends.build

# Clean frontend builds
mix frontends.clean

Architecture

Backend Structure

lib/
 rephi/              # Core business logic
    accounts/       # User management
    authorization/  # RBAC system
 rephi_web/          # Web layer
    controllers/    # API controllers
    auth/          # Authentication plugs
    channels/      # WebSocket channels

Frontend Structure

apps/
 shared/            # Shared React components
 dashboard/         # Dashboard SPA
 admin/            # Admin panel SPA
 ecommerce/        # E-commerce SPA
 landing/          # Landing page SPA

API Documentation

Interactive API documentation is available via Swagger:

  • Swagger UI: http://localhost:4000/api/swagger
  • Swagger JSON: http://localhost:4000/api/swagger/swagger.json

To regenerate documentation after changes:

mix phx.swagger.generate

Useful Commands

Backend

# Run tests
mix test

# Format code
mix format

# Clean and rebuild
mix clean && mix compile

# Reset database
mix ecto.reset

# Generate Swagger documentation
mix phx.swagger.generate

Frontend

# Build for production
npm run build

# Run linter
npm run lint

# Check TypeScript types
npm run typecheck

# Start production server
npm start

Technology Stack

Backend (Phoenix/Elixir)

  • REST API under /api/*
  • JWT Authentication with Guardian
  • WebSockets with Phoenix Channels
  • Database PostgreSQL with Ecto
  • Documentation automatic with Phoenix Swagger

Frontend (React)

  • SPA Mode without SSR
  • Global State with Zustand (persisted)
  • Forms with React Hook Form + Zod
  • Styling with Tailwind CSS v4
  • API Client with Axios

Authorization System

JWT Authentication

  1. Users register/authenticate at /api/users/register or /api/users/login
  2. JWT is stored in Zustand and localStorage
  3. Axios interceptor automatically adds Authorization: Bearer {token} header
  4. Protected endpoints require valid authentication

Role-Based Access Control (RBAC)

Rephi includes a complete role-based access control (RBAC) system with the following features:

Roles and Hierarchies

  • Hierarchical roles: Roles can inherit permissions from other roles
  • Default roles:
    • admin → inherits from manager
    • manager → inherits from user
    • user → basic access

Granular Permissions

Permissions are organized by categories:

  • users: - User management (users:view, users:create, users:edit, users:delete)
  • roles: - Role management (roles:view, roles:create, roles:edit, roles:delete, roles:assign)
  • permissions: - Permission management (permissions:view, permissions:create, etc.)
  • system: - System configuration (system:settings, system:logs, system:manage)

Authorization Checks

In Controllers:

# Protect individual actions
plug AuthorizationPlug, {:permission, "users:edit"}
plug AuthorizationPlug, {:role, "admin"}
plug AuthorizationPlug, {:any_permission, ["users:create", "users:edit"]}
plug AuthorizationPlug, {:all_permissions, ["users:edit", "system:manage"]}

# Manual checks
if can?(conn, "users:edit") do
  # User can edit users
end

if has_role?(conn, "admin") do
  # User has admin role
end

In Context:

# Direct checks
Authorization.can?(user, "users:edit")
Authorization.has_role?(user, "admin")
Authorization.role_has_permission?(role, permission)

# Flexible checks
Authorization.can_by?(user: user, permission: "system:manage")
Authorization.can_by?(user: user, role: "admin")

# Get data
Authorization.get_user_roles(user)
Authorization.get_user_permissions(user)
Authorization.get_role_permissions(role)

Roles and Permissions API

Role Management:

GET    /api/roles              # List roles
POST   /api/roles              # Create role
GET    /api/roles/:id          # Get specific role
PUT    /api/roles/:id          # Update role
DELETE /api/roles/:id          # Delete role

# Role assignment to users
POST   /api/users/:user_id/roles/:role_id     # Assign role
DELETE /api/users/:user_id/roles/:role_id     # Remove role

Permission Management:

GET    /api/permissions         # List permissions
POST   /api/permissions         # Create permission
GET    /api/permissions/:id     # Get specific permission
PUT    /api/permissions/:id     # Update permission
DELETE /api/permissions/:id     # Delete permission

# Permission assignment to roles
POST   /api/roles/:role_id/permissions/:perm_id     # Assign permission
DELETE /api/roles/:role_id/permissions/:perm_id     # Remove permission

Current User Information:

GET /api/me  # Includes roles and permissions of authenticated user

Seed Data

When running mix ecto.reset or mix run priv/repo/seeds.exs, the following are automatically created:

  • 3 roles with hierarchy (admin → manager → user)
  • 17 permissions categorized by functionality
  • Administrator user (admin@admin.com / password123!!) with admin role

JWT Integration

JWT tokens automatically include:

  • User roles list ("roles": ["admin", "manager"])
  • Effective permissions list ("permissions": ["users:view", "users:create", ...])

Authorization Helpers

Available in all controllers and views:

can?(conn, "permission:slug")           # Has specific permission?
has_role?(conn, "role_slug")           # Has specific role?
can_any?(conn, ["perm1", "perm2"])     # Has any of these permissions?
can_all?(conn, ["perm1", "perm2"])     # Has all these permissions?
current_user_roles(conn)               # Current user roles
current_user_permissions(conn)         # Current user permissions
authorize(conn, permission: "users:edit") # Flexible verification

WebSockets

WebSocket connection is established at ws://localhost:4000/socket with user-specific channels.

✅ Security: WebSocket connections validate the JWT token before allowing connection. Invalid or missing tokens are automatically rejected.

Testing

# Run backend tests
mix test

# Run with coverage
mix test --cover

Deployment

Building for Production

# Backend
MIX_ENV=prod mix compile
MIX_ENV=prod mix assets.deploy

# Frontends
mix frontends.build

Docker Support

docker build -t rephi .
docker run -p 4000:4000 rephi

Publishing to Hex.pm

  1. Update the version in mix.exs
  2. Update CHANGELOG.md with release notes
  3. Ensure tests pass: mix test
  4. Create git tag: git tag -a v0.1.0 -m "Release v0.1.0"
  5. Publish: mix hex.publish

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.