Fix tenant register 2

This commit is contained in:
Urtzi Alfaro
2025-07-20 23:43:42 +02:00
parent 38e78e7163
commit 2ee5117d48
6 changed files with 290 additions and 80 deletions

View File

@@ -103,8 +103,14 @@ async def login(
metrics = get_metrics_collector(request)
try:
# Check login attempts
# Check login attempts TODO
# if not await SecurityManager.check_login_attempts(login_data.email):
# if metrics:
# metrics.increment_counter("login_failure_total", labels={"reason": "rate_limited"})
# raise HTTPException(
# status_code=status.HTTP_429_TOO_MANY_REQUESTS,
# detail="Too many login attempts. Please try again later."
# )
# Attempt login
result = await AuthService.login(login_data.email, login_data.password, db)

View File

@@ -1,6 +1,6 @@
# services/tenant/app/main.py
"""
Tenant Service FastAPI application
Tenant Service FastAPI application - FIXED VERSION
"""
import structlog
@@ -47,11 +47,35 @@ async def startup_event():
"""Initialize service on startup"""
logger.info("Starting Tenant Service...")
try:
# ✅ FIX: Import models to ensure they're registered with SQLAlchemy
from app.models.tenants import Tenant, TenantMember, Subscription
logger.info("Tenant models imported successfully")
# ✅ FIX: Create database tables on startup
await database_manager.create_tables()
logger.info("Tenant database tables created successfully")
except Exception as e:
logger.error(f"Failed to initialize tenant service: {e}")
raise
logger.info("Tenant Service startup completed successfully")
@app.on_event("shutdown")
async def shutdown_event():
"""Cleanup on shutdown"""
logger.info("Shutting down Tenant Service...")
await database_manager.engine.dispose()
try:
# Close database connections properly
if hasattr(database_manager, 'engine') and database_manager.engine:
await database_manager.engine.dispose()
logger.info("Database connections closed")
except Exception as e:
logger.error(f"Error during shutdown: {e}")
logger.info("Tenant Service shutdown completed")
@app.get("/health")
async def health_check():

View File

@@ -1,11 +1,12 @@
# services/tenant/app/schemas/tenants.py
"""
Tenant schemas
Tenant schemas - FIXED VERSION
"""
from pydantic import BaseModel, Field, validator
from typing import Optional, List, Dict, Any
from datetime import datetime
from uuid import UUID
import re
class BakeryRegistration(BaseModel):
@@ -42,8 +43,8 @@ class BakeryRegistration(BaseModel):
return v
class TenantResponse(BaseModel):
"""Tenant response schema"""
id: str
"""Tenant response schema - FIXED VERSION"""
id: str # ✅ Keep as str for Pydantic validation
name: str
subdomain: Optional[str]
business_type: str
@@ -55,9 +56,17 @@ class TenantResponse(BaseModel):
subscription_tier: str
model_trained: bool
last_training_date: Optional[datetime]
owner_id: str
owner_id: str # ✅ Keep as str for Pydantic validation
created_at: datetime
# ✅ FIX: Add custom validator to convert UUID to string
@validator('id', 'owner_id', pre=True)
def convert_uuid_to_string(cls, v):
"""Convert UUID objects to strings for JSON serialization"""
if isinstance(v, UUID):
return str(v)
return v
class Config:
from_attributes = True
@@ -68,16 +77,70 @@ class TenantAccessResponse(BaseModel):
permissions: List[str]
class TenantMemberResponse(BaseModel):
"""Tenant member response"""
"""Tenant member response - FIXED VERSION"""
id: str
user_id: str
role: str
is_active: bool
joined_at: Optional[datetime]
# ✅ FIX: Add custom validator to convert UUID to string
@validator('id', 'user_id', pre=True)
def convert_uuid_to_string(cls, v):
"""Convert UUID objects to strings for JSON serialization"""
if isinstance(v, UUID):
return str(v)
return v
class Config:
from_attributes = True
class TenantUpdate(BaseModel):
"""Tenant update schema"""
name: Optional[str] = Field(None, min_length=2, max_length=200)
address: Optional[str] = Field(None, min_length=10, max_length=500)
phone: Optional[str] = None
business_type: Optional[str] = None
business_type: Optional[str] = None
class TenantListResponse(BaseModel):
"""Response schema for listing tenants"""
tenants: List[TenantResponse]
total: int
page: int
per_page: int
has_next: bool
has_prev: bool
class TenantMemberInvitation(BaseModel):
"""Schema for inviting a member to a tenant"""
email: str = Field(..., pattern=r'^[^@]+@[^@]+\.[^@]+$')
role: str = Field(..., pattern=r'^(admin|member|viewer)$')
message: Optional[str] = Field(None, max_length=500)
class TenantMemberUpdate(BaseModel):
"""Schema for updating tenant member"""
role: Optional[str] = Field(None, pattern=r'^(owner|admin|member|viewer)$')
is_active: Optional[bool] = None
class TenantSubscriptionUpdate(BaseModel):
"""Schema for updating tenant subscription"""
plan: str = Field(..., pattern=r'^(basic|professional|enterprise)$')
billing_cycle: str = Field(default="monthly", pattern=r'^(monthly|yearly)$')
class TenantStatsResponse(BaseModel):
"""Tenant statistics response"""
tenant_id: str
total_members: int
active_members: int
total_predictions: int
models_trained: int
last_training_date: Optional[datetime]
subscription_plan: str
subscription_status: str
@validator('tenant_id', pre=True)
def convert_uuid_to_string(cls, v):
"""Convert UUID objects to strings for JSON serialization"""
if isinstance(v, UUID):
return str(v)
return v

View File

@@ -5,6 +5,7 @@ Tenant service messaging for event publishing
from shared.messaging.rabbitmq import RabbitMQClient
from app.core.config import settings
import structlog
from datetime import datetime
logger = structlog.get_logger()