feat(settings): Settings page with email, webhooks, notifications, profile [FASE-8]
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
- SystemConfig model + migration b033 for runtime key-value config - GET/PATCH /system/email-config + POST /system/email-test (admin only) - email_service reads SMTP config from DB (overrides .env) - Webhooks now accessible to red_lead/blue_lead + admin - GET /users/me already existed; /users/me/preferences already working - SettingsPage with 4 role-aware tabs: * Profile & Jira: jira_account_id, user info * Notifications: role-specific email/in-app toggles (12 prefs) * Webhooks: full CRUD + test ping (leads + admin) * Email/SMTP: enable toggle, server config, test email (admin only) - Added /settings route (all authenticated users) - Settings link added to Sidebar Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ from fastapi import APIRouter, Depends, status
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.database import get_db
|
||||
from app.dependencies.auth import require_role
|
||||
from app.dependencies.auth import require_any_role
|
||||
from app.domain.unit_of_work import UnitOfWork
|
||||
from app.models.user import User
|
||||
from app.schemas.webhook import WebhookConfigCreate, WebhookConfigOut, WebhookConfigUpdate
|
||||
@@ -52,7 +52,7 @@ def list_webhooks_route(
|
||||
offset: int = 0,
|
||||
limit: int = 50,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Return all webhook configurations. **Requires admin role.**"""
|
||||
webhooks = list_webhooks(db, offset=offset, limit=limit)
|
||||
@@ -68,7 +68,7 @@ def list_webhooks_route(
|
||||
def create_webhook_route(
|
||||
payload: WebhookConfigCreate,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Create a new webhook configuration. **Requires admin role.**"""
|
||||
with UnitOfWork(db) as uow:
|
||||
@@ -87,7 +87,7 @@ def create_webhook_route(
|
||||
def get_webhook_route(
|
||||
webhook_id: uuid.UUID,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Return a single webhook configuration. **Requires admin role.**"""
|
||||
wh = get_webhook_or_raise(db, webhook_id)
|
||||
@@ -104,7 +104,7 @@ def update_webhook_route(
|
||||
webhook_id: uuid.UUID,
|
||||
payload: WebhookConfigUpdate,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Update one or more fields of a webhook configuration. **Requires admin role.**"""
|
||||
with UnitOfWork(db) as uow:
|
||||
@@ -123,7 +123,7 @@ def update_webhook_route(
|
||||
def delete_webhook_route(
|
||||
webhook_id: uuid.UUID,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Hard-delete a webhook configuration. **Requires admin role.**"""
|
||||
with UnitOfWork(db) as uow:
|
||||
@@ -140,7 +140,7 @@ def delete_webhook_route(
|
||||
def test_webhook_route(
|
||||
webhook_id: uuid.UUID,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
current_user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
):
|
||||
"""Send a test ping to the webhook endpoint. **Requires admin role.**"""
|
||||
# Verify the webhook exists before dispatching
|
||||
|
||||
Reference in New Issue
Block a user