e500bd7a8448f4b08b40409f7850b0e82bd6e9b8
El carrito enseñaba PD/PV aunque eligieras tarjeta, y por defecto ya presuponía saldo. Ahora se muestran SIEMPRE las dos monedas y se apaga la que no se va a cobrar con el método elegido, así que no presupone nada ni se contradice. Los euros por línea van con hasta 3 decimales a propósito: un ítem en PV con precio impar cuesta medio céntimo (75 PV = 0,375 €), y redondear cada línea a 2 haría que las líneas no sumaran el total (0,38 + 0,38 = 0,76 contra un total de 0,75). El total sí va a céntimos: es el importe que se cobra de verdad. Y con mínimo 2 decimales, que es dinero: "1,50 €", no "1,5 €". El formateo va por Intl con el locale de la web, así que en español sale con coma; antes el selector interpolaba el número crudo y decía "0.75 €" con punto. Mínimos de las pasarelas: SumUp ya estaba en 1 € y Stripe estaba en 0,50 €, ahora también 1 €. Estaban sueltos en la ruta; se centralizan en `lib/store-pricing`, un módulo PURO que importan tanto la ruta como el componente, para que el carrito enseñe exactamente lo que se valida y se cobra. `storeEuroTotal` pasa a vivir ahí (una sola implementación) y lib/store lo envuelve con un guard: si alguien cambia PD_PER_UNIT o VP_PRICE_FACTOR sin tocar store-pricing, revienta al primer uso en vez de cobrar mal en silencio (esos módulos tocan BD y no pueden llegar al bundle del cliente, de ahí la duplicación, igual que en PaymentMethodSelect). Por debajo del mínimo, la opción de tarjeta se desactiva y dice "Mínimo 1,00 €" en vez de dejarte pulsar Enviar para que la API la rechace. El método efectivo se deriva en el render (si el carrito baja del mínimo con tarjeta ya elegida, cae al saldo) en vez de sincronizarlo con un setState en un efecto, que provocaría renders en cascada. Verificado en el navegador: con 0,375 € las dos tarjetas salen desactivadas y elegido el saldo; con 1,50 € se habilitan. Las dos líneas de 0,375 € suman el total de 0,75 €. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nova WoW
Portal web (Django) para un servidor de World of Warcraft basado en AzerothCore.
- Python: 3.14
- Framework: Django 6.0
- Base de datos: MySQL (4 bases: la del portal
django_wow+ las de AzerothCoreacore_auth,acore_characters,acore_world)
1. Requisitos
- Python 3.14 y
venv - MySQL/MariaDB accesible
- Librerías de sistema para compilar algunas dependencias:
sudo apt install python3.14-venv python3.14-dev build-essential pkg-config \
default-libmysqlclient-dev libgmp-dev libmpfr-dev libmpc-dev libjpeg-dev zlib1g-dev
2. Puesta en marcha (desarrollo)
git clone https://git.nightspire.gg/Inna/NovaWoW.git
cd NovaWoW
# Entorno virtual
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
# Variables de entorno
cp .env.example .env
# edita .env con tus credenciales reales (ver sección 3)
# Migraciones y arranque
python manage.py migrate
python manage.py createsuperuser # opcional
python manage.py runserver
La app queda en http://127.0.0.1:8000
3. Configuración (.env)
Toda la configuración sensible se lee de variables de entorno mediante
python-dotenv. Copia .env.example
a .env y rellena los valores. El .env no se versiona.
| Variable | Descripción |
|---|---|
DJANGO_SECRET_KEY |
Clave secreta de Django. Genera una nueva (ver abajo). |
DJANGO_DEBUG |
True en desarrollo, False en producción. |
DB_USER / DB_PASSWORD |
Credenciales MySQL (compartidas por las 4 BBDD). |
DB_HOST / DB_PORT |
Host y puerto de MySQL. |
DB_NAME_DEFAULT |
BD del portal (por defecto django_wow). |
DB_NAME_AUTH / DB_NAME_CHARACTERS / DB_NAME_WORLD |
BBDD de AzerothCore. |
AC_SOAP_* |
Conexión SOAP a AzerothCore (crear cuentas, etc.). |
SUMUP_* / STRIPE_* |
Pasarelas de pago. |
EMAIL_HOST_USER / EMAIL_HOST_PASSWORD |
SMTP de Gmail (App Password). |
Generar una SECRET_KEY nueva:
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
4. Producción
# Recopilar estáticos
python manage.py collectstatic --noinput
# Servir con gunicorn (4 workers)
gunicorn novawow.wsgi:application --bind 0.0.0.0:8000 --workers 4
Recomendaciones:
DJANGO_DEBUG=Falsey unaDJANGO_SECRET_KEYpropia y secreta.- Poner Nginx delante como proxy inverso y para servir
staticfiles/. - Revisar
ALLOWED_HOSTSyCSRF_TRUSTED_ORIGINSennovawow/settings.py.
5. Docker
Alternativamente, se puede levantar todo con Docker (web + MySQL):
cp .env.example .env # ajusta los secretos (no las variables DB_*, las fija compose)
docker compose up --build
- La web queda en http://127.0.0.1:8000
- El servicio
dbcrea automáticamente las 4 bases de datos. - El
entrypointespera a MySQL, aplica migraciones y recopila estáticos antes de arrancar gunicorn.
Ver docker-compose.yml y Dockerfile para los detalles.
6. Notas de seguridad
- Los secretos que estuvieron hardcodeados en el historial de git deben rotarse (contraseña MySQL/SOAP, App Password de Gmail, claves de Stripe/SumUp).
- Nunca subas el archivo
.enval repositorio.
Description
Languages
Macaulay2
97.3%
TypeScript
2.3%
CSS
0.3%