A privacy-focused local web application for collecting and aggregating peer feedback based on team tenets. Integrates with Workday for feedback requests and collection.
Live Demo - Explore with fictitious sample data
This tool enables teams to:
- Individuals: Provide structured feedback to colleagues using team tenets
- Managers: Aggregate feedback from Workday, add insights, and generate reports
All data stays local—no cloud sync, no external dependencies.
Example Report:
The tool integrates with Workday (or similar HR systems) for feedback collection:
- Request: Manager or employee requests feedback via Workday, including a link to this tool
- Notify: Feedback providers receive notification with tool link
- Provide: Providers clone the repo, run locally, select tenets and provide feedback
- Copy: Click "Copy for Workday" to get formatted text, paste into Workday
- Import: Manager downloads "Feedback on My Team" XLSX from Workday, imports into tool
- Report: Tool aggregates feedback for butterfly charts and reports
| Type | Source | In Butterfly Chart |
|---|---|---|
| Structured | Tool-assisted (contains [TENETS] marker) |
Yes |
| Generic | Other Workday workflows (free-text) | No (shown separately) |
The tool supports three modes for different use cases:
| Mode | Set via | Use Case | Data Persistence |
|---|---|---|---|
| Local (default) | Default | Prepare feedback for multiple team members | Persistent SQLite |
| Hosted | HOSTED_MODE=true |
Online service for Workday integration | Ephemeral (per-session) |
| Demo | /demo routes |
Explore tool with fictitious sample data | Session-isolated SQLite |
Hosted mode (includes demo):
HOSTED_MODE=true python3 app.py
# Access demo at http://localhost:5001/demo
# Access hosted feedback at http://localhost:5001/feedback?for=NameIn hosted mode, /manager and /individual routes are blocked—users must use demo mode or the /feedback workflow.
# Build and run with Docker/Podman
podman build -t team-feedback .
podman run -p 8080:8080 -e HOSTED_MODE=true team-feedback
# OpenShift deployment
oc new-app --strategy=docker --binary --name=team-feedback
oc start-build team-feedback --from-dir=. --follow
oc expose svc/team-feedback --name=demo
oc patch route demo -p '{"spec":{"tls":{"termination":"edge","insecureEdgeTerminationPolicy":"Redirect"}}}'- Select 3 tenet strengths and 2-3 areas for improvement
- Two-column compact tenet layout for faster selection
- Auto-save with 2-second debounce (no manual save needed)
- Visual progress checklist (yellow → green when complete)
- Copy for Workday button generates formatted text with tenets
- Preview of formatted output before copying
- Support for external feedback providers (not in orgchart)
- Import Workday XLSX: Drag & drop "Feedback on My Team" export
- Automatic detection of structured vs generic feedback
- Date range filtering (default: last 3 months, or custom range)
- Sortable team table (name, job title, feedback count)
- Butterfly chart visualization of aggregated peer feedback
- Separate "Additional Feedback" section for generic entries
- Highlight specific tenets for emphasis in reports
- Add manager's own feedback and comments
- Copy for Workday: Export manager feedback for pasting back to Workday
- Export PDF reports for team members
Clone and run:
git clone <repo-url>
cd team-feedback-tool
./run.sh # macOS/Linux
run.bat # WindowsThe script automatically:
- Creates a virtual environment (first run only)
- Installs dependencies
- Opens your browser to http://localhost:5001
Try the tool with fictitious data:
# Full demo setup: orgchart, peer feedback, manager feedback, sample XLSX
python3 scripts/create_sample_data.py --demo
# Or for a larger organization (50 employees, 5 managers)
python3 scripts/create_sample_data.py --large --demoSample managers include: Della Gate (dgate), Rhoda Map (rmap), Kay P. Eye (keye), Agie Enda (aenda), Mai Stone (mstone)
pip install -r requirements.txt
python3 app.pyImport your orgchart via Web UI (Recommended):
- Go to http://localhost:5001
- Drag & drop your orgchart CSV onto the upload zone (or click to browse)
Or via Command Line:
python3 scripts/import_orgchart.py REAL-orgchart-export.csv-
Request Feedback: Manager or employee requests feedback via Workday, including a direct link like:
http://localhost:5001/feedback?for=Robin%20RollbackThis pre-fills the recipient name, making it easy for providers to start immediately.
-
Providers Give Feedback:
- Clone this repo and run locally:
python3 app.py - Click the link from Workday (or go to http://localhost:5001/feedback)
- Select tenets and write feedback for the colleague
- Click "Copy for Workday" and paste the formatted text into Workday
- Clone this repo and run locally:
-
Manager Aggregates:
- Download "Feedback on My Team" XLSX from Workday
- Import XLSX at http://localhost:5001/manager
- Tool parses structured feedback (with tenets) and generic feedback separately
- Review reports, add highlights, export PDFs
pip install flask sqlalchemyOr install from requirements.txt:
pip install -r requirements.txtIf you have an orgchart, the expected CSV format is:
Name,User ID,Job Title,Location,Email,Manager UID
Paige Duty,pduty,Staff SRE,Boston MA,[email protected],dgate
Della Gate,dgate,Engineering Manager,Raleigh NC,[email protected],The application looks for tenets in this order:
tenets.json(your organization's customized tenets)samples/tenets-sample.json(fallback with tech-themed examples)
To customize tenets for your organization:
# Copy the sample file
cp samples/tenets-sample.json tenets.json
# Edit tenets.json with your organization's values
# (This file is in .gitignore, so it stays private)Tenet format:
{
"tenets": [
{
"id": "ownership",
"name": "Ownership & Accountability",
"description": "Takes responsibility for outcomes",
"active": true
}
]
}Set "active": false to temporarily disable a tenet without deleting it.
- Flask: Web framework (port 5001)
- SQLAlchemy: ORM for database operations
- SQLite: Local database (feedback.db)
- Jinja2: Template engine
- Chart.js: Butterfly chart visualizations
- Vanilla JavaScript: No frameworks, simple and maintainable
persons: Imported from orgchart
- user_id (PK), name, job_title, location, email, manager_uid (FK)
feedback: Peer feedback entries
- id (PK), from_user_id (FK), to_user_id (FK)
- strengths (JSON array of tenet IDs)
- improvements (JSON array of tenet IDs)
- strengths_text, improvements_text
workday_feedback: Feedback imported from Workday XLSX
- id (PK), about (recipient name), from_name (provider name)
- question, feedback (raw text), asked_by, request_type, date
- is_structured (1 if contains [TENETS] marker)
- strengths, improvements (JSON arrays, if structured)
- strengths_text, improvements_text (if structured)
manager_feedback: Manager's feedback
- id (PK), manager_uid (FK), team_member_uid (FK)
- selected_strengths, selected_improvements (JSON arrays)
- feedback_text
This tool is designed as a helper utility that enhances the feedback experience without becoming a repository for sensitive employee data:
- Workday remains the source of truth: All feedback ultimately lives in Workday (or your HR system)
- Copy-paste workflow: Feedback providers paste formatted text into Workday, not out of it
- Managers import from Workday: The XLSX is exported from Workday, imported here for visualization
- No data sharing between users: Each user runs their own local instance
- Ephemeral local storage: The local database can be deleted after each feedback cycle
- Local-first: All data stays on your machine—no cloud sync, no external servers
- No authentication: Designed for single-user local execution (each person runs their own copy)
- No telemetry: No external API calls, analytics, or phoning home
- Anonymous peer feedback: Manager reports show feedback without identifying who gave it
- .gitignore: Protects REAL-.csv, REAL-.xlsx, feedback.db, tenets.json from accidental commits
.
├── app.py # Flask application
├── models.py # SQLAlchemy models
├── demo_mode.py # Demo mode session isolation
├── scripts/
│ ├── import_workday.py # Workday XLSX import utility
│ ├── import_orgchart.py # Optional orgchart CSV import
│ ├── create_sample_data.py # Sample data generator
│ └── create_demo_template.py # Generate demo template database
├── demo-templates/ # Demo mode template DB (generated)
├── templates/ # Jinja2 templates
├── tests/ # Test suite
├── samples/
│ └── tenets-sample.json # Sample tenets configuration
├── docs/ # Documentation assets
└── README.md # This file
Used consistently across the application:
- 2-second debounce on all changes
- Visual "✓ Saved" indicator
- Silent error handling (logs to console)
- No manual save buttons or popups
- Two-column layout: Compact tenet selectors
- Sortable tables: Click headers to sort (↑↓)
- Context banners: Show current user/manager identity
- Progress indicators: Checklist with yellow → green states
- Inline editing: No separate forms or modals
Port conflict
- Feedback tool uses port 5001
- Change in app.py if needed:
app.run(port=5002)
No managers found (when using orgchart)
- Make sure orgchart CSV has people with direct reports
- Managers are auto-detected (people referenced in Manager UID column)
- If not using orgchart, just enter manager name manually
Auto-save not working
- Check browser console for errors
- Verify JavaScript is enabled
- Try hard refresh: Ctrl+Shift+R
Butterfly chart not rendering
- Check browser console for JavaScript errors
- Verify Chart.js CDN is accessible
- Try clearing browser cache
Database locked
- Close any other processes using feedback.db
- Restart the Flask app
This tool was developed with AI assistance (Claude Code by Anthropic) to accelerate development while maintaining code quality.
MIT License - See LICENSE file for details
- Sample employee names are tech-themed puns for demo purposes
- Butterfly chart pattern adapted from performance analytics tools
- Built with Flask, SQLAlchemy, and Chart.js
