Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ SMTP_PASSWORD=your-app-password
SMTP_DOMAIN=soundscape.com

# AI Configuration
GEMINI_API_KEY=your-gemini-api-key-here
OPENAI_API_KEY=your-openai-api-key-here
# OPENAI_MODEL=gpt-3.5-turbo

# Redis Configuration (for caching and rate limiting)
REDIS_URL=redis://localhost:6379/0
Expand Down
18 changes: 9 additions & 9 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ En la sección **Environment Variables**, agrega:

#### Variables Requeridas (las tienes que configurar)
- `RAILS_MASTER_KEY` → Copia el contenido de `config/master.key`
- `GEMINI_API_KEY` → Tu clave de API de Google Gemini
- `OPENAI_API_KEY` → Tu clave API de OpenAI
- `SMTP_USERNAME` → Tu email de Gmail
- `SMTP_PASSWORD` → Tu contraseña de aplicación de Gmail
- `CORS_ALLOWED_ORIGINS` → URL de tu frontend en Vercel (ej: `https://soundscape-frontend.vercel.app`)
Expand Down Expand Up @@ -81,28 +81,28 @@ https://soundscape-api.onrender.com
```

### Endpoints principales:
- Health Check: `GET /up`
- API Base: `/api/v1/`
- Chequeo de salud: `GET /up`
- API base: `/api/v1/`
- Autenticación: `/api/v1/auth/login`
- Playlists: `/api/v1/playlists`
- AI Search: `/api/v1/ai_search`
- Búsqueda con IA: `/api/v1/ai_search`

## 🔧 Troubleshooting
## 🔧 Solución de Problemas

### Error: "Web service failed to start"
### Error: "El servicio web no pudo iniciar"
1. Revisa los logs en Render Dashboard
2. Verifica que `RAILS_MASTER_KEY` sea correcto
3. Asegúrate de que todas las variables de entorno estén configuradas

### Error: Database connection
### Error: Conexión a la base de datos
1. Verifica que `DATABASE_URL` esté conectada correctamente
2. La base de datos debe estar en el mismo proyecto

### Error: CORS
1. Verifica que `CORS_ALLOWED_ORIGINS` contenga la URL exacta de tu frontend
2. No agregues "/" al final de las URLs

### Error: Email sending
### Error: Envío de correo
1. Verifica `SMTP_USERNAME` y `SMTP_PASSWORD`
2. Asegúrate de usar una contraseña de aplicación, no tu contraseña de Gmail normal

Expand All @@ -118,4 +118,4 @@ Una vez que tu API esté funcionando:
Si tienes problemas:
1. Revisa los logs en Render Dashboard
2. Verifica que todas las variables de entorno estén configuradas
3. Prueba los endpoints manualmente con curl o Postman
3. Prueba los endpoints manualmente con curl o Postman
7 changes: 2 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ gem "jwt"
# Authorization with CanCanCan
gem "cancancan"

# AI Integration with Google Gemini
gem "gemini-ai"

# HTTP client for API requests
gem "faraday"
# OpenAI client
gem "ruby-openai", require: "openai"

# Redis for caching and rate limiting
gem "redis"
Expand Down
34 changes: 1 addition & 33 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ GEM
erubi (1.13.1)
et-orbi (1.2.11)
tzinfo
ethon (0.16.0)
ffi (>= 1.15.0)
event_stream_parser (1.0.0)
factory_bot (6.5.4)
activesupport (>= 6.1.0)
factory_bot_rails (6.5.0)
Expand All @@ -125,9 +123,6 @@ GEM
logger
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
faraday-typhoeus (1.1.0)
faraday (~> 2.0)
typhoeus (~> 1.4)
ffi (1.17.2-aarch64-linux-gnu)
ffi (1.17.2-aarch64-linux-musl)
ffi (1.17.2-arm-linux-gnu)
Expand All @@ -139,26 +134,8 @@ GEM
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
gemini-ai (4.3.0)
event_stream_parser (~> 1.0)
faraday (~> 2.13, >= 2.13.2)
faraday-typhoeus (~> 1.1)
googleauth (~> 1.8)
typhoeus (~> 1.4, >= 1.4.1)
globalid (1.2.1)
activesupport (>= 6.1)
google-cloud-env (2.3.1)
base64 (~> 0.2)
faraday (>= 1.0, < 3.a)
google-logging-utils (0.2.0)
googleauth (1.14.0)
faraday (>= 1.0, < 3.a)
google-cloud-env (~> 2.2)
google-logging-utils (~> 0.1)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
io-console (0.8.1)
Expand Down Expand Up @@ -229,7 +206,6 @@ GEM
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
os (1.1.4)
ostruct (0.6.3)
parallel (1.27.0)
parser (3.3.9.0)
Expand Down Expand Up @@ -355,11 +331,6 @@ GEM
securerandom (0.4.1)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
signet (0.20.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
solid_cable (3.0.11)
actioncable (>= 7.2)
activejob (>= 7.2)
Expand Down Expand Up @@ -391,8 +362,6 @@ GEM
thruster (0.1.15-x86_64-darwin)
thruster (0.1.15-x86_64-linux)
timeout (0.4.3)
typhoeus (1.4.1)
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.1.4)
Expand Down Expand Up @@ -428,8 +397,6 @@ DEPENDENCIES
dotenv-rails
factory_bot_rails
faker
faraday
gemini-ai
jwt
kamal
pg (~> 1.1)
Expand All @@ -439,6 +406,7 @@ DEPENDENCIES
redis
rspec-rails
rubocop-rails-omakase
ruby-openai
shoulda-matchers (~> 6.5)
solid_cable
solid_cache
Expand Down
56 changes: 28 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ SoundScape es una API REST construida con Ruby on Rails que permite a los usuari

- **Autenticación JWT** con confirmación de email obligatoria
- **Gestión de Playlists** y canciones con autorización basada en roles
- **Búsqueda Inteligente con IA** usando Google Gemini para sugerencias de canciones
- **Sistema de Analytics** para tracking de búsquedas y tendencias
- **Cache Inteligente** y rate limiting para optimización de rendimiento
- **Búsqueda Potenciada con IA** usando OpenAI ChatGPT para sugerencias de canciones
- **Sistema de análisis** para seguimiento de búsquedas y tendencias
- **Cache Inteligente** y limitación de tasa para optimización de rendimiento
- **Exportación** a Spotify/YouTube Music (próximamente)

## 🛠 Tecnologías
Expand All @@ -18,16 +18,16 @@ SoundScape es una API REST construida con Ruby on Rails que permite a los usuari
- **PostgreSQL** como base de datos
- **JWT** para autenticación
- **CanCanCan** para autorización
- **Google Gemini AI** para búsqueda inteligente
- **OpenAI ChatGPT** para búsquedas con IA
- **RSpec** para testing
- **RuboCop** para formateo de código

## 📋 Requisitos del Sistema

- Ruby 3.2.2+
- PostgreSQL 12+
- Redis (para cache y rate limiting)
- Gemini API Key de Google
- Redis (para cache y limitación de tasa)
- Clave API de OpenAI

## ⚙️ Configuración

Expand All @@ -51,28 +51,28 @@ rails db:migrate
Crear archivo `.env` basado en `.env.example`:

```bash
# Database Configuration
# Configuración de Base de Datos
DATABASE_URL=postgresql://username:password@localhost/soundscape_development

# Email Configuration
# Configuración de Correo
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_DOMAIN=soundscape.com

# AI Configuration
GEMINI_API_KEY=your-gemini-api-key-here
# Configuración de IA
OPENAI_API_KEY=your-openai-api-key-here

# Redis Configuration (for caching and rate limiting)
# Configuración de Redis (para cache y limitación de tasa)
REDIS_URL=redis://localhost:6379/0
```

### 3. Obtener Gemini API Key
### 3. Obtener la API Key de OpenAI

1. Visita [Google AI Studio](https://makersuite.google.com/app/apikey)
2. Crea una nueva API key
3. Agrega la key a tu archivo `.env`
1. Visita [OpenAI Platform](https://platform.openai.com/account/api-keys)
2. Crea una nueva clave API
3. Agrega la clave a tu archivo `.env`

## 🚀 Uso

Expand Down Expand Up @@ -177,32 +177,32 @@ Actualmente tenemos **107+ tests pasando** con cobertura completa de:
- Modelos y validaciones
- Controladores y autenticación
- Servicios de IA y cache
- Analytics y rate limiting
- Análisis y limitación de tasa

## 📊 Funcionalidades de IA

### Búsqueda Inteligente

El sistema utiliza **Google Gemini 1.5 Flash** para generar sugerencias inteligentes de canciones:
El sistema usa **OpenAI ChatGPT** para generar sugerencias de canciones:

- **Cache**: Resultados cacheados por 1 hora para mejor rendimiento
- **Rate Limiting**: 60 búsquedas por hora por usuario
- **Limitación de tasa**: 60 búsquedas por hora por usuario
- **Validación**: Queries entre 2-100 caracteres
- **Fallback**: Respuesta graceful cuando la IA no está disponible
- **Respuesta alternativa**: Respuesta de emergencia cuando la IA no está disponible

### Analytics y Tendencias
### Análisis y Tendencias

- **Tracking de búsquedas**: Registra consultas, timestamps y resultados
- **Búsquedas trending**: Top consultas en períodos configurables
- **Seguimiento de búsquedas**: Registra consultas, timestamps y resultados
- **Búsquedas en tendencia**: Top consultas en períodos configurables
- **Historial personal**: Búsquedas paginadas por usuario
- **Datos anónimos**: IP addresses para analytics sin identificación personal
- **Datos anónimos**: Direcciones IP para análisis sin identificación personal

## 🔒 Seguridad

- **JWT Authentication** con tokens seguros
- **Email confirmation** obligatoria antes del acceso
- **Rate limiting** por usuario y endpoint
- **Authorization** basada en roles con CanCanCan
- **Autenticación JWT** con tokens seguros
- **Confirmación de email** obligatoria antes del acceso
- **Limitación de tasa** por usuario y endpoint
- **Autorización** basada en roles con CanCanCan
- **Validación** exhaustiva de inputs
- **Logs seguros** sin exposición de datos sensibles

Expand All @@ -228,7 +228,7 @@ docker-compose up -d
- [ ] Sistema de recomendaciones personalizado
- [ ] Compartir playlists entre usuarios
- [ ] API de exportación masiva
- [ ] Dashboard de analytics
- [ ] Dashboard de análisis
- [ ] Mobile SDK

## 🤝 Contribución
Expand Down
41 changes: 15 additions & 26 deletions app/services/ai_search_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class AiSearchService

def initialize(attributes = {})
super
@api_key = ENV["GEMINI_API_KEY"]
raise StandardError, "GEMINI_API_KEY not configured" if @api_key.blank?
@api_key = ENV["OPENAI_API_KEY"]
raise StandardError, "OPENAI_API_KEY not configured" if @api_key.blank?
end

def search_songs
Expand Down Expand Up @@ -98,31 +98,20 @@ def fetch_from_cache

def generate_ai_suggestions
prompt = build_search_prompt

conn = Faraday.new("https://generativelanguage.googleapis.com")

response = conn.post("/v1beta/models/gemini-1.5-flash:generateContent") do |req|
req.params["key"] = @api_key
req.headers["Content-Type"] = "application/json"
req.body = {
contents: [{
parts: [{ text: prompt }]
}]
}.to_json
end

if response.success?
result = JSON.parse(response.body)
result.dig("candidates", 0, "content", "parts", 0, "text") || ""
else
Rails.logger.error "Gemini API Error: #{response.status} - #{response.body}"
raise StandardError, "Gemini API request failed: #{response.status}"
end
rescue JSON::ParserError => e
Rails.logger.error "JSON Parse Error: #{e.message}"
raise StandardError, "Failed to parse Gemini response"

client = OpenAI::Client.new(access_token: @api_key)
response = client.chat(
parameters: {
model: ENV.fetch("OPENAI_MODEL", "gpt-3.5-turbo"),
messages: [
{ role: "user", content: prompt }
]
}
)

response.dig("choices", 0, "message", "content") || ""
rescue StandardError => e
Rails.logger.error "Gemini API Error: #{e.message}"
Rails.logger.error "OpenAI API Error: #{e.message}"
raise e
end

Expand Down
4 changes: 2 additions & 2 deletions render.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ services:
# CORS Configuration
- key: CORS_ALLOWED_ORIGINS
value: https://soundscape-frontend-qzwqagdi9-jean612s-projects.vercel.app
# Gemini AI API Key
- key: GEMINI_API_KEY
# OpenAI API Key
- key: OPENAI_API_KEY
sync: false
buildCommand: bundle install
startCommand: ./bin/render-start.sh
Expand Down
Loading