Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vanegasjoseignacio2-cyber/Eco-It/llms.txt

Use this file to discover all available pages before exploring further.

EcoBot is Eco-It’s conversational AI assistant, purpose-built to answer questions about recycling and environmental sustainability in the Colombian context. It refuses all off-topic requests and enforces Colombia’s national color-coded bin system in every response — White (Blanco) for recyclables such as plastic, glass, and metals; Black (Negro) for non-recyclables like used paper towels and dirty napkins; and Green (Verde) for organic waste such as food scraps. EcoBot never uses Markdown formatting in its replies and always responds in Spanish.

AI Models

EcoBot is backed by two models, accessed through the OpenRouter API.

openrouter/free

The primary model used for all text-based conversations. Requests fall back automatically when the quota is exhausted.

google/gemini-2.5-flash-lite

The fallback model for text queries when openrouter/free hits a rate limit or quota error. Also the exclusive model used for all image analysis requests due to its multimodal capabilities.
The fallback logic inspects HTTP status codes 429 and 402, as well as error message keywords such as rate_limit, quota, limit exceeded, insufficient, and credits, before switching to Gemini.

Chat Sessions & Persistence

Every conversation is stored as a Chat document in MongoDB, scoped to the authenticated user. Each chat holds a title (derived from the first 40 characters of the opening question) and an array of mensajes (messages) with role (user or bot) and content fields. A hard cap of 50 chats per user is enforced automatically — when the limit is exceeded, the oldest chats are deleted.

GET /api/ai/chats

Returns all chats for the authenticated user, sorted newest first. Includes _id, title, and updatedAt.

GET /api/ai/chats/:id

Returns the full message history of a single chat by its ID.

DELETE /api/ai/chats/:id

Permanently deletes a single chat belonging to the authenticated user.

DELETE /api/ai/chats

Permanently deletes all chats belonging to the authenticated user.
All chat endpoints require a valid JWT in the Authorization: Bearer <token> header.

Text Chat — SSE Streaming

Sending a question to EcoBot opens a Server-Sent Events (SSE) stream so that tokens are delivered to the client incrementally as they are generated.

Endpoint

pregunta
string
required
The user’s recycling or sustainability question, in plain text.
chatId
string
Optional. The MongoDB _id of an existing chat session to continue. If omitted, a new chat is created automatically.
POST /api/ai/consultar
Authorization: Bearer <token>
Content-Type: application/json

{
  "pregunta": "¿Cómo reciclo una botella PET correctamente?",
  "chatId": "664f1a2b3c4d5e6f7a8b9c0d"
}
The server responds with Content-Type: text/event-stream. The first SSE event always carries the chatId so the client can associate subsequent chunks with the session:
data: {"chatId":"664f1a2b3c4d5e6f7a8b9c0d"}

data: {"content":"Las botellas PET (código 1) son altamente reciclables."}

data: {"content":" Enjuágalas, retira la tapa y deposítalas en la caneca blanca."}

data: [DONE]

Consuming the Stream — JavaScript Example

The consultarIA function from frontend/src/services/api.js shows the canonical pattern for reading the SSE stream in the browser:
import { consultarIA } from '@/services/api';

async function sendMessage(question, chatId) {
  const abortController = new AbortController();

  await consultarIA(
    question,
    chatId,
    (content, newChatId) => {
      if (newChatId) {
        // Store the chat ID returned with the first event
        currentChatId = newChatId;
      }
      if (content) {
        // Append each token chunk to the displayed message
        appendToMessage(content);
      }
    },
    abortController.signal
  );
}
The function reads the response body with a ReadableStream reader, splits incoming bytes by newline, strips the data: prefix from each line, and parses the JSON payload. When the sentinel value [DONE] is received the stream terminates.

Image Analysis

EcoBot can analyze a photograph of a waste item and suggest the correct Colombian bin for disposal.

Endpoint

imagen
string
required
A base64-encoded data URL (e.g. data:image/jpeg;base64,...) of the image to analyze.
contexto
string
Optional text providing additional context about the image (e.g. "¿Es reciclable este envase?"). Defaults to a generic analysis prompt.
chatId
string
Optional. The _id of an existing chat to append the image interaction to. A new chat is created when omitted.
POST /api/ai/analizar-imagen
Authorization: Bearer <token>
Content-Type: application/json

{
  "imagen": "data:image/jpeg;base64,/9j/4AAQ...",
  "contexto": "¿En qué caneca va este envase de vidrio?",
  "chatId": "664f1a2b3c4d5e6f7a8b9c0d"
}
success
boolean
true when the analysis completes successfully.
data.respuesta
string
EcoBot’s plain-text analysis and disposal recommendation in Spanish.
data.chatId
string
The _id of the chat session (existing or newly created).
Unlike text chat, image analysis is not streamed — the full response is returned in a single JSON body once Gemini finishes processing.

Content Moderation

EcoBot enforces a strict zero-tolerance content policy at two layers: the AI’s own system prompt, and a server-side post-processing check on every response.
1

Inappropriate language detected

If the AI’s reply contains the sentinel string ALERTA_LENGUAJE_INAPROPIADO, the backend calls registrarAlertaContenido without banning the user. A Notification document of type alerta_lenguaje is saved to MongoDB and the admin:alerta_lenguaje Socket.io event is broadcast to all connected admins in real time.
2

Obscene image detected

If the Gemini response for an image begins with ALERTA_OBSCENA:, the backend automatically sets the user’s status to banned for 3 days and records the ban reason as "Sistema: Envío de imagen con contenido obsceno.". Two Socket.io events are then emitted to the admins room: admin:alerta_obscena (with the offending image payload) and admin:usuario_baneado.
3

Admin notification persisted

All content moderation alerts are stored in the Notification collection with a TTL index of 7 days (604,800 seconds), after which they are automatically purged from the database.
Banned users receive a 403 HTTP response on all subsequent API calls. The frontend listens for this status code and dispatches a global USER_BANNED custom event to inform the UI and log the user out.

Client-Side Input Validation

The ChatInput component (Charinput.jsx) applies a real-time offensive-language check via the useOfensiveValidator hook before a message is ever sent to the server. It also strips emoji characters and any non-Latin-extended Unicode scripts (Cyrillic, Arabic, CJK, etc.), keeping input within the expected character set for Spanish text.
EcoBot’s system prompt enforces the following rules on every response: replies must always be in Spanish, no Markdown formatting (no **bold**, no ### headings, no asterisk lists) may appear in the output, and only plain text with simple numbered lists (1., 2.) or single hyphens (-) is allowed. These constraints apply equally to the primary openrouter/free model and the google/gemini-2.5-flash-lite fallback.

Build docs developers (and LLMs) love