feat(tempo): per-user Tempo API token — same pattern as Jira token
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Each user can now store their own personal Tempo API token in their profile settings. Time is logged using each user's own credentials. Backend: - Migration b044: adds tempo_api_token column to users table - User model: adds tempo_api_token column - UserPreferencesUpdate: adds tempo_api_token field (write-only) - UserOut: adds tempo_api_token (excluded) + tempo_token_set bool; @model_validator derives both jira_token_set and tempo_token_set - users router: handles tempo_api_token same as jira_api_token (empty string clears it, never returned in responses) - tempo_service: refactored to per-user token; has_tempo_configured(), get_user_tempo_client(user) use user.tempo_api_token; global TEMPO_ENABLED still acts as kill-switch - system router: /system/tempo-test now uses current user's personal token (any role); removed global TEMPO_API_TOKEN dependency Frontend: - settings.ts: UserPreferencesUpdate.tempo_api_token, UserMeOut.tempo_token_set - SettingsPage ProfileSection: Tempo Integration section with password field, show/hide toggle, configured badge, and Test Tempo button — mirrors the Jira token UX exactly - JiraConfigSection: removed stale global Tempo test block Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ def update_my_preferences(
|
||||
"""
|
||||
update_data = payload.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
if field in ("jira_api_token", "jira_email"):
|
||||
if field in ("jira_api_token", "jira_email", "tempo_api_token"):
|
||||
# Empty string means "clear the value"
|
||||
setattr(current_user, field, value if value else None)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user