Today every authenticated user is treated as an Employee. A post_save signal on User auto-creates an Employee record (financial/signals.py), and time entry uses Employee.objects.get_or_create(user=request.user) (financial/views.py). That means clients or other non-billable users show up in employee lists, timekeeping, and reports.
We need an explicit Employee vs Client distinction, configurable on the user profile, and employee-only filtering wherever time is entered or reported.
Current behavior
Employee model (financial/models.py) has a one-to-one link to User (manager, addresses, salary, etc.).
create_employee_for_user signal creates an Employee for every new User.
TimeCard / TimeCardCell are tied to Employee.
Time logs page already supports filtering by employee in query params, but the employee dropdown includes all users with an Employee row.
User profile menu (public/templates/base.html) only offers Change Password and Log Out — no role/type setting.
Proposed approach
1. User type on profile
Add a user-type field (e.g. Employee | Client) that admins can set on a user's profile. Options:
Option A: Field on Employee model (e.g. user_type / role) — only users marked Employee get full employee fields; Clients may still have a lightweight profile record or none.
Option B: Separate Client model or profile extension with shared base — clearer separation if clients need different data.
Recommend starting with a simple enum on the user profile (or on a shared UserProfile model) rather than auto-creating Employee for everyone.
2. Stop auto-creating Employee for all users
Remove or change create_employee_for_user in financial/signals.py so new users are not automatically Employees.
Migration/data backfill: existing users with time entries should remain Employees; others can be set to Client.
3. Profile UI
Extend the private-site user profile (admin user management and/or profile dropdown) so an admin can set Employee or Client.
Employee-only fields (manager, salary, addresses, phone) should only apply when type is Employee.
4. Time entry — filter by employee
timekeeping view: only users with type Employee can log time (or admins select which employee to log for).
Do not call get_or_create for non-employees.
Time log create/edit forms: employee picker should list Employees only, not Clients.
5. Reports — filter by employee
time_logs, client_reports, and financial index aggregations should default to or only include Employees.
Employee filter dropdowns and contract/charge-number rollups should exclude Client users.
Confirm planning/financial dashboards that iterate Employee.objects.all() (financial/views.py index) only count employees.
Acceptance criteria
User profile allows setting type: Employee or Client (admin-only is fine for v1).
New users are not auto-created as Employees unless explicitly set.
Clients cannot enter time (or do not appear in time entry UI).
Time log list/filter employee dropdown shows Employees only.
Reports and hour aggregations exclude Clients unless explicitly filtered otherwise.
Data migration preserves existing time data for current employees.
Tests cover: signal behavior, profile update, time entry restriction, report filtering.
Files likely touched
financial/models.py — type field / model changes
financial/signals.py — remove or gate auto-create
financial/forms.py — profile / employee forms
financial/views.py — timekeeping, time_logs, reports, index
financial/admin.py — admin user type
public/templates/base.html or new profile template — UI for type
New migration(s)
Open questions
Should Client users have login access to the private site (read-only) or no access at all?
Can one user ever be both, or is it strictly mutually exclusive?
Who can change the type — superuser only, or any admin?
Should existing auto-created Employee rows for non-billable users be bulk-migrated to Client?
## Summary
Today every authenticated user is treated as an **Employee**. A `post_save` signal on `User` auto-creates an `Employee` record (`financial/signals.py`), and time entry uses `Employee.objects.get_or_create(user=request.user)` (`financial/views.py`). That means clients or other non-billable users show up in employee lists, timekeeping, and reports.
We need an explicit **Employee vs Client** distinction, configurable on the user profile, and employee-only filtering wherever time is entered or reported.
## Current behavior
- `Employee` model (`financial/models.py`) has a one-to-one link to `User` (manager, addresses, salary, etc.).
- `create_employee_for_user` signal creates an `Employee` for every new `User`.
- `TimeCard` / `TimeCardCell` are tied to `Employee`.
- Time logs page already supports filtering by employee in query params, but the employee dropdown includes all users with an `Employee` row.
- User profile menu (`public/templates/base.html`) only offers Change Password and Log Out — no role/type setting.
## Proposed approach
### 1. User type on profile
Add a user-type field (e.g. `Employee` | `Client`) that admins can set on a user's profile. Options:
- **Option A:** Field on `Employee` model (e.g. `user_type` / `role`) — only users marked Employee get full employee fields; Clients may still have a lightweight profile record or none.
- **Option B:** Separate `Client` model or profile extension with shared base — clearer separation if clients need different data.
Recommend starting with a simple enum on the user profile (or on a shared `UserProfile` model) rather than auto-creating `Employee` for everyone.
### 2. Stop auto-creating Employee for all users
- Remove or change `create_employee_for_user` in `financial/signals.py` so new users are **not** automatically Employees.
- Migration/data backfill: existing users with time entries should remain Employees; others can be set to Client.
### 3. Profile UI
- Extend the private-site user profile (admin user management and/or profile dropdown) so an admin can set **Employee** or **Client**.
- Employee-only fields (manager, salary, addresses, phone) should only apply when type is Employee.
### 4. Time entry — filter by employee
- `timekeeping` view: only users with type **Employee** can log time (or admins select which employee to log for).
- Do not call `get_or_create` for non-employees.
- Time log create/edit forms: employee picker should list **Employees only**, not Clients.
### 5. Reports — filter by employee
- `time_logs`, `client_reports`, and financial index aggregations should default to or only include **Employees**.
- Employee filter dropdowns and contract/charge-number rollups should exclude Client users.
- Confirm planning/financial dashboards that iterate `Employee.objects.all()` (`financial/views.py` index) only count employees.
## Acceptance criteria
- [ ] User profile allows setting type: **Employee** or **Client** (admin-only is fine for v1).
- [ ] New users are **not** auto-created as Employees unless explicitly set.
- [ ] Clients cannot enter time (or do not appear in time entry UI).
- [ ] Time log list/filter employee dropdown shows **Employees only**.
- [ ] Reports and hour aggregations exclude Clients unless explicitly filtered otherwise.
- [ ] Data migration preserves existing time data for current employees.
- [ ] Tests cover: signal behavior, profile update, time entry restriction, report filtering.
## Files likely touched
- `financial/models.py` — type field / model changes
- `financial/signals.py` — remove or gate auto-create
- `financial/forms.py` — profile / employee forms
- `financial/views.py` — timekeeping, time_logs, reports, index
- `financial/admin.py` — admin user type
- `public/templates/base.html` or new profile template — UI for type
- New migration(s)
## Open questions
1. Should **Client** users have login access to the private site (read-only) or no access at all?
2. Can one user ever be both, or is it strictly mutually exclusive?
3. Who can change the type — superuser only, or any admin?
4. Should existing auto-created Employee rows for non-billable users be bulk-migrated to Client?
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Today every authenticated user is treated as an Employee. A
post_savesignal onUserauto-creates anEmployeerecord (financial/signals.py), and time entry usesEmployee.objects.get_or_create(user=request.user)(financial/views.py). That means clients or other non-billable users show up in employee lists, timekeeping, and reports.We need an explicit Employee vs Client distinction, configurable on the user profile, and employee-only filtering wherever time is entered or reported.
Current behavior
Employeemodel (financial/models.py) has a one-to-one link toUser(manager, addresses, salary, etc.).create_employee_for_usersignal creates anEmployeefor every newUser.TimeCard/TimeCardCellare tied toEmployee.Employeerow.public/templates/base.html) only offers Change Password and Log Out — no role/type setting.Proposed approach
1. User type on profile
Add a user-type field (e.g.
Employee|Client) that admins can set on a user's profile. Options:Employeemodel (e.g.user_type/role) — only users marked Employee get full employee fields; Clients may still have a lightweight profile record or none.Clientmodel or profile extension with shared base — clearer separation if clients need different data.Recommend starting with a simple enum on the user profile (or on a shared
UserProfilemodel) rather than auto-creatingEmployeefor everyone.2. Stop auto-creating Employee for all users
create_employee_for_userinfinancial/signals.pyso new users are not automatically Employees.3. Profile UI
4. Time entry — filter by employee
timekeepingview: only users with type Employee can log time (or admins select which employee to log for).get_or_createfor non-employees.5. Reports — filter by employee
time_logs,client_reports, and financial index aggregations should default to or only include Employees.Employee.objects.all()(financial/views.pyindex) only count employees.Acceptance criteria
Files likely touched
financial/models.py— type field / model changesfinancial/signals.py— remove or gate auto-createfinancial/forms.py— profile / employee formsfinancial/views.py— timekeeping, time_logs, reports, indexfinancial/admin.py— admin user typepublic/templates/base.htmlor new profile template — UI for typeOpen questions
Implementation complete on branch
feature/14-employee-client-user-type.Resolved open questions:
PR incoming once branch is pushed.