A gamified time-tracking app that turns your founder hours into earnings, complete with levels, badges, streaks, and a motivational boss avatar.
- Firebase Authentication: Secure login with Google OAuth or email/password
- Dual Logging System: Quick Add for fast entries or Live Timer for real-time tracking
- Gamification: Levels (every $500 earned), achievement badges, and daily streaks
- Analytics: Beautiful charts showing earnings by role and trends over time
- Role Management: Configure multiple roles with custom hourly rates and colors
- Project Tracking: Organize entries by projects
- Export: Download all your data as CSV
- Offline Support: IndexedDB queue for offline entry creation
- Keyboard Shortcuts: Press
Lto open Log Time modal quickly
- React + TypeScript
- Vite (dev server)
- TailwindCSS (styling)
- React Query (server state management)
- Zustand (local UI state)
- Chart.js (analytics visualizations)
- React Router (navigation)
- FastAPI (Python)
- SQLAlchemy ORM
- SQLite database
- Pydantic (validation)
The app runs automatically when you start the Replit. Both backend and frontend servers start together.
If you need to start the servers manually:
cd server && python main.py &
cd client && npm run devBackend runs on port 8000, frontend on port 5000 (with proxy to backend).
The app seeds with these default roles on first run:
| Role | Default Hourly Rate | Color |
|---|---|---|
| Product Manager | $50/hr | Blue |
| Go To Market | $40/hr | Green |
| Fundraiser | $75/hr | Orange |
| Designer | $30/hr | Purple |
| Admin Manager | $20/hr | Gray |
| Coder | Not set | Red |
- Navigate to Roles & Rates page
- Click Edit on any role
- Update the hourly rate
- Click Update Role
All future time entries for that role will use the new rate. Past entries remain unchanged.
┌──────────────┐
│ roles │
├──────────────┤
│ id │
│ name │
│ hourly_rate │◄──┐
│ color │ │
│ created_at │ │
│ updated_at │ │
└──────────────┘ │
│
┌──────────────┐ │
│ projects │ │
├──────────────┤ │
│ id │◄──┼──┐
│ name │ │ │
│ color │ │ │
│ created_at │ │ │
└──────────────┘ │ │
│ │
┌──────────────────┼──┼──┐
│ entries │ │ │
├──────────────────┼──┼──┤
│ id │ │ │
│ role_id ├──┘ │
│ project_id ├─────┘
│ started_at │
│ duration_minutes │
│ note │
│ tags (JSON) │
│ created_at │
└──────────────────┘
┌──────────────────┐
│ achievements │
├──────────────────┤
│ id │
│ code │
│ title │
│ description │
│ earned_at │
└──────────────────┘
┌──────────────────┐
│ settings │
├──────────────────┤
│ id │
│ key │
│ value │
└──────────────────┘
- First Blood: Log your first time entry
- Power Hour: Complete a 60-minute session in one entry
- Tri-Role: Work in 3 different roles in a single day
- Weekly Warrior: Hit your weekly goal
- Fundraising Beast: Log 5+ hours as Fundraiser in a week
A streak day requires at least 30 minutes of logged time. The dashboard shows your current streak and longest streak.
You gain 1 level for every $500 earned. The dashboard shows a progress bar indicating how close you are to the next level.
Your boss reacts based on your activity:
- No entries by 2pm: "Let's ship something today"
- Hit daily goal: "Nice. Clocked in like a pro"
- Work across 3+ roles: "Versatile. Keep it up"
Configure your experience:
- Daily Goal: Target minutes per day (default: 240 = 4 hours)
- Weekly Goal: Target minutes per week (default: 1200 = 20 hours)
- Currency: Display currency code (default: USD)
- Gamification: Toggle confetti and sound effects
- Navigate to Settings
- Click Export CSV
- Your browser downloads a CSV with all entries
Filters from the History page apply to exports.
L- Open Log Time modal (when not typing in an input)S- Start/Stop timer (when in Timer mode)E- Export data (when on History page)
To reset and re-seed the database:
rm server/founder_mode.db
# Restart the server
cd server && python main.pyThe database will be recreated with default roles and sample entries.
Run backend tests:
cd server
pytestTests cover:
- Entry earnings calculations with various scenarios
- Level progression logic
- Achievement detection
The app is pre-configured to run on Replit:
- The workflow automatically starts both servers
- Frontend runs on port 5000 (dev server)
- Backend API runs on port 8000
- Vite proxies
/apirequests to the backend
The app is configured for autoscale deployment:
- Build: Frontend is built with
npm run build - Run: FastAPI serves both the static frontend and API on port 5000
- Click "Deploy" in Replit to publish your app
- After deployment, add your production domain to Firebase Authorized domains
Important: Before deploying, make sure you have:
- Set up Firebase credentials (VITE_FIREBASE_PROJECT_ID, VITE_FIREBASE_APP_ID, VITE_FIREBASE_API_KEY)
- Added your Replit domain to Firebase Console > Authentication > Settings > Authorized domains
/
├── server/ # FastAPI backend
│ ├── main.py # API routes and app setup
│ ├── models.py # SQLAlchemy models
│ ├── schemas.py # Pydantic schemas
│ ├── database.py # Database configuration
│ ├── seeder.py # Data seeding logic
│ ├── gamification.py # Achievement & level logic
│ ├── test_main.py # Unit tests
│ └── requirements.txt # Python dependencies
│
├── client/ # React frontend
│ ├── src/
│ │ ├── api/ # API client
│ │ ├── components/ # Reusable components
│ │ ├── pages/ # Page components
│ │ ├── store/ # Zustand stores
│ │ ├── types/ # TypeScript types
│ │ ├── utils/ # Utilities (offline queue)
│ │ ├── App.tsx # Main app component
│ │ └── main.tsx # Entry point
│ ├── vite.config.ts # Vite configuration
│ └── package.json # Node dependencies
│
├── start.sh # Startup script
└── README.md # This file
GET /api/roles- List all rolesPOST /api/roles- Create rolePATCH /api/roles/:id- Update roleDELETE /api/roles/:id- Delete role
GET /api/projects- List all projectsPOST /api/projects- Create project
GET /api/entries?from=ISO&to=ISO&roleId=&projectId=&q=- List entries with filtersPOST /api/entries- Create entryPATCH /api/entries/:id- Update entryDELETE /api/entries/:id- Delete entry
GET /api/summary?range=day|week|month|quarter|year- Get summary statsGET /api/stats- Get levels, streaks, boss messageGET /api/achievements- List all achievements
GET /api/settings- List all settingsPOST /api/settings- Upsert setting
GET /api/export.csv?filters- Export entries as CSV
DELETE /api/reset- Reset all entries and achievements (preserves roles and settings)
If you want to start fresh, you can reset all your data from the Settings page:
- Navigate to Settings
- Scroll down to the Danger Zone section
- Click Reset All Data
- Confirm the action
This will:
- ✓ Delete all time entries
- ✓ Clear all achievements and streaks
- ✓ Reset your total earnings to $0
- ✓ Reset your level to 1
- ✓ Preserve your role rates and settings
- ✓ Clear any offline queued entries
MIT