Improve the frontend and fix TODOs

This commit is contained in:
Urtzi Alfaro
2025-10-24 13:05:04 +02:00
parent 07c33fa578
commit 61376b7a9f
100 changed files with 8284 additions and 3419 deletions

View File

@@ -131,4 +131,55 @@ class AuthServiceClient(BaseServiceClient):
user_id=user_id,
error=str(e),
default_plan="starter")
return "starter"
return "starter"
async def create_user_by_owner(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
"""
Create a new user account via the auth service (owner/admin only - pilot phase).
This method calls the auth service endpoint that allows tenant owners
to directly create users with passwords during the pilot phase.
Args:
user_data: Dictionary containing:
- email: User email (required)
- full_name: Full name (required)
- password: Password (required)
- phone: Phone number (optional)
- role: User role (optional, default: "user")
- language: Language preference (optional, default: "es")
- timezone: Timezone (optional, default: "Europe/Madrid")
Returns:
Dict with created user data including user ID
Raises:
Exception if user creation fails
"""
try:
logger.info(
"Creating user via auth service",
email=user_data.get("email"),
role=user_data.get("role", "user")
)
result = await self.post("/users/create-by-owner", user_data)
if result and result.get("id"):
logger.info(
"User created successfully via auth service",
user_id=result.get("id"),
email=result.get("email")
)
return result
else:
logger.error("User creation returned no user ID")
raise Exception("User creation failed: No user ID returned")
except Exception as e:
logger.error(
"Failed to create user via auth service",
email=user_data.get("email"),
error=str(e)
)
raise

View File

@@ -0,0 +1,130 @@
# shared/clients/notification_client.py
"""
Notification Service Client for Inter-Service Communication
Provides access to notification and email sending from other services
"""
import structlog
from typing import Dict, Any, Optional
from uuid import UUID
from shared.clients.base_service_client import BaseServiceClient
from shared.config.base import BaseServiceSettings
logger = structlog.get_logger()
class NotificationServiceClient(BaseServiceClient):
"""Client for communicating with the Notification Service"""
def __init__(self, config: BaseServiceSettings):
super().__init__("notification", config)
def get_service_base_path(self) -> str:
return "/api/v1/notifications"
# ================================================================
# NOTIFICATION ENDPOINTS
# ================================================================
async def send_notification(
self,
tenant_id: str,
notification_type: str,
message: str,
recipient_email: Optional[str] = None,
subject: Optional[str] = None,
html_content: Optional[str] = None,
priority: str = "normal",
metadata: Optional[Dict[str, Any]] = None
) -> Optional[Dict[str, Any]]:
"""
Send a notification
Args:
tenant_id: Tenant ID (UUID as string)
notification_type: Type of notification (email, sms, push, in_app)
message: Notification message
recipient_email: Recipient email address (for email notifications)
subject: Email subject (for email notifications)
html_content: HTML content for email (optional)
priority: Priority level (low, normal, high, urgent)
metadata: Additional metadata
Returns:
Dictionary with notification details
"""
try:
notification_data = {
"type": notification_type,
"message": message,
"priority": priority,
"recipient_email": recipient_email,
"subject": subject,
"html_content": html_content,
"metadata": metadata or {}
}
result = await self.post("send", data=notification_data, tenant_id=tenant_id)
if result:
logger.info("Notification sent successfully",
tenant_id=tenant_id,
notification_type=notification_type)
return result
except Exception as e:
logger.error("Error sending notification",
error=str(e),
tenant_id=tenant_id,
notification_type=notification_type)
return None
async def send_email(
self,
tenant_id: str,
to_email: str,
subject: str,
message: str,
html_content: Optional[str] = None,
priority: str = "normal"
) -> Optional[Dict[str, Any]]:
"""
Send an email notification (convenience method)
Args:
tenant_id: Tenant ID (UUID as string)
to_email: Recipient email address
subject: Email subject
message: Email message (plain text)
html_content: HTML version of email (optional)
priority: Priority level (low, normal, high, urgent)
Returns:
Dictionary with notification details
"""
return await self.send_notification(
tenant_id=tenant_id,
notification_type="email",
message=message,
recipient_email=to_email,
subject=subject,
html_content=html_content,
priority=priority
)
# ================================================================
# UTILITY METHODS
# ================================================================
async def health_check(self) -> bool:
"""Check if notification service is healthy"""
try:
result = await self.get("../health") # Health endpoint is not tenant-scoped
return result is not None
except Exception as e:
logger.error("Notification service health check failed", error=str(e))
return False
# Factory function for dependency injection
def create_notification_client(config: BaseServiceSettings) -> NotificationServiceClient:
"""Create notification service client instance"""
return NotificationServiceClient(config)