Skip to content
Merged

Dev #56

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
340 changes: 340 additions & 0 deletions README.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
<p align="center">
<img src="backend/static/images/suuuu5.png" alt="Looping Marketplace" width="600">
</p>

<p align="center">
<a href="README.md"><img src="https://img.shields.io/badge/English-0d1a1f?style=flat&logoColor=7fd1c6&labelColor=0a1014" alt="English"></a>
·
<img src="https://img.shields.io/badge/Espa%C3%B1ol-0d1a1f?style=flat&logoColor=7fd1c6&labelColor=0a1014" alt="Español">
</p>

<p align="center">
<img src="https://img.shields.io/badge/Python-3.12+-0a1014?logo=python&logoColor=7fd1c6&labelColor=0d1a1f" alt="Python">
<img src="https://img.shields.io/badge/Django-6.0-0a1014?logo=django&logoColor=7fd1c6&labelColor=0d1a1f" alt="Django">
<img src="https://img.shields.io/badge/Bootstrap-5.3-0a1014?logo=bootstrap&logoColor=7fd1c6&labelColor=0d1a1f" alt="Bootstrap">
<img src="https://img.shields.io/badge/Stripe-payments-0a1014?logo=stripe&logoColor=7fd1c6&labelColor=0d1a1f" alt="Stripe">
<img src="https://img.shields.io/badge/Supabase-storage-0a1014?logo=supabase&logoColor=7fd1c6&labelColor=0d1a1f" alt="Supabase">
<img src="https://img.shields.io/badge/PostgreSQL-database-0a1014?logo=postgresql&logoColor=7fd1c6&labelColor=0d1a1f" alt="PostgreSQL">
<img src="https://img.shields.io/badge/uv-package%20mgr-0a1014?logoColor=7fd1c6&labelColor=0d1a1f" alt="uv">
<img src="https://img.shields.io/badge/Docker-compose-0a1014?logo=docker&logoColor=7fd1c6&labelColor=0d1a1f" alt="Docker">
<img src="https://img.shields.io/badge/Make-dev-0a1014?logo=gnu&logoColor=7fd1c6&labelColor=0d1a1f" alt="Make">
</p>

# Looping Marketplace

Marketplace web completo para comprar y vender productos, con pagos online seguros y cuentas de comprador y vendedor.

CRUD completo de productos | Roles de comprador y vendedor | Pagos con Stripe | 2 idiomas (EN / ES)

---

## Tabla de contenidos

- [Descripción del proyecto](#descripción-del-proyecto)
- [Funcionalidades](#funcionalidades)
- [Arquitectura](#arquitectura)
- [Stack técnico](#stack-técnico)
- [Estructura del proyecto](#estructura-del-proyecto)
- [Modelo de datos](#modelo-de-datos)
- [Endpoints de la API](#endpoints-de-la-api)
- [Puesta en marcha](#puesta-en-marcha)
- [Ejecutar con Make (recomendado)](#ejecutar-con-make-recomendado)
- [Ejecutar en macOS / Linux](#ejecutar-en-macos--linux)
- [Ejecutar en Windows](#ejecutar-en-windows)
- [Ejecutar con Docker](#ejecutar-con-docker)
- [Variables de entorno](#variables-de-entorno)
- [Comandos de Make](#comandos-de-make)
- [Hoja de ruta](#hoja-de-ruta)
- [Contribuir](#contribuir)

---

## Descripción del proyecto

**Looping Marketplace** es una aplicación web completa diseñada para comprar y vender productos. Incluye un sistema CRUD completo e integra Stripe como pasarela de pago.

La aplicación es totalmente funcional para uso real. Los usuarios pueden crear una cuenta y empezar a explorar y comprar productos de inmediato. Para convertirse en vendedor, pagan una cuota única que desbloquea el rol de vendedor y les permite publicar y gestionar sus propios productos.

## Funcionalidades

- Sistema CRUD completo para productos
- Autenticación de usuarios y gestión de roles (comprador / vendedor)
- Upgrade único para convertirse en vendedor
- Integración de pagos con Stripe (checkout individual y múltiple)
- Favoritos y carrito de compra
- Almacenamiento de imágenes de producto en Supabase
- Base de datos PostgreSQL (SQLite como respaldo en desarrollo local)
- Interfaz responsive construida con Bootstrap
- Páginas de error personalizadas (400 / 403 / 404 / 500) y logging centralizado

## Arquitectura

Looping Marketplace es un **monolito Django con renderizado en servidor**. Django gestiona la lógica de negocio y el HTML (plantillas Django + Bootstrap); los servicios externos se encargan de los pagos, el almacenamiento de imágenes y la base de datos.

```
┌──────────────────────────────┐
Navegador ──────▶│ Django (app MarketPlace) │
(UI Bootstrap, │ ────────────────────────── │
Stripe.js, │ urls.py → enrutado │
SweetAlert2) │ views.py → lógica negocio │
│ models.py → ORM │
│ templates → HTML servidor │
└───────┬───────┬───────┬──────┘
│ │ │
┌──────────────┘ │ └──────────────┐
▼ ▼ ▼
┌───────────────┐ ┌────────────────┐ ┌────────────────┐
│ PostgreSQL │ │ Stripe │ │ Supabase │
│ (Supabase / │ │ Checkout y │ │ Bucket de │
│ SQLite local)│ │ pagos │ │ imágenes │
└───────────────┘ └────────────────┘ └────────────────┘
```

**Flujo de una petición**

1. Un usuario se registra / inicia sesión → la autenticación de Django crea la cuenta y una señal `post_save` crea su `UserProfile`.
2. Un vendedor crea un producto → la imagen se sube al bucket `products_images` de Supabase y su URL pública se guarda en el `Product`.
3. Un comprador compra → se crea una sesión de Stripe Checkout → Stripe redirige a la URL de éxito → se registra el pedido.
4. Favoritos y carrito se guardan como relaciones del `UserProfile`.

## Stack técnico

| Capa | Tecnología |
|------|-----------|
| Framework web | Django 6.0 (Python 3.12) |
| Frontend | Plantillas Django + Bootstrap 5.3, Stripe.js, SweetAlert2 |
| Base de datos | PostgreSQL (vía `dj-database-url`) · SQLite en desarrollo local |
| Almacenamiento de imágenes | Supabase Storage |
| Pagos | Stripe Checkout |
| Autenticación | Autenticación de Django + señales de perfil |
| Gestor de paquetes | uv |
| Contenedores | Docker / Docker Compose |
| Tooling | Make |

## Estructura del proyecto

```
MarketPlace/
├── Makefile # Comandos de desarrollo (install, dev, migrate, docker-up...)
├── README.md / README.es.md # Documentación (EN / ES)
├── backend/
│ ├── manage.py # Punto de entrada de la CLI de Django
│ ├── pyproject.toml # Proyecto uv + dependencias
│ ├── requirements.txt # Dependencias pip (alternativa)
│ ├── Dockerfile # Imagen del servidor
│ ├── docker-compose.yml # Servicio del servidor en el puerto 8000
│ ├── MarketPlace/ # Paquete del proyecto Django
│ │ ├── settings.py # Configuración global (apps, BD, Stripe, logging)
│ │ ├── urls.py # Router raíz (todos los endpoints)
│ │ ├── views.py # Todas las vistas de la plataforma
│ │ ├── models.py # Product, UserProfile, Location, Favorite, Order, ShoppingCart
│ │ ├── forms.py # Formularios Django
│ │ ├── admin.py # Registro en el admin de Django
│ │ ├── error_views.py # Handlers 400 / 403 / 404 / 500
│ │ └── error_handlers.py # Middleware de errores
│ ├── services/ # Integraciones externas
│ │ ├── stripe_service.py # Configuración de Stripe
│ │ └── supabase.py # Cliente de Supabase (almacenamiento de imágenes)
│ ├── config_logs/ # Configuración centralizada de logging
│ ├── templates/ # HTML en servidor (main, product_detail, login, profile...)
│ └── static/ # CSS/JS de Bootstrap e imágenes
└── frontend/ # Maquetas HTML estáticas (referencia, no conectadas a la app)
```

## Modelo de datos

| Modelo | Propósito | Relaciones clave |
|--------|-----------|------------------|
| `UserProfile` | Extiende el `User` de Django; `is_premium` marca a un vendedor | 1:1 `User`, FK `Location`, M2M `Product` (favoritos) |
| `Location` | Ciudad / país de un usuario o producto | referenciado por `UserProfile` y `Product` |
| `Product` | Artículo publicado a la venta | FK `seller` (UserProfile), FK `Location` |
| `Order` | Compra completada (comprador ≠ vendedor) | FK `buyer`, FK `seller`, FK `product` |
| `Favorite` | Producto guardado | FK `UserProfile`, FK `Product` (únicos juntos) |
| `ShoppingCart` | Línea del carrito | FK `UserProfile`, FK `Product` (únicos juntos) |

> Se crea un `UserProfile` automáticamente para cada nuevo `User` mediante una señal `post_save`. Un usuario se convierte en **vendedor** cuando `is_premium = True` (tras el pago de upgrade).

## Endpoints de la API

| Ruta | Nombre | Propósito |
|------|--------|-----------|
| `/` | `main_page` | Catálogo de productos |
| `/product/<id>/` | `product_detail` | Página de detalle de producto |
| `/product/new/` | `create_product` | Crear una publicación |
| `/product/buy/<id>/` | `acquire_product` | Completar una compra |
| `/product/delete/<id>/` | `delete_product` | Eliminar una publicación |
| `/register/` · `/login/` · `/logout/` | auth | Acceso de cuenta |
| `/profile/` | `user_profile` | Compras, ventas y favoritos |
| `/profile/upgrade/` | `upgrade_to_seller` | Convertirse en vendedor |
| `/favorites/` · `/toggle-favorites/<id>/` | favoritos | Gestionar favoritos |
| `/shopping-cart/` · `/toggle-shopping-cart/<id>/` | carrito | Gestionar carrito |
| `/create-checkout-session/<id>/` | `create_checkout_session` | Checkout Stripe individual |
| `/create-multi-checkout/` | `create_multi_checkout` | Checkout Stripe múltiple |
| `/create-upgrade-session/` | `create_upgrade_session` | Checkout de upgrade a vendedor |
| `/about/` · `/contact/` · `/info/` | páginas estáticas | Páginas informativas |
| `/admin/` | — | Admin de Django |

---

## Puesta en marcha

### Requisitos

- **Python 3.12+**
- **[uv](https://docs.astral.sh/uv/)** (recomendado) — o pip
- **Make** (preinstalado en macOS/Linux; en Windows usa WSL o ejecuta los comandos sueltos)
- **Docker Desktop** (opcional)
- **Git**

Clona primero el repositorio:

```bash
git clone https://github.com/Bootcamp-IA-P6/MarketPlace.git
cd MarketPlace
```

### Ejecutar con Make (recomendado)

Desde la raíz del proyecto:

```bash
make dev
```

Esto instala las dependencias con uv, aplica las migraciones y arranca el servidor en **http://localhost:8000**.

### Ejecutar en macOS / Linux

```bash
cd backend
uv sync # crea .venv e instala dependencias
uv run python manage.py migrate # prepara la base de datos
uv run python manage.py runserver # arranca en http://localhost:8000
```

<details>
<summary>Sin uv (venv + pip clásico)</summary>

```bash
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
```
</details>

### Ejecutar en Windows

**PowerShell con uv (recomendado):**

```powershell
cd backend
uv sync
uv run python manage.py migrate
uv run python manage.py runserver
```

<details>
<summary>Sin uv (venv + pip clásico)</summary>

```powershell
cd backend
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
```
</details>

> `make` no está disponible en Windows por defecto. Usa los comandos de arriba o ejecuta el proyecto dentro de **WSL** para poder usar `make dev`.

### Ejecutar con Docker

Descarga y ejecuta la imagen publicada (sin clonar):

```bash
docker pull iruperth/looping:latest
docker run -d -p 8000:8000 iruperth/looping:latest
```

O constrúyela desde el código con Docker Compose:

```bash
cd backend
docker compose up --build # añade -d para ejecutarlo en segundo plano
docker compose down # detener
```

---

## Variables de entorno

Crea un archivo `backend/.env`. Para desarrollo local todo tiene un valor por defecto seguro, así que un archivo vacío/mínimo ya funciona (se usa SQLite y los pagos/almacenamiento quedan desactivados).

```env
# Django
DJANGO_SECRET_KEY=cambia-esto-en-produccion
DJANGO_DEBUG=True

# Base de datos — omítela para usar el respaldo SQLite local
DATABASE_URL=postgresql://user:password@host:5432/marketplace

# Stripe — déjalas vacías para desactivar los pagos reales
STRIPE_PUBLIC_KEY=pk_test_xxx
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx

# Supabase — déjalas vacías para desactivar la subida de imágenes
SUPABASE_URL=https://tu-proyecto.supabase.co
SUPABASE_SERVICE_ROLE_KEY=tu-service-role-key
```

| Variable | Obligatoria | Por defecto / efecto |
|----------|-------------|----------------------|
| `DJANGO_SECRET_KEY` | En producción | Clave de desarrollo insegura si no se define |
| `DJANGO_DEBUG` | No | `True` en desarrollo local |
| `DATABASE_URL` | En producción | SQLite (`db.sqlite3`) si no se define |
| `STRIPE_PUBLIC_KEY` | Para pagos | Placeholder de test si no se define |
| `STRIPE_SECRET_KEY` | Para pagos | Vacía → checkout desactivado |
| `STRIPE_WEBHOOK_SECRET` | Para webhooks | Vacía |
| `SUPABASE_URL` | Para subir imágenes | Vacía → almacenamiento desactivado |
| `SUPABASE_SERVICE_ROLE_KEY` | Para subir imágenes | Vacía → almacenamiento desactivado |

## Comandos de Make

```bash
make help # lista todos los targets disponibles
make install # crea el entorno virtual e instala dependencias (uv sync)
make dev # install + migrate + arranca el servidor de desarrollo
make run # arranca el servidor (sin sync / migrate)
make migrate # aplica las migraciones de la base de datos
make makemigrations # genera nuevas migraciones
make superuser # crea un usuario administrador de Django
make shell # abre la shell de Django
make collectstatic # recopila los archivos estáticos
make test # ejecuta los tests
make clean # elimina archivos de cache de Python
make docker-up # docker compose up --build
make docker-down # docker compose down
```

## Hoja de ruta

- Chat en tiempo real entre compradores y vendedores
- Promoción de pago opcional para destacar productos en lo alto del marketplace
- Cupones de descuento para compradores frecuentes
- Notificaciones automáticas de pedidos, mensajes de chat y alertas de bajo stock
- Objetivo a largo plazo: aplicación móvil nativa

## Contribuir

Damos la bienvenida a contribuciones para mejorar Looping Marketplace. Si quieres colaborar, abre un pull request y nuestro equipo lo revisará.

---

<p align="center">
<img src="backend/static/images/suuuu2.png" alt="Looping Marketplace" width="600">
</p>
Loading
Loading