Fix bugs issues
This commit is contained in:
@@ -54,13 +54,36 @@ async def lifespan(app: FastAPI):
|
|||||||
logger.info("Messaging setup complete")
|
logger.info("Messaging setup complete")
|
||||||
|
|
||||||
# Register custom metrics (metrics_collector already exists)
|
# Register custom metrics (metrics_collector already exists)
|
||||||
metrics_collector.register_counter("registration_total", "Total user registrations")
|
metrics_collector.register_counter(
|
||||||
metrics_collector.register_counter("login_success_total", "Successful logins")
|
"registration_total",
|
||||||
metrics_collector.register_counter("login_failure_total", "Failed logins")
|
"Total user registrations by status",
|
||||||
metrics_collector.register_counter("token_refresh_total", "Token refresh requests")
|
labels=["status"] # Add this line
|
||||||
metrics_collector.register_counter("token_verify_total", "Token verification requests")
|
)
|
||||||
metrics_collector.register_counter("logout_total", "User logout requests")
|
metrics_collector.register_counter(
|
||||||
metrics_collector.register_counter("errors_total", "Total errors")
|
"login_success_total",
|
||||||
|
"Total successful user logins"
|
||||||
|
)
|
||||||
|
metrics_collector.register_counter(
|
||||||
|
"login_failure_total",
|
||||||
|
"Total failed user logins by reason",
|
||||||
|
labels=["reason"] # Add this line, based on auth.py usage
|
||||||
|
)
|
||||||
|
metrics_collector.register_counter(
|
||||||
|
"token_refresh_total",
|
||||||
|
"Total token refreshes by status",
|
||||||
|
labels=["status"] # Add this line
|
||||||
|
)
|
||||||
|
metrics_collector.register_counter(
|
||||||
|
"token_verify_total",
|
||||||
|
"Total token verifications by status",
|
||||||
|
labels=["status"] # Add this line
|
||||||
|
)
|
||||||
|
metrics_collector.register_counter(
|
||||||
|
"logout_total",
|
||||||
|
"Total user logouts by status",
|
||||||
|
labels=["status"] # Add this line
|
||||||
|
)
|
||||||
|
metrics_collector.register_counter("errors_total", "Total errors", labels=["type"]) # Add this line
|
||||||
metrics_collector.register_histogram("registration_duration_seconds", "Registration request duration")
|
metrics_collector.register_histogram("registration_duration_seconds", "Registration request duration")
|
||||||
metrics_collector.register_histogram("login_duration_seconds", "Login request duration")
|
metrics_collector.register_histogram("login_duration_seconds", "Login request duration")
|
||||||
metrics_collector.register_histogram("token_refresh_duration_seconds", "Token refresh duration")
|
metrics_collector.register_histogram("token_refresh_duration_seconds", "Token refresh duration")
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
|
# ================================================================
|
||||||
|
# services/auth/app/models/users.py - FIXED VERSION
|
||||||
|
# ================================================================
|
||||||
"""
|
"""
|
||||||
User models for authentication service
|
User models for authentication service - FIXED
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Boolean, DateTime, Text
|
from sqlalchemy import Column, String, Boolean, DateTime, Text
|
||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from shared.database.base import Base
|
from shared.database.base import Base
|
||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
"""User model"""
|
"""User model - FIXED timezone handling"""
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
@@ -22,9 +25,10 @@ class User(Base):
|
|||||||
tenant_id = Column(UUID(as_uuid=True), nullable=True)
|
tenant_id = Column(UUID(as_uuid=True), nullable=True)
|
||||||
role = Column(String(50), default="user") # user, admin, super_admin
|
role = Column(String(50), default="user") # user, admin, super_admin
|
||||||
|
|
||||||
created_at = Column(DateTime, default=datetime.utcnow)
|
# FIXED: Use timezone-aware datetime for all datetime fields
|
||||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
|
||||||
last_login = Column(DateTime)
|
updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||||
|
last_login = Column(DateTime(timezone=True)) # FIXED: Now timezone-aware
|
||||||
|
|
||||||
# Profile fields
|
# Profile fields
|
||||||
phone = Column(String(20))
|
phone = Column(String(20))
|
||||||
@@ -53,22 +57,23 @@ class User(Base):
|
|||||||
|
|
||||||
|
|
||||||
class UserSession(Base):
|
class UserSession(Base):
|
||||||
"""User session model"""
|
"""User session model - FIXED timezone handling"""
|
||||||
__tablename__ = "user_sessions"
|
__tablename__ = "user_sessions"
|
||||||
|
|
||||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||||
refresh_token_hash = Column(String(255), nullable=False)
|
refresh_token_hash = Column(String(255), nullable=False)
|
||||||
is_active = Column(Boolean, default=True)
|
is_active = Column(Boolean, default=True)
|
||||||
expires_at = Column(DateTime, nullable=False)
|
expires_at = Column(DateTime(timezone=True), nullable=False) # FIXED: timezone-aware
|
||||||
|
|
||||||
# Session metadata
|
# Session metadata
|
||||||
ip_address = Column(String(45))
|
ip_address = Column(String(45))
|
||||||
user_agent = Column(Text)
|
user_agent = Column(Text)
|
||||||
device_info = Column(Text)
|
device_info = Column(Text)
|
||||||
|
|
||||||
created_at = Column(DateTime, default=datetime.utcnow)
|
# FIXED: Use timezone-aware datetime
|
||||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
|
||||||
|
updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<UserSession(id={self.id}, user_id={self.user_id})>"
|
return f"<UserSession(id={self.id}, user_id={self.user_id})>"
|
||||||
@@ -12,6 +12,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
from sqlalchemy import select, update
|
from sqlalchemy import select, update
|
||||||
from fastapi import HTTPException, status
|
from fastapi import HTTPException, status
|
||||||
|
|
||||||
|
from app.core.config import settings
|
||||||
from app.models.users import User, UserSession
|
from app.models.users import User, UserSession
|
||||||
from app.schemas.auth import UserRegistration, UserLogin, TokenResponse, UserResponse
|
from app.schemas.auth import UserRegistration, UserLogin, TokenResponse, UserResponse
|
||||||
from app.core.security import security_manager
|
from app.core.security import security_manager
|
||||||
@@ -63,7 +64,6 @@ class AuthService:
|
|||||||
"user.registered",
|
"user.registered",
|
||||||
UserRegisteredEvent(
|
UserRegisteredEvent(
|
||||||
service_name="auth-service",
|
service_name="auth-service",
|
||||||
timestamp=datetime.now(timezone.utc),
|
|
||||||
data={
|
data={
|
||||||
"user_id": str(user.id),
|
"user_id": str(user.id),
|
||||||
"email": user.email,
|
"email": user.email,
|
||||||
@@ -149,9 +149,7 @@ class AuthService:
|
|||||||
"user_events",
|
"user_events",
|
||||||
"user.login",
|
"user.login",
|
||||||
UserLoginEvent(
|
UserLoginEvent(
|
||||||
event_id=str(session.id),
|
|
||||||
service_name="auth-service",
|
service_name="auth-service",
|
||||||
timestamp=datetime.now(timezone.utc),
|
|
||||||
data={
|
data={
|
||||||
"user_id": str(user.id),
|
"user_id": str(user.id),
|
||||||
"email": user.email,
|
"email": user.email,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Event definitions for microservices communication
|
|||||||
- Simple class-based approach to avoid dataclass issues
|
- Simple class-based approach to avoid dataclass issues
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@@ -14,9 +14,20 @@ class BaseEvent:
|
|||||||
self.data = data
|
self.data = data
|
||||||
self.event_type = event_type
|
self.event_type = event_type
|
||||||
self.event_id = str(uuid.uuid4())
|
self.event_id = str(uuid.uuid4())
|
||||||
self.timestamp = datetime.utcnow()
|
self.timestamp = datetime.now(timezone.utc)
|
||||||
self.correlation_id = correlation_id
|
self.correlation_id = correlation_id
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]: # Add this method
|
||||||
|
"""Converts the event object to a dictionary for JSON serialization."""
|
||||||
|
return {
|
||||||
|
"service_name": self.service_name,
|
||||||
|
"data": self.data,
|
||||||
|
"event_type": self.event_type,
|
||||||
|
"event_id": self.event_id,
|
||||||
|
"timestamp": self.timestamp.isoformat(), # Convert datetime to ISO 8601 string
|
||||||
|
"correlation_id": self.correlation_id
|
||||||
|
}
|
||||||
|
|
||||||
# Training Events
|
# Training Events
|
||||||
class TrainingStartedEvent(BaseEvent):
|
class TrainingStartedEvent(BaseEvent):
|
||||||
def __init__(self, service_name: str, data: Dict[str, Any], correlation_id: Optional[str] = None):
|
def __init__(self, service_name: str, data: Dict[str, Any], correlation_id: Optional[str] = None):
|
||||||
|
|||||||
Reference in New Issue
Block a user