# 🦝 Raccoon Timekeeper A self-hosted time tracking application with multi-user support and role-based access control. ## Features - **Multi-user support** - Each user has their own tasks and time entries - **Role-based access** - Admin users can manage all users, regular users can only see their own data - **First-run setup** - Admin account created on first launch via web interface - **CLI management** - Reset admin password or create users from command line - **Weekly timesheets** - View and print weekly summaries - **Flexible time input** - Supports formats like `1:30`, `1.5`, `90m`, `1h 30m` - **Task management** - Each user manages their own task list ## Security Model ### User Isolation - Each user can only view and modify their own: - Tasks - Time entries - Weekly summaries - All API endpoints filter by `current_user.id` ### Admin Privileges Admin users can: - View all users - Create new users - Edit user details (email, display name, admin status) - Activate/deactivate user accounts - Reset user passwords - Delete users (and all their data) Admin users **cannot**: - Deactivate their own account - Remove their own admin status - Delete their own account ## Installation ### Using Docker (Recommended) ```bash docker-compose up -d ``` ### Manual Installation ```bash # Clone the repository git clone https://gitea.hideawaygaming.com.au/jessikitty/Raccoon-TimeKeeper.git cd Raccoon-TimeKeeper # Create virtual environment python -m venv venv source venv/bin/activate # Linux/Mac # or: venv\Scripts\activate # Windows # Install dependencies pip install -r requirements.txt # Initialize database flask init-db # Run the application flask run --host=0.0.0.0 --port=5000 ``` ## First-Run Setup 1. Navigate to `http://localhost:5000` 2. You'll be redirected to the setup page 3. Create your admin account: - Username (min 3 characters) - Email - Display name (optional) - Password (min 8 characters) 4. Log in with your new credentials ## CLI Commands ### Initialize Database ```bash flask init-db ``` ### Reset Admin Password If you're locked out, reset the admin account from the command line: ```bash flask reset-admin ``` You'll be prompted for: - New admin username - New admin email - New password This will either update the existing admin or create a new one if none exists. ### Create User from CLI ```bash flask create-user ``` Options: - `--admin` flag to make the user an administrator ### List All Users ```bash flask list-users ``` Shows all users with their status (active/inactive) and admin flag. ## Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `SECRET_KEY` | Flask secret key for sessions | Auto-generated | | `DATABASE_URL` | Database connection string | `sqlite:///timekeeper.db` | | `DEBUG` | Enable debug mode | `false` | ## API Endpoints ### Authentication - `GET /login` - Login page - `POST /login` - Process login - `GET /logout` - Logout user - `GET /setup` - First-run admin setup - `GET /change-password` - Change password page ### Pages (require login) - `GET /` - Main time logging page - `GET /settings` - Task management - `GET /admin/users` - User management (admin only) ### Tasks API (user-scoped) - `GET /api/tasks` - List user's tasks - `POST /api/tasks` - Create task - `PUT /api/tasks/` - Update task - `DELETE /api/tasks/` - Delete task ### Entries API (user-scoped) - `GET /api/entries` - List user's entries - `POST /api/entries` - Create entry - `PUT /api/entries/` - Update entry - `DELETE /api/entries/` - Delete entry - `GET /api/weekly-summary` - Get weekly summary ### Admin API (admin only) - `GET /api/admin/users` - List all users - `POST /api/admin/users` - Create user - `PUT /api/admin/users/` - Update user - `DELETE /api/admin/users/` - Delete user ## Database Schema ### Users | Column | Type | Description | |--------|------|-------------| | id | Integer | Primary key | | username | String(80) | Unique username | | email | String(120) | Unique email | | password_hash | String(256) | Hashed password | | display_name | String(100) | Display name | | is_admin | Boolean | Admin flag | | is_active | Boolean | Account active | | created_at | DateTime | Creation timestamp | | last_login | DateTime | Last login time | ### Tasks | Column | Type | Description | |--------|------|-------------| | id | Integer | Primary key | | user_id | Integer | Owner (FK to users) | | name | String(100) | Task name | | active | Boolean | Active flag | | created_at | DateTime | Creation timestamp | ### Time Entries | Column | Type | Description | |--------|------|-------------| | id | Integer | Primary key | | user_id | Integer | Owner (FK to users) | | task_id | Integer | Task (FK to tasks) | | date | Date | Entry date | | hours | Integer | Hours component | | minutes | Integer | Minutes component | | total_minutes | Integer | Total in minutes | | notes | String(500) | Optional notes | | created_at | DateTime | Creation timestamp | ## License MIT License