diff --git a/README.md b/README.md index d101740..259b1e2 100644 --- a/README.md +++ b/README.md @@ -1,191 +1,279 @@ -# API de Parchat +# 🚀 API de Parchat -Este proyecto implementa una API para una plataforma de mensajería utilizando Go, Fx para la gestión de dependencias y Firebase Authentication para la autenticación de usuarios. +> Plataforma de mensajería en tiempo real desarrollada en Go, con autenticación mediante Firebase, persistencia en Firestore y comunicación instantánea vía WebSockets. -## Estructura del Proyecto +--- -``` +## 📚 Índice + +* [🧰 Tecnologías principales](#tecnologías-principales) +* [🗂️ Estructura del Proyecto](#️estructura-del-proyecto) +* [✅ Requisitos](#requisitos) +* [⚙️ Configuración](#configuración) +* [▶️ Ejecución](#️ejecución) +* [📖 Documentación API (Swagger)](#documentación-api-swagger) +* [🔐 Endpoints](#endpoints) + + * [🟢 Públicos](#-públicos) + * [🔒 Protegidos (requieren token JWT)](#protegidos-requieren-token-jwt) +* [⚙️ Implementación técnica](#implementación-técnica) + + * [🧩 Firestore](#firestore) +* [🌐 WebSockets](#websockets) +* [💬 Flujo de Chat Directo](#flujo-de-chat-directo) +* [🚧 Desarrollo](#desarrollo) + +--- + +## 🧰 Tecnologías principales + +| Herramienta | Descripción | +| ----------------- | ------------------------------------------------------ | +| **Go** | Lenguaje principal por su rendimiento y concurrencia | +| **Uber Fx** | Inyección de dependencias para arquitectura modular | +| **Firebase Auth** | Autenticación segura de usuarios | +| **Firestore** | Base de datos NoSQL en tiempo real | +| **WebSockets** | Comunicación bidireccional para mensajería instantánea | +| **Chi** | Router HTTP ligero y eficiente | +| **Swagger** | Generación automática de documentación | +| **Docker** | Contenedorización para desarrollo y despliegue | + +--- + +## 🗂️ Estructura del Proyecto + +
+Ver estructura completa del proyecto + +```bash . -├── cmd -│ └── api -│ └── main.go # Punto de entrada de la aplicación +├── cmd/api/main.go # Entrada principal ├── internal -│ ├── auth -│ │ └── firebase.go # Integración con Firebase Auth -│ ├── config -│ │ └── config.go # Configuración de la aplicación -│ ├── handlers -│ │ └── user_handler.go # Manejadores HTTP -│ ├── middleware -│ │ └── auth_middleware.go # Middleware de autenticación -│ ├── models -│ │ └── user.go # Modelos de datos -│ ├── routes -│ │ └── router.go # Definición de rutas -│ └── services -│ └── user_service.go # Lógica de negocio -├── docs # Documentación generada por Swagger -├── .env.example # Ejemplo de variables de entorno -├── go.mod # Dependencias de Go -└── README.md # Documentación +│ ├── config/ # Configuración general y de servicios +│ ├── handlers/ # Manejadores HTTP +│ ├── middleware/ # Middleware de autenticación +│ ├── models/ # Modelos de negocio +│ ├── pkg/websocket/ # WebSocket Hub e implementación +│ ├── repositories/ # Acceso a datos +│ ├── routes/router.go # Ruteo +│ └── services/ # Lógica de negocio +├── docs/ # Documentación Swagger +├── Dockerfile.dev / .prod # Archivos Docker +├── compose.yml # Configuración de Docker Compose +└── README.md # Documentación general ``` -## Requisitos +
+ +--- -- [Docker Compose](https://docs.docker.com/compose/install/) -- Cuenta de Firebase con Authentication habilitado -- Archivo de credenciales de Firebase Admin SDK +## ✅ Requisitos -## Configuración +* [Docker Compose](https://docs.docker.com/compose/install/) +* Cuenta Firebase con **Authentication** habilitado +* Archivo de credenciales de Firebase Admin SDK -1. Crea un archivo `.env` basado en `.env.example`: +--- + +## ⚙️ Configuración ```bash cp .env.example .env ``` -2. Configura las variables de entorno en el archivo `.env`: +Edita `.env` con tu configuración: -``` +```env PORT=8080 -FIREBASE_CREDENTIALS=./path/to/your/firebase-credentials.json +FIREBASE_CREDENTIALS=./path/to/firebase-credentials.json ENVIRONMENT=development ``` -3. Asegúrate de tener el archivo de credenciales de Firebase Admin SDK en la ubicación especificada. +--- -## Ejecución +## ▶️ Ejecución ```bash docker compose --profile=dev up ``` -## Documentación API (Swagger) +--- + +## 📖 Documentación API (Swagger) -Para generar o actualizar la documentación de la API con Swagger, ejecuta: +Generar y formatear documentación: ```bash -# Generar documentación swag init -g cmd/api/main.go -o ./docs - -# Formatear comentarios de Swagger swag fmt ``` -Una vez iniciado el servidor puedes acceder a la documentación desde [http://localhost:8080/swagger/index.html](http://localhost:8080/swagger/index.html) +🔗 Accede a Swagger: +[http://localhost:8080/swagger/index.html](http://localhost:8080/swagger/index.html) + +--- + +## 🔐 Endpoints -## Endpoints +### 🟢 Públicos + +| Método | Ruta | Descripción | +| ------ | --------------------- | --------------------- | +| `GET` | `/health` | Estado de la API | +| `POST` | `/auth/signup` | Registro de usuario | +| `POST` | `/api/v1/auth/signup` | Registro (versión v1) | + +### 🔒 Protegidos + +🔑 Requieren Header: + +```http +Authorization: Bearer +``` -### Públicos +| Método | Ruta | Descripción | +| ------ | --------------------- | ------------------------------------------------- | +| `GET` | `/api/v1/auth/me` | Información del usuario actual | +| `POST` | `/api/v1/user/create` | Asegura que el usuario exista en la base de datos | -- `GET /health`: Verifica el estado de la API -- `POST /auth/signup`: Registra un nuevo usuario -- `POST /api/v1/auth/signup`: Registra un nuevo usuario +#### 🧑‍🤝‍🧑 Salas de Chat -### Protegidos (requieren token JWT) +| Método | Ruta | Descripción | +| ------ | ------------------------------------------------ | ----------------------------------- | +| `POST` | `/api/v1/chat/rooms` | Crea una nueva sala de chat | +| `GET` | `/api/v1/chat/rooms` | Obtiene todas las salas disponibles | +| `GET` | `/api/v1/chat/rooms/me` | Salas del usuario actual | +| `GET` | `/api/v1/chat/rooms/{roomId}` | Información de una sala específica | +| `GET` | `/api/v1/chat/rooms/{roomId}/messages` | Mensajes de una sala específica | +| `GET` | `/api/v1/chat/rooms/{roomId}/messages/paginated` | Mensajes paginados de una sala | +| `POST` | `/api/v1/chat/rooms/{roomId}/join` | Une al usuario a una sala | -#### Autenticación -- `GET /api/v1/auth/me`: Obtiene información del usuario actual +#### 💬 Chats Directos -#### Salas de Chat -- `POST /api/v1/chat/rooms`: Crea una nueva sala de chat -- `GET /api/v1/chat/rooms`: Obtiene todas las salas del usuario actual -- `GET /api/v1/chat/rooms/{roomId}`: Obtiene información de una sala específica -- `GET /api/v1/chat/rooms/{roomId}/messages`: Obtiene mensajes de una sala específica -- `GET /api/v1/chat/rooms/{roomId}/messages/paginated`: Obtiene mensajes de una sala específica paginados +| Método | Ruta | Descripción | +| ------ | --------------------------------------- | ----------------------------------------- | +| `POST` | `/api/v1/chat/direct/{otherUserId}` | Crea un chat directo con otro usuario | +| `GET` | `/api/v1/chat/direct/me` | Todos los chats directos del usuario | +| `GET` | `/api/v1/chat/direct/{chatId}` | Información de un chat directo específico | +| `GET` | `/api/v1/chat/direct/{chatId}/messages` | Mensajes de un chat directo específico | -#### Chats Directos -- `POST /api/v1/chat/direct/{otherUserId}`: Crea un chat directo entre el usuario autenticado y otro usuario -- `GET /api/v1/chat/direct/me`: Obtiene todos los chats directos del usuario actual -- `GET /api/v1/chat/direct/{chatId}/messages`: Obtiene mensajes de un chat directo específico +#### 🚨 Moderación -#### WebSocket -- `GET /api/v1/chat/ws`: Endpoint para establecer conexión WebSocket +| Método | Ruta | Descripción | +| ------ | ------------------------------------------- | --------------------------------------------- | +| `POST` | `/api/v1/chat/rooms/{roomId}/report` | Reportar mensaje inapropiado | +| `GET` | `/api/v1/chat/rooms/{roomId}/banned-users` | Usuarios baneados (solo admins) | +| `POST` | `/api/v1/chat/rooms/{roomId}/clear-reports` | Eliminar reportes de un usuario (solo admins) | -## Flujo de Chat Directo +#### 🔌 WebSocket -### Establecer un Direct Chat entre usuarios desde Postman +| Método | Ruta | Descripción | +| ------ | ----------------- | ---------------------------- | +| `GET` | `/api/v1/chat/ws` | Establece conexión WebSocket | -Para establecer un Direct Chat entre dos usuarios usando Postman, necesitas seguir estos pasos: +--- -#### 1. Obtén un token JWT +## ⚙️ Implementación técnica -Primero, debes autenticarte para obtener un token JWT: +### 🧩 Firestore -1. Inicia sesión con tu usuario en la API (esto dependerá de tu implementación de autenticación) -2. Obtén el token JWT de la respuesta +**Colecciones usadas**: -#### 2. Crea el Direct Chat +* `users` +* `rooms` +* `messages` +* `directChats` +* `reports` -Una vez que tengas el token, puedes crear un Direct Chat: +**Ventajas**: -1. Configura una solicitud POST a: `http://localhost:8080/api/v1/chat/direct/{ID_DEL_OTRO_USUARIO}` - - Reemplaza `{ID_DEL_OTRO_USUARIO}` con el ID real del usuario con el que deseas chatear -2. En la pestaña "Headers", añade: - - `Content-Type: application/json` - - `Authorization: Bearer TU_TOKEN_JWT` -3. Envía la solicitud +* Realtime +* Escalabilidad automática +* Integración con Firebase Auth -La respuesta será un JSON con los detalles del chat directo creado (o existente si ya había uno): +## 🌐 WebSockets + +**URL**: `ws://localhost:8080/api/v1/chat/ws` +**Header**: `Authorization: Bearer ` + +### Tipos de mensajes + +| Tipo | Descripción | +| ------------------ | --------------------------- | +| `CHAT_ROOM` | Enviar mensaje a una sala | +| `DIRECT_CHAT` | Enviar mensaje directo | +| `JOIN_ROOM` | Unirse a una sala | +| `JOIN_DIRECT_CHAT` | Unirse a chat directo | +| `USER_LEAVE` | Abandonar sala | +| `ERROR` | Mensaje de error | +| `SUCCESS` | Operación exitosa | +| `ROOM_CREATED` | Notificación de sala creada | + +--- + +## 💬 Flujo de Chat Directo con Postman + +### Paso 1: Obtener JWT + +Autentícate y copia el token desde la respuesta. + +### Paso 2: Crear Direct Chat + +```http +POST /api/v1/chat/direct/{otherUserId} +Authorization: Bearer +``` + +📥 Respuesta esperada: ```json { "id": "chat-id-123456", - "userIds": ["tu-usuario-id", "ID_DEL_OTRO_USUARIO"], - "createdAt": "2025-05-13T10:15:30Z", - "updatedAt": "2025-05-13T10:15:30Z" + "userIds": [...], + "displayNames": [...], + "createdAt": "...", + "updatedAt": "..." } ``` -#### 3. Para usar WebSocket desde Postman - -Si quieres probar la conexión WebSocket desde Postman: - -1. Crea una nueva pestaña de tipo "WebSocket Request" -2. Introduce esta URL: `ws://localhost:8080/api/v1/chat/ws` -3. En la sección "Headers", añade: - - `Authorization: Bearer TU_TOKEN_JWT` -4. Conecta al WebSocket - -Para unirte al chat directo recién creado: -1. En el panel "Message", envía: - ```json - { - "type": "JOIN_DIRECT_CHAT", - "payload": "chat-id-123456", - "timestamp": "2025-05-13T10:16:00Z" - } - ``` - -Para enviar un mensaje: -1. En el panel "Message", envía: - ```json - { - "type": "DIRECT_CHAT", - "payload": { - "content": "Hola, este es un mensaje de prueba", - "roomID": "chat-id-123456", - "type": "text" - }, - "timestamp": "2025-05-13T10:17:00Z" - } - ``` - -## Autenticación - -Para acceder a los endpoints protegidos, debes incluir un token de ID de Firebase en el encabezado `Authorization`: +### Paso 3: WebSocket desde Postman +* URL: `ws://localhost:8080/api/v1/chat/ws` +* Header: `Authorization: Bearer ` + +**Unirse al chat**: + +```json +{ + "type": "JOIN_DIRECT_CHAT", + "payload": "chat-id-123456", + "timestamp": "2025-05-13T10:16:00Z" +} ``` -Authorization: Bearer + +**Enviar mensaje**: + +```json +{ + "type": "DIRECT_CHAT", + "payload": { + "content": "Hola", + "roomID": "chat-id-123456", + "type": "text" + }, + "timestamp": "2025-05-13T10:17:00Z" +} ``` -## Desarrollo +--- + +## 🚧 Desarrollo -Para añadir nuevas funcionalidades: +Pasos para añadir nuevas funcionalidades: -1. Crea los modelos necesarios en `internal/models/` -2. Implementa la lógica de negocio en `internal/services/` -3. Crea los repositorios en caso de ser necesarios en `internal/repositories/` -4. Crea los manejadores HTTP en `internal/handlers/` -5. Registra las rutas en `internal/routes/router.go` -6. Registra los proveedores en `cmd/api/main.go` +1. 📦 Modelos → `internal/models/` +2. 🔧 Servicios → `internal/services/` +3. 🗃 Repositorios → `internal/repositories/` +4. 🧩 Manejadores HTTP → `internal/handlers/` +5. 🌐 Rutas → `internal/routes/router.go` +6. 🧬 Proveedores → `cmd/api/main.go`