A web-based tool for managers to conduct performance reviews and calculate team bonuses with algorithmic fairness.
- Performance Rating Interface: Rate team members on a 0-200% scale with justification
- Talent Calibration: Assess employee potential with What/How performance, agility ratings, and movement readiness
- Auto-save: Ratings save automatically as you work (2-second delay)
- Analytics Dashboard: View team performance distribution with calibration guidance
- Bonus Calculation: Algorithmic bonus allocation with configurable parameters
- Fixed Pool Guarantee: Total bonuses always equal your budget (sum of targets)
- Historical Tracking: Archive periods and view employee rating history over time
- Period Comparison: Compare current ratings with any historical period
- Trend Analysis: See performance trends with charts and improving/stable/declining indicators
- International Support: Handles multiple currencies (USD, GBP, EUR, CAD, INR)
- Privacy-Focused: SQLite database, runs locally, no cloud dependencies
Performance-to-bonus allocation curve showing how ratings translate to bonuses with proportional scaling
This tool is designed as a local companion to your HR system (Workday, or similar), not a replacement. The architecture maintains a clear separation:
What comes FROM Workday (import):
- Employee roster and identifiers
- Salaries and bonus targets
- Job profiles and org structure
- Currency information
What stays LOCAL (manager-entered):
- Performance ratings (0-200%)
- Justifications explaining ratings
- Team tenets evaluation
- Mentor/mentee relationships
What goes BACK to Workday (export):
- Final bonus allocations
- Rating justifications (for HR records)
Why this matters:
- No duplicate data entry: Employee info is maintained in one place (your HR system)
- Safe re-imports: Refreshing from Workday updates salaries and org changes without overwriting your ratings
- Audit trail: Your HR system remains the official record; this tool helps you get there
- Portability: Works with any HR system that can export to Excel
The workflow is: Import → Rate → Calculate → Export. Your HR system handles the before (employee data) and after (final allocations). This tool handles the middle (the actual performance evaluation work).
The easiest way to explore this tool is through the public demo:
The demo features:
- Session isolation: Each visitor gets their own sandbox database
- Pre-built sample data: Choose between small team (12 employees) or large organization (50 employees)
- Historical periods: Demo includes 2-3 historical periods for testing trend analysis
- Full functionality: All features work exactly as they would with real data
- No uploads: Demo uses fictitious sample data only (import is replaced with "Generate Demo Data")
Your demo session is completely isolated from other users and will be automatically cleaned up after 1 hour of inactivity.
git clone https://github.com/adereis/performance-rating-and-bonus.git
cd performance-rating-and-bonus
./run.shThe script automatically:
- Checks for Python 3.9+
- Creates a virtual environment
- Installs dependencies
- Starts the server and opens your browser
git clone https://github.com/adereis/performance-rating-and-bonus.git
cd performance-rating-and-bonus
run.batOnce the app is running, generate demo data to explore the features:
# In a new terminal, from the project directory:
# macOS/Linux - activate the virtual environment first
source .venv/bin/activate
# Generate sample Workday export (12 employees)
python3 scripts/create_sample_data.py
# Then in the browser:
# 1. Go to Import tab
# 2. Upload sample-data-small.xlsx
# 3. Start rating!
# Optional: Pre-populate sample ratings to see all features
python3 scripts/populate_sample_ratings.py small| Scenario | Step 1: Generate Data | Step 2: Populate Ratings |
|---|---|---|
| Small team (12 employees, 1 manager) | python3 scripts/create_sample_data.py |
python3 scripts/populate_sample_ratings.py small |
| Large org (50 employees, 5 managers) | python3 scripts/create_sample_data.py --large |
python3 scripts/populate_sample_ratings.py large |
| With history (6 quarters of data) | Add --historical flag to above |
Same as above, then import samples/sample-historical-*.xlsx as Historical Periods |
After generating, import the .xlsx file via the Import tab, then run the populate script.
Both datasets include international employees (GBP) for multi-currency testing. Sample ratings range from 45-185% with justifications included.
docker-compose up -d # Start at http://localhost:5000
docker-compose down # Stop
docker-compose up -d --build # Rebuild after changesData persists in ./data directory. See docs/DOCKER.md for production deployment, commands reference, and running without docker-compose.
Export your team data from Workday with these required columns:
Required Columns:
- Associate (employee name)
- Associate ID (unique identifier)
- Supervisory Organization
- Current Job Profile
- Current Base Pay All Countries
- Current Base Pay All Countries (XXX) - where XXX is manager's currency
- Currency
- Annual Bonus Target Percent
- Bonus Target - Local Currency
- Bonus Target - Local Currency (XXX) - where XXX is manager's currency
Note on International Teams: Workday exports include columns with your home currency code in parentheses (e.g.,
(USD)for US managers,(AUD)for Australian managers). For employees in your country, this column is empty since their local currency matches yours. For international employees, it contains the converted value in your currency. The app automatically detects and uses the correct column regardless of your location.
Optional Columns:
- Photo
- Errors
- Grade (internal use, not shown to managers)
- Last Bonus Allocation Percent
- Notes
Save the export as real-workday-export.xlsx (or any name starting with real- - these are automatically ignored by git to protect your data)
- Start the web server:
python3 app.py - Open http://localhost:5000
- Navigate to Import tab
- Upload your Workday export file
- Choose Current Period import type
- If switching from sample data, check "Clear existing data before import"
- Click Import Data
This will:
- Import all employee records from Workday
- Initialize empty performance rating fields
- Optionally clear any existing sample data
Navigate to Bonus Rating to begin entering performance ratings.
- Navigate to Bonus Rating tab
- For each employee:
- Enter performance rating (0-200%, where 100% = met expectations)
- Add justification explaining the rating
- Optionally note mentors and mentees
- Ratings auto-save after 2 seconds of inactivity
- Navigate to Analytics tab
- Review performance distribution across team
- Check calibration guidance (informational, not a requirement)
- View breakdowns by department and job profile
- Navigate to Bonus Calculation tab
- Review default parameters:
- Upside Exponent (1.35): Rewards for ratings ≥ 100%
- Downside Exponent (1.9): Penalties for ratings < 100%
- Adjust parameters if needed
- Click Recalculate to see results
- Review individual bonuses and % of target
When you've completed ratings for a period:
- Navigate to Dashboard
- Click Archive Period button
- Enter a Period ID (e.g.,
2024-H2) and Name (e.g.,Second Half 2024) - Click Archive Period
This:
- Creates a snapshot of all current ratings
- Clears all ratings to prepare for the next period
- Preserves historical data for comparison
- Click any employee name to open their detail modal
- Switch to the History tab to see:
- Performance trend chart across periods
- Trend indicator (improving/stable/declining)
- Period-by-period breakdown with justifications
- Navigate to Analytics tab
- In the Period-over-Period Comparison section:
- Select a historical period from the dropdown
- View who improved, declined, or stayed stable
- See average rating changes across the team
In addition to performance ratings, you can conduct talent calibration to assess employee potential and career readiness:
- Navigate to Calibrate tab
- For each employee:
- Assess Performance: What (results delivered) and How (behaviors demonstrated)
- Evaluate Growth Agility and Change Agility (determines Future Talent designation)
- Set Movement Readiness (ready for promotion, lateral move, or continue growing)
- Add proposed development actions
- Select Leadership Tenets (strengths and improvement areas)
- The system automatically derives:
- Overall Performance: High Impact / Successful / Evolving / Low Performer
- Future Talent: Yes/No based on agility ratings
- Cross-cycle Alignment: Flags when performance ratings don't match talent assessment
Talent data can be exported and re-imported—tenets are embedded in the "Proposed Actions" field for Workday compatibility.
Currently manual (copy from UI). Future versions will support CSV export.
| Rating | Meaning |
|---|---|
| 0-60% | Significant performance concerns |
| 60-90% | Needs improvement |
| 90-110% | Met expectations (solid performance) |
| 110-130% | Exceeded expectations |
| 130-200% | Exceptional performance |
Note: 100% is the baseline for "met all expectations". Most solid performers should be in the 90-110% range.
Analytics dashboard showing performance distribution with calibration guidance to help ensure fair ratings across the team
See BONUS_CALCULATION_README.md for detailed explanation.
Summary:
- Total Pool = Sum of all bonus targets from Workday (in your currency)
- Performance Multiplier = Split curve (different exponents for above/below 100%)
- Raw Share = Target × Perf Multiplier
- Final Bonus = Raw Share × Normalization Factor (ensures total = pool)
- Backend: Python 3, Flask
- Database: SQLite with SQLAlchemy ORM
- Frontend: HTML, CSS, JavaScript (vanilla)
- Charts: Chart.js
- Excel: openpyxl for Workday imports
Run the test suite:
python3 -m pytest tests/ -vTests cover database operations, rating validation, bonus calculations, multi-org scenarios, Workday import/export, and historical data preservation.
- Local-only: All data stays on your machine
- No cloud: SQLite database, no external dependencies
- No telemetry: No data sent to external services
- Git-safe:
.gitignoreexcludes sensitive files:ratings.db(your data)real-*.xlsx(Workday exports)
| Issue | Solution |
|---|---|
| "No such file or directory" on import | Export from Workday first, or generate sample data with python3 scripts/create_sample_data.py |
| Only some employees in bonus calculation | Ensure Workday export has both "Bonus Target - Local Currency" columns (local and converted) |
| Ratings not saving | Check browser console; ensure server is running (python3 app.py) |
| "Database locked" error | Close other processes using ratings.db; restart Flask app |
Refreshing from Workday: Import new export via Import tab → Current Period (don't check "Clear existing data"). Workday fields update but your ratings are preserved.
This is a manager tool for internal use. Contributions welcome:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
MIT License - see LICENSE file for details
For issues or questions:
- Check this README and BONUS_CALCULATION_README.md
- Review test suite for examples:
tests/test_app.py - Open an issue on GitHub