Academic Project · Full-Stack Development
Election Management System
A full-stack election management prototype built with Python, Flask, and MySQL. The application models separate voter, manager, and administrator workflows, including account registration, user verification, precinct-based ballots, election configuration, ballot activation, voting, result verification, and controlled public result release.

Project overview
Modeling an Election from Registration to Results
The election management system explores the many connected workflows required to organize an election. Rather than focusing only on casting a vote, the application includes voter registration, account approval, precinct configuration, election and race management, ballot generation, manager assignments, voting, result calculation, and public result release.
The application uses separate voter, manager, and administrator roles. Each role receives different routes and interface options based on its responsibilities. Flask blueprints separate authentication, primary voter features, and administrative operations, while controller modules organize database logic for users, elections, races, candidates, precincts, ballots, managers, notifications, and email.
This project strengthened my understanding of full-stack development, relational data modeling, role-based workflows, session-based flows, database-backed business rules, and automated testing.
Collaboration
Contributions and Technical Scope
This project required integrating authentication, election configuration, relational database design, voting logic, administrative workflows, interface development, and testing into one connected system.
- Python and Flask development
- MySQL schema design
- Server-rendered Jinja templates
- Role-based routes and dashboards
- Election and precinct management
- Ballot and voting workflows
- Form validation
- Testing and debugging
- Technical integration
User roles
Different Responsibilities, Different Workflows
Voter
- Create a voter account
- Wait for account verification
- Log in after approval
- Review and update profile information
- Submit sensitive profile changes for review
- View notifications
- Access an eligible active ballot
- Move through races one at a time
- View candidate profiles
- Review selections before submission
- Submit one ballot per election
- View public results after release
Manager
- Work with an assigned precinct
- Review ballots for that precinct
- Activate and deactivate eligible ballots
- Count ballot results
- Review or declare precinct-level results
- Participate in result-verification workflows
Administrator
- Approve or deny new users
- Review profile-change requests
- Create role invite codes
- Search users across multiple fields
- Create and manage elections
- Create and manage races and candidates
- Create and manage precincts
- Associate elections and races with precincts
- Generate and verify ballots
- Assign managers to precincts
- Review election results
- Release approved results publicly
Voting workflow
From Precinct Eligibility to Ballot Submission
- 1A voter registers and receives a generated user ID.
- 2An administrator verifies the account.
- 3The system uses the voter’s ZIP code to identify a precinct.
- 4The system finds a verified, active ballot for that precinct.
- 5The voter moves through the ballot one race at a time.
- 6Candidate information is available during selection.
- 7The voter reviews a summary.
- 8The ballot is submitted.
- 9A database constraint prevents a second submission for the same election.
- 10Results remain unavailable publicly until released.
This is the implemented prototype workflow—not a claim that the application meets the security, legal, accessibility, audit, or certification requirements of a real public election system.
Database
A Relational Model for Election Operations
The initialization defines 21 tables and two result views. Primary keys, foreign keys, unique constraints, status fields, and association tables connect users, election configuration, ballot activity, and result publication.
Users and verification
- • Users
- • Admins
- • Invite codes
- • Verifications
- • Notifications
Election configuration
- • Elections
- • Races
- • Candidates
- • Precincts
- • ZIP-code ranges
Associations
- • Election–race
- • Race–candidate
- • Election–precinct
- • Race–precinct
- • Manager–precinct
Ballots and results
- • Ballots
- • Voter ballots
- • Ballot audit
- • Ballot results
- • Ballot winners
- • Race results
Database views
- • Election race results
- • Public election results
Account controls
Role-Based Access and Account Verification
- Passwords are hashed with bcrypt
- Flask-Login manages authenticated sessions
- Pending users cannot log in
- Administrative and manager routes check user roles
- Manager and administrator registration requires invite codes
- Login attempts are tracked
- Account approval is separated from signup
- Profile changes can require administrative review
- Notifications communicate approval and rejection events
Interface
Gallery





Testing
Checking Election and Permission Rules
- Election creation
- Race and precinct associations
- Precinct and ZIP-code behavior
- Candidate operations
- Application routes
The repository includes pytest coverage for these areas.
Reflection
Challenges in Modeling a High-Stakes Workflow
Coordinating Multiple Roles
Voters, managers, and administrators require different interfaces, permissions, and responsibilities while still working with the same election data.
Managing Relational Associations
Elections, races, candidates, precincts, managers, and ballots form a highly connected data model that requires careful association handling.
Protecting Workflow State
The application must prevent duplicate voting, restrict ballots by precinct and date, track ballot status, and control when results become public.
Recognizing Security Boundaries
Building the prototype demonstrated that a functional voting workflow is different from a production election system, which would require extensive cryptographic, infrastructure, privacy, accessibility, auditing, and certification work.
This project strengthened my ability to break a large real-world process into roles, data relationships, routes, validation rules, and state transitions. It also showed me why high-stakes systems require both functional correctness and a much deeper level of security review.
Technology stack
Tools Behind the Prototype
- Python
- Flask
- Flask Blueprints
- Flask-Login
- Flask-Mail
- bcrypt
- MySQL
- Jinja
- HTML/CSS
- JavaScript
- pytest
- Git and GitHub
Skills
Skills Demonstrated
- Full-stack development
- Relational database design
- Role-based access
- Authentication
- Password hashing
- Server-side sessions
- CRUD operations
- Dynamic queries
- Form validation
- Workflow design
- State management
- Automated testing
- Debugging
- Security awareness
Completed prototype