A comprehensive Role-Based Access Control (RBAC) voting system built with Next.js, TypeScript, NextAuth, and Prisma. Designed for organizational elections with secure authentication, real-time voting, and comprehensive audit trails.
- Node.js 18+
- npm or yarn
- Git
-
Clone and Install
git clone <repository-url> cd next-rbac npm install
-
Environment Setup Create
.env.local:DATABASE_URL_SQLITE="file:./prisma/dev.db" NEXTAUTH_URL="http://localhost:3000" NEXTAUTH_SECRET="your-secret-key-here" # Optional OAuth GOOGLE_CLIENT_ID="your-google-client-id" GOOGLE_CLIENT_SECRET="your-google-client-secret"
-
Database Setup
npx prisma generate npx prisma migrate dev
-
Create SuperAdmin
node scripts/create-superadmin.mjs
Creates:
superadmin@botomoto.com/superadmin123 -
Start Development
npm run dev
- Multi-provider Authentication: NextAuth with Credentials, Google, and Facebook
- Role-Based Access Control: SuperAdmin, Admin, Voter roles
- Organization Approval Workflow: Admins must be approved by SuperAdmin
- Two-Factor Authentication (2FA): Multiple options for extra security: login with your email, email OTP, SMS OTP, or passphrase. (See voter routes:
/voter/login/2fa-email,/voter/login/2fa-text,/voter/login/2fa-passphrase,/voter/login/2fa-email) - Secure Session Management: Database-based sessions
SuperAdmin
- Full system oversight and control
- Approve/reject organization registrations
- View all organizations, elections, and tickets globally
- Access to comprehensive audit logs
- Manage support tickets from all admins
- No onboarding required - direct access to dashboard
Admin
- Register and create organization (first-time onboarding required)
- Manage multiple elections for their organization
- Register voters via form or CSV upload
- Generate unique voter codes
- Create positions, candidates, and parties
- Configure 2FA methods per election (applies to all voters in that election)
- Real-time vote monitoring and analytics
- Ballot preview and live dashboard management
- Email distribution and election toggle controls
- Submit support tickets
- Completely isolated from other admins
Voter
- Access voting via unique 6-digit codes
- Election-based two-factor authentication (2FA) options: email, SMS, or passphrase (configurable per election by admin)
- Submit votes through secure ballot forms
- Complete post-vote surveys
- View real-time results (requires authentication)
- Election Lifecycle: Draft β Active β Paused β Closed β Archived
- Real-time Voting: Live vote counts with WebSocket/SSE support
- Vote Integrity: Encrypted votes with chain hashing
- Voting Scopes: Hierarchical voting areas
- Party Voting: Optional party-based voting
- Candidate Profiles: Rich candidate information
- 2FA Configuration: Per-election 2FA method selection
- Ballot Preview: Admin can preview and customize ballot forms
- Live Dashboard: Real-time election monitoring
- Email Distribution: Automated voter code and notification sending
- Real-time Dashboards: Live vote counts and participation metrics
- PDF Reports: Generate comprehensive election results
- Email Notifications: Automated voter code distribution
- Audit Trails: Complete system activity logging
- Support System: Ticket-based support for admins
- Admin registers with email/password or OAuth
- Admin goes through onboarding process (first time only)
- Admin creates organization profile
- SuperAdmin reviews and approves organization
- Admin gains access to election management dashboard
- Admin creates elections and manages:
- Voting scopes and hierarchical areas
- Political parties and affiliations
- Voter registration and code generation
- Position definitions and requirements
- Candidate profiles and information
- 2FA method selection (applies to all voters in that election)
- Admin manages elections:
- Ballot preview and customization
- Receipt form configuration
- Survey form setup
- Email distribution to voters
- Live dashboard monitoring
- Election toggle (on/off control)
- Admin submit support tickets and system issues
- 6-digit alphanumeric codes (globally unique)
- Generated individually or via CSV upload
- Supports email/SMS distribution
- Election-based multi-factor authentication
- Live dashboard access (requires authentication)
- Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
- Backend: Next.js API Routes, Prisma ORM
- Authentication: NextAuth.js v4
- Database: SQLite (development), PostgreSQL (production)
- File Storage: Supabase Storage
- Real-time: WebSocket / Server-Sent Events
src/
βββ app/ # Next.js App Router
β βββ api/ # API routes
β βββ auth/ # Authentication pages
β βββ admin/ # Admin pages
β βββ superadmin/ # SuperAdmin pages
β βββ voter/ # Voter interface
β βββ public/ # Public pages
βββ components/ # Reusable components
βββ lib/ # Utility libraries
βββ types/ # TypeScript definitions
βββ generated/ # Generated Prisma client
/auth/login # Admin login
/auth/signup # Admin registration
/auth/forgot-password # Password reset
/auth/forgot-password/otp # Password reset OTP
/admin/onboard/ # Onboarding (first-time admin)
/admin/onboard/add-org # Create organization
/admin/onboard/processing # Approval pending
/admin/dashboard/elections # Main elections dashboard
/admin/dashboard/elections/create # Create new election
/admin/dashboard/elections/[id]/setup # Election setup wizard
βββ /scope/ # Voting scope setup
βββ /party/ # Party management
βββ /voter/ # Voter registration
βββ /position/ # Position definition
βββ /candidates/ # Candidate management
/admin/dashboard/elections/[id]/manage # Election management
βββ /ballot-preview/ # Ballot customization
βββ /email-send/ # Email distribution
βββ /live-dashboard/ # Real-time monitoring
βββ /2fa-settings/ # 2FA method selection
/admin/dashboard/tickets # Support tickets
/superadmin/dashboard # Main dashboard with sidebar navigation
βββ /org-request # Organization approval
βββ /elections # Election oversight
βββ /tickets # Support ticket management
βββ /audits # System audit logs
βββ /survey-form # Survey management
/voter/login # Voter code entry
/voter/login/2fa-email # Email 2FA
/voter/login/2fa-otp # OTP 2FA
/voter/login/2fa-text # SMS 2FA
/voter/login/2fa-passphrase # Passphrase 2FA
/voter/election-status # Election status
/voter/election-terms-conditions # Terms and conditions
/voter/ballot-form # Voting interface
/voter/receipt # Vote receipt
/voter/survey-form # Post-vote survey
/voter/live-dashboard # Live results (requires auth)
/ # Landing page
/public/about-us # About page
/public/contact # Contact page
This project follows industry best practices for organizing TypeScript interfaces and type definitions. All types are centralized in the src/types/ directory with clear separation of concerns.
src/types/
βββ index.ts # Main type exports (barrel export)
βββ auth.ts # Authentication & user-related types
βββ api.ts # API request/response types
βββ components.ts # Component prop types
βββ next-auth.d.ts # NextAuth extensions
Note: Database model types are not hand-written. Instead, use the types generated by Prisma Client, e.g.:
import { User, Organization, Election } from '@/generated/prisma';
// Core user and authentication interfaces
interface User {
id: string;
email: string;
name: string;
role: UserRole;
isApproved: boolean;
organization?: Organization;
}
// Form data interfaces
interface LoginFormData {
email: string;
password: string;
rememberMe?: boolean;
}
// Type unions for better type safety
type UserRole = "ADMIN" | "VOTER" | "SUPER_ADMIN";
type OrganizationStatus = "PENDING" | "APPROVED" | "REJECTED" | "SUSPENDED";// Generic API response wrapper
interface ApiResponse<T = any> {
success: boolean;
data?: T;
message?: string;
error?: string;
statusCode: number;
}
// Pagination interfaces
interface PaginatedResponse<T> {
data: T[];
pagination: {
page: number;
limit: number;
total: number;
totalPages: number;
hasNext: boolean;
hasPrev: boolean;
};
}
// Request/Response interfaces
interface CreateUserRequest {
name: string;
email: string;
password: string;
role: string;
}// Component prop interfaces
interface ButtonProps {
children: ReactNode;
type?: "button" | "submit" | "reset";
variant?: "primary" | "secondary" | "danger" | "ghost";
size?: "sm" | "md" | "lg";
disabled?: boolean;
loading?: boolean;
onClick?: () => void;
className?: string;
}
interface TableProps<T> {
data: T[];
columns: TableColumn<T>[];
loading?: boolean;
pagination?: PaginationProps;
}// NextAuth module extensions
declare module "next-auth" {
interface Session {
user: SessionUser & DefaultSession["user"];
}
}
declare module "next-auth/jwt" {
interface JWT {
role: UserRole;
id: string;
organization?: {
id: number;
name: string;
status: string;
};
}
}- PascalCase for interfaces:
User,ApiResponse - Descriptive names:
CreateUserRequest,PaginatedResponse - Suffix conventions:
Propsfor component interfacesRequest/Responsefor API interfacesDatafor database operations
- Single Responsibility: Each file handles one domain
- Reusability: Generic interfaces where possible
- Type Safety: Union types and strict typing
- Extensibility: Easy to extend and maintain
- Documentation: Clear comments explaining purpose
In Components:
import { ButtonProps, User } from "@/types";
const MyComponent = ({ user, ...props }: ButtonProps & { user: User }) => {
// Type-safe component implementation
};In API Routes:
import { CreateUserRequest, ApiResponse } from "@/types";
export async function POST(request: Request) {
const data: CreateUserRequest = await request.json();
// Type-safe API handling
}In Database Operations:
import { PrismaUser, CreateUserData } from "@/types";
const createUser = async (data: CreateUserData): Promise<PrismaUser> => {
// Type-safe database operations
};When adding new types, follow these guidelines:
- Choose the right file based on the domain
- Use descriptive names that clearly indicate purpose
- Add JSDoc comments for complex interfaces
- Export from index.ts for easy importing
- Follow existing patterns for consistency
- Maintainability: Easy to find and update types
- Reusability: Types can be shared across components
- Type Safety: Catch errors at compile time
- Documentation: Self-documenting code
- Scalability: Easy to add new types as project grows
- Team Collaboration: Clear structure for multiple developers
GET /api/auth/[...nextauth]- NextAuth authentication (login, callback, logout)POST /api/auth/signup- User registrationPOST /api/auth/verify-session- Verify current sessionPOST /api/auth/refresh- Refresh session token
GET /api/admin/onboard/status- Get onboarding statusPOST /api/admin/onboard/organization- Create organizationGET /api/admin/onboard/processing- Check approval status
GET /api/admin/elections- List all elections for admin's organizationPOST /api/admin/elections- Create new electionGET /api/admin/elections/[id]- Get specific election detailsPUT /api/admin/elections/[id]- Update electionDELETE /api/admin/elections/[id]- Delete election
-
GET /api/admin/elections/[id]/setup- Get election setup status -
POST /api/admin/elections/[id]/setup/scope- Create voting scope -
GET /api/admin/elections/[id]/setup/scope- List voting scopes -
PUT /api/admin/elections/[id]/setup/scope/[scopeId]- Update voting scope -
DELETE /api/admin/elections/[id]/setup/scope/[scopeId]- Delete voting scope -
POST /api/admin/elections/[id]/setup/party- Create party -
GET /api/admin/elections/[id]/setup/party- List parties -
PUT /api/admin/elections/[id]/setup/party/[partyId]- Update party -
DELETE /api/admin/elections/[id]/setup/party/[partyId]- Delete party -
POST /api/admin/elections/[id]/setup/voter- Register voter -
GET /api/admin/elections/[id]/setup/voter- List voters -
POST /api/admin/elections/[id]/setup/voter/bulk- Bulk register voters (CSV) -
PUT /api/admin/elections/[id]/setup/voter/[voterId]- Update voter -
DELETE /api/admin/elections/[id]/setup/voter/[voterId]- Delete voter -
POST /api/admin/elections/[id]/setup/voter/send-codes- Send voter codes via email/SMS -
POST /api/admin/elections/[id]/setup/position- Create position -
GET /api/admin/elections/[id]/setup/position- List positions -
PUT /api/admin/elections/[id]/setup/position/[positionId]- Update position -
DELETE /api/admin/elections/[id]/setup/position/[positionId]- Delete position -
POST /api/admin/elections/[id]/setup/candidates- Create candidate -
GET /api/admin/elections/[id]/setup/candidates- List candidates -
PUT /api/admin/elections/[id]/setup/candidates/[candidateId]- Update candidate -
DELETE /api/admin/elections/[id]/setup/candidates/[candidateId]- Delete candidate
-
GET /api/admin/elections/[id]/manage- Get election management data -
POST /api/admin/elections/[id]/manage/activate- Activate election -
POST /api/admin/elections/[id]/manage/pause- Pause election -
POST /api/admin/elections/[id]/manage/close- Close election -
GET /api/admin/elections/[id]/manage/ballot-preview- Get ballot preview -
PUT /api/admin/elections/[id]/manage/ballot-preview- Update ballot configuration -
GET /api/admin/elections/[id]/manage/ballot-preview/receipt- Get receipt form -
PUT /api/admin/elections/[id]/manage/ballot-preview/receipt- Update receipt form -
GET /api/admin/elections/[id]/manage/ballot-preview/survey- Get survey form -
PUT /api/admin/elections/[id]/manage/ballot-preview/survey- Update survey form -
POST /api/admin/elections/[id]/manage/email-send- Send emails to voters -
GET /api/admin/elections/[id]/manage/email-send/status- Get email sending status -
GET /api/admin/elections/[id]/manage/live-dashboard- Get live dashboard data -
GET /api/admin/elections/[id]/manage/live-dashboard/candidate/[candidateId]- Get candidate stats -
GET /api/admin/elections/[id]/manage/live-dashboard/voting-scope/[scopeId]- Get scope stats -
GET /api/admin/elections/[id]/manage/2fa-settings- Get 2FA settings -
PUT /api/admin/elections/[id]/manage/2fa-settings- Update 2FA settings
GET /api/admin/tickets- List admin's ticketsPOST /api/admin/tickets- Create support ticketGET /api/admin/tickets/[id]- Get ticket detailsPUT /api/admin/tickets/[id]- Update ticketPOST /api/admin/tickets/[id]/message- Add message to ticket
GET /api/superadmin/dashboard- Get dashboard overviewGET /api/superadmin/dashboard/stats- Get system statistics
GET /api/superadmin/organizations- List all organizationsGET /api/superadmin/organizations/[id]- Get organization detailsPUT /api/superadmin/organizations/[id]/approve- Approve organizationPUT /api/superadmin/organizations/[id]/reject- Reject organizationPUT /api/superadmin/organizations/[id]/suspend- Suspend organizationDELETE /api/superadmin/organizations/[id]- Delete organization
GET /api/superadmin/elections- List all electionsGET /api/superadmin/elections/[id]- Get election detailsPUT /api/superadmin/elections/[id]/status- Update election statusGET /api/superadmin/elections/[id]/results- Get election results
GET /api/superadmin/tickets- List all ticketsGET /api/superadmin/tickets/[id]- Get ticket detailsPUT /api/superadmin/tickets/[id]/status- Update ticket statusPOST /api/superadmin/tickets/[id]/message- Reply to ticketPUT /api/superadmin/tickets/[id]/assign- Assign ticket
GET /api/superadmin/audits- Get audit logsGET /api/superadmin/audits/[id]- Get specific audit entryGET /api/superadmin/users- List all usersPUT /api/superadmin/users/[id]/role- Update user rolePUT /api/superadmin/users/[id]/status- Update user statusGET /api/superadmin/surveys- List all surveysGET /api/superadmin/surveys/[id]- Get survey results
POST /api/voter/auth/verify-code- Verify voter codePOST /api/voter/auth/2fa/email- Email 2FA verificationPOST /api/voter/auth/2fa/otp- OTP 2FA verificationPOST /api/voter/auth/2fa/text- SMS 2FA verificationPOST /api/voter/auth/2fa/passphrase- Passphrase 2FA verificationPOST /api/voter/auth/logout- Voter logout
GET /api/voter/elections/[code]- Get election details by voter codeGET /api/voter/elections/[code]/status- Get election statusGET /api/voter/elections/[code]/terms- Get election terms and conditionsGET /api/voter/elections/[code]/ballot- Get ballot formPOST /api/voter/elections/[code]/vote- Submit voteGET /api/voter/elections/[code]/receipt- Get vote receiptPOST /api/voter/elections/[code]/survey- Submit survey responseGET /api/voter/elections/[code]/live-dashboard- Get live results (if enabled)
GET /api/public/about- Get about page dataPOST /api/public/contact- Submit contact form
POST /api/upload/voter-csv- Upload voter CSV filePOST /api/upload/candidate-image- Upload candidate imagePOST /api/upload/party-logo- Upload party logoPOST /api/upload/organization-document- Upload organization document
GET /api/utils/generate-voter-codes- Generate voter codesPOST /api/utils/send-email- Send email notificationsPOST /api/utils/send-sms- Send SMS notificationsGET /api/utils/export-results/[electionId]- Export election results as PDF
- Password hashing with bcrypt
- Database session management
- Input sanitization and validation
- SQL injection prevention via Prisma
- Encrypted vote storage
- Chain hashing for audit trails
- Role-based access control
- Election-based 2FA configuration
- Connect repository to Vercel
- Set environment variables
- Deploy automatically
DATABASE_URL="postgresql://user:password@localhost:5432/botomoto"- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
MIT License - see LICENSE file for details.
- Create an issue in the GitHub repository
- Check the documentation in
/docs - Review the API documentation
BotoMoTo - Secure, Scalable, and Modern Voting Solutions