chore: Limpieza de proyecto y optimización
🗑️ Eliminados: - Scripts temporales de debugging (9 archivos en backend/) - Archivos temporales en raíz (4 archivos) - Reportes de cobertura htmlcov/ (~543 KB) - Directorio backups/ - Script de migración update_password_hashes.py ✨ Optimizaciones: - Creado scripts/db_utils.py - Herramienta consolidada para administración - Actualizado README.md con sección de Utilidades Administrativas - Mejorado .gitignore para prevenir archivos temporales futuros 📦 Espacio liberado: ~600-800 KB Las funcionalidades de debugging ahora están consolidadas en: - scripts/db_utils.py (herramienta CLI profesional) - Documentación en README.md - Alternativas sugeridas (psql, tests, API docs)
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
import asyncio
|
||||
from sqlalchemy import text
|
||||
from app.core.database import engine
|
||||
|
||||
async def add_columns():
|
||||
print("Starting schema update...")
|
||||
async with engine.begin() as conn:
|
||||
try:
|
||||
await conn.execute(text("ALTER TABLE tickets ADD COLUMN system_id UUID REFERENCES systems(id)"))
|
||||
print("Added system_id column")
|
||||
except Exception as e:
|
||||
print(f"Error adding system_id (might exist): {e}")
|
||||
|
||||
try:
|
||||
await conn.execute(text("ALTER TABLE tickets ADD COLUMN category_id UUID REFERENCES categories(id)"))
|
||||
print("Added category_id column")
|
||||
except Exception as e:
|
||||
print(f"Error adding category_id (might exist): {e}")
|
||||
print("Schema update finished.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(add_columns())
|
||||
@@ -1,32 +0,0 @@
|
||||
"""Script para verificar información del admin"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import select
|
||||
from app.models.user import User
|
||||
import os
|
||||
|
||||
async def check_user():
|
||||
database_url = os.getenv('DATABASE_URL', 'postgresql+asyncpg://postgres:postgres@db:5432/servicemanager')
|
||||
engine = create_async_engine(database_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
select(User).where(User.email == 'admin@example.com')
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if user:
|
||||
print(f'User found:')
|
||||
print(f' Email: {user.email}')
|
||||
print(f' Role: {user.role}')
|
||||
print(f' Tenant ID: {user.tenant_id}')
|
||||
print(f' User ID: {user.id}')
|
||||
else:
|
||||
print('User not found')
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_user())
|
||||
@@ -1,32 +0,0 @@
|
||||
"""Script para verificar información del test_user"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import select
|
||||
from app.models.user import User
|
||||
import os
|
||||
|
||||
async def check_user():
|
||||
database_url = os.getenv('DATABASE_URL', 'postgresql+asyncpg://postgres:postgres@db:5432/servicemanager')
|
||||
engine = create_async_engine(database_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
select(User).where(User.email == 'test_user@example.com')
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if user:
|
||||
print(f'User found:')
|
||||
print(f' Email: {user.email}')
|
||||
print(f' Role: {user.role}')
|
||||
print(f' Tenant ID: {user.tenant_id}')
|
||||
print(f' User ID: {user.id}')
|
||||
else:
|
||||
print('User not found')
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_user())
|
||||
@@ -1,77 +0,0 @@
|
||||
"""
|
||||
Script para verificar y actualizar password del test_user
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
from sqlalchemy import select
|
||||
from passlib.context import CryptContext
|
||||
|
||||
# Configurar el path
|
||||
backend_path = os.path.join(os.path.dirname(__file__), 'backend')
|
||||
sys.path.insert(0, backend_path)
|
||||
|
||||
from app.core.database import AsyncSessionLocal
|
||||
from app.models.user import User
|
||||
|
||||
# Configurar passlib igual que en security.py
|
||||
pwd_context = CryptContext(
|
||||
schemes=["argon2", "bcrypt"],
|
||||
deprecated="auto",
|
||||
argon2__memory_cost=65536,
|
||||
argon2__time_cost=3,
|
||||
argon2__parallelism=4,
|
||||
)
|
||||
|
||||
async def check_and_fix_test_user():
|
||||
"""Verificar y actualizar password del test_user"""
|
||||
|
||||
# Contraseñas posibles
|
||||
possible_passwords = [
|
||||
"admin123",
|
||||
"TestPassword123!",
|
||||
"password123",
|
||||
"test123",
|
||||
"hashed_password"
|
||||
]
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
# Buscar test_user
|
||||
result = await session.execute(
|
||||
select(User).where(User.email == "test_user@example.com")
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
print("❌ Usuario test_user@example.com no encontrado")
|
||||
return
|
||||
|
||||
print(f"✅ Usuario encontrado: {user.email}")
|
||||
print(f"Hash actual: {user.password_hash}")
|
||||
|
||||
# Probar contraseñas posibles
|
||||
found_password = None
|
||||
for password in possible_passwords:
|
||||
if pwd_context.verify(password, user.password_hash):
|
||||
found_password = password
|
||||
break
|
||||
|
||||
if found_password:
|
||||
print(f"🎉 Contraseña encontrada: {found_password}")
|
||||
else:
|
||||
print("❌ Ninguna contraseña coincide")
|
||||
print("Estableciendo nueva contraseña: admin123")
|
||||
|
||||
# Establecer nueva contraseña
|
||||
new_password = "admin123"
|
||||
user.password_hash = pwd_context.hash(new_password)
|
||||
await session.commit()
|
||||
print(f"✅ Contraseña actualizada a: {new_password}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
await session.rollback()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_and_fix_test_user())
|
||||
@@ -1,47 +0,0 @@
|
||||
"""Script para verificar información del ticket"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import select
|
||||
from app.models.ticket import Ticket
|
||||
from app.models.user import User
|
||||
import uuid
|
||||
import os
|
||||
|
||||
async def check_ticket():
|
||||
database_url = os.getenv('DATABASE_URL', 'postgresql+asyncpg://postgres:postgres@db:5432/servicemanager')
|
||||
engine = create_async_engine(database_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
ticket_id = '2bd79718-440d-4144-b660-c0c6051fcf73'
|
||||
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
select(Ticket).where(Ticket.id == uuid.UUID(ticket_id))
|
||||
)
|
||||
ticket = result.scalar_one_or_none()
|
||||
|
||||
if ticket:
|
||||
creator_result = await session.execute(
|
||||
select(User).where(User.id == ticket.created_by)
|
||||
)
|
||||
creator = creator_result.scalar_one_or_none()
|
||||
|
||||
print(f'Ticket found:')
|
||||
print(f' ID: {ticket.id}')
|
||||
print(f' Number: {ticket.ticket_number}')
|
||||
print(f' Subject: {ticket.subject}')
|
||||
print(f' Status: {ticket.status}')
|
||||
print(f' Tenant ID: {ticket.tenant_id}')
|
||||
print(f' Created by ID: {ticket.created_by}')
|
||||
if creator:
|
||||
print(f' Creator email: {creator.email}')
|
||||
print(f' Creator role: {creator.role}')
|
||||
print(f' Assigned to: {ticket.assigned_to}')
|
||||
else:
|
||||
print('Ticket not found')
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_ticket())
|
||||
@@ -1,41 +0,0 @@
|
||||
"""Script para verificar números de tickets existentes"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import select
|
||||
from app.models.ticket import Ticket
|
||||
import os
|
||||
|
||||
async def check_tickets():
|
||||
database_url = os.getenv('DATABASE_URL', 'postgresql+asyncpg://postgres:postgres@db:5432/servicemanager')
|
||||
engine = create_async_engine(database_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
tenant_id = 'c186c814-4f5a-4293-aae9-46f57637bb35'
|
||||
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
select(Ticket.ticket_number, Ticket.id, Ticket.subject)
|
||||
.where(Ticket.tenant_id == tenant_id)
|
||||
.order_by(Ticket.ticket_number)
|
||||
)
|
||||
tickets = result.all()
|
||||
|
||||
print(f"Tickets existentes para tenant {tenant_id}:")
|
||||
print("=" * 80)
|
||||
for ticket_number, ticket_id, subject in tickets:
|
||||
print(f" {ticket_number} | {ticket_id} | {subject}")
|
||||
print("=" * 80)
|
||||
print(f"Total: {len(tickets)} tickets")
|
||||
|
||||
if tickets:
|
||||
last_ticket = tickets[-1]
|
||||
last_number = int(last_ticket[0].split('-')[1])
|
||||
next_number = last_number + 1
|
||||
print(f"\nÚltimo número: {last_ticket[0]} (número: {last_number})")
|
||||
print(f"Próximo número debería ser: TK-{next_number:06d}")
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_tickets())
|
||||
@@ -1,42 +0,0 @@
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add parent directory to path so we can import 'app'
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from sqlalchemy import select
|
||||
from app.core.database import AsyncSessionLocal
|
||||
from app.models.tenant import Tenant
|
||||
from app.models.ticket import Ticket
|
||||
from app.models.category import Category # ✅ AÑADIR ESTO
|
||||
from app.models.system import System # ✅ AÑADIR ESTO
|
||||
from app.models.user import User
|
||||
from app.core.security import SecurityUtils
|
||||
|
||||
async def fix_password():
|
||||
async with AsyncSessionLocal() as session:
|
||||
# Find the admin user
|
||||
email = "admin@aduanasoft.com"
|
||||
result = await session.execute(select(User).where(User.email == email))
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if user:
|
||||
print(f"User {email} found.")
|
||||
# Reset password to 'admin123'
|
||||
new_password = "admin123"
|
||||
hashed = SecurityUtils.hash_password(new_password)
|
||||
user.password_hash = hashed
|
||||
|
||||
try:
|
||||
await session.commit()
|
||||
print(f"Password for {email} updated successfully!")
|
||||
print(f"New password is: {new_password}")
|
||||
except Exception as e:
|
||||
await session.rollback()
|
||||
print(f"Error updating password: {e}")
|
||||
else:
|
||||
print(f"User {email} not found!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(fix_password())
|
||||
@@ -1,31 +0,0 @@
|
||||
"""Script para listar todos los usuarios"""
|
||||
import asyncio
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import select
|
||||
from app.models.user import User
|
||||
import os
|
||||
|
||||
async def list_users():
|
||||
database_url = os.getenv('DATABASE_URL', 'postgresql+asyncpg://postgres:postgres@db:5432/servicemanager')
|
||||
engine = create_async_engine(database_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as session:
|
||||
result = await session.execute(select(User))
|
||||
users = result.scalars().all()
|
||||
|
||||
if users:
|
||||
print(f'Found {len(users)} users:')
|
||||
for user in users:
|
||||
print(f'\n Email: {user.email}')
|
||||
print(f' Role: {user.role}')
|
||||
print(f' Tenant ID: {user.tenant_id}')
|
||||
print(f' User ID: {user.id}')
|
||||
else:
|
||||
print('No users found')
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(list_users())
|
||||
@@ -1,59 +0,0 @@
|
||||
"""
|
||||
Script para establecer contraseña real al test_user
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
from sqlalchemy import select
|
||||
from passlib.context import CryptContext
|
||||
|
||||
# Configurar el path
|
||||
backend_path = os.path.join(os.path.dirname(__file__), 'backend')
|
||||
sys.path.insert(0, backend_path)
|
||||
|
||||
from app.core.database import AsyncSessionLocal
|
||||
from app.models.user import User
|
||||
|
||||
# Configurar passlib
|
||||
pwd_context = CryptContext(
|
||||
schemes=["argon2", "bcrypt"],
|
||||
deprecated="auto",
|
||||
argon2__memory_cost=65536,
|
||||
argon2__time_cost=3,
|
||||
argon2__parallelism=4,
|
||||
)
|
||||
|
||||
async def set_test_user_password():
|
||||
"""Establecer contraseña admin123 para test_user"""
|
||||
|
||||
new_password = "admin123"
|
||||
password_hash = pwd_context.hash(new_password)
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
# Buscar test_user
|
||||
result = await session.execute(
|
||||
select(User).where(User.email == "test_user@example.com")
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
print("❌ Usuario test_user@example.com no encontrado")
|
||||
return
|
||||
|
||||
print(f"✅ Usuario encontrado: {user.email}")
|
||||
print(f"Hash anterior: {user.password_hash}")
|
||||
|
||||
# Establecer nueva contraseña hash
|
||||
user.password_hash = password_hash
|
||||
await session.commit()
|
||||
|
||||
print(f"🎉 Contraseña establecida: {new_password}")
|
||||
print(f"✅ Nuevo hash: {password_hash[:50]}...")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
await session.rollback()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(set_test_user_password())
|
||||
Reference in New Issue
Block a user