Compare commits
No commits in common. "3e7e1f0aecb4588a37812d1718300951b5b8b7fd" and "2d484aa40ab9672527e1661466e3e8a50c7cd004" have entirely different histories.
3e7e1f0aec
...
2d484aa40a
267
README.md
267
README.md
@ -1,215 +1,92 @@
|
|||||||
# expenses_manager
|
# expenses_manager
|
||||||
|
|
||||||
Aplicación web de gestión de finanzas personales (gastos, ingresos, cuentas,
|
## Descripción
|
||||||
categorías, objetivos y repostajes de vehículo), construida con **Django** y
|
expenses_manager es una aplicación diseñada para ayudarte a gestionar tus gastos diarios. Fue creada con la intención de hacer que el seguimiento de finanzas personales sea más sencillo y eficiente.
|
||||||
desplegada en un NAS Synology mediante **Docker** + **PostgreSQL**.
|
|
||||||
|
|
||||||
## Características
|
## Uso Básico
|
||||||
|
La aplicación permite:
|
||||||
|
- Registrar ingresos y egresos.
|
||||||
|
- Visualizar tus gastos por categoría.
|
||||||
|
- Generar informes financieros mensuales y semanales.
|
||||||
|
|
||||||
- Registro de **gastos** e **ingresos**, con categorías jerárquicas y etiquetas.
|
## Índice
|
||||||
- **Cuentas** con cálculo de saldo (soft-delete para preservar históricos).
|
1. [Instalación](#instalación)
|
||||||
- **Dashboard** con gráficos por categoría, evolución de saldo y comparativas de periodo.
|
2. [Configuración](#configuración)
|
||||||
- **Objetivos** de tres tipos: pago/deuda, presupuesto (mensual/anual) y ahorro.
|
3. [Uso](#uso)
|
||||||
- Módulo de **repostajes** con cálculo de consumo, precio por litro y km recorridos.
|
|
||||||
|
|
||||||
## Stack
|
## Instalación
|
||||||
|
|
||||||
- Python 3.11 · Django 5.2
|
### Despliegue en Local
|
||||||
- PostgreSQL (producción) / SQLite (desarrollo local por defecto)
|
|
||||||
- Gunicorn + WhiteNoise
|
|
||||||
- Docker (despliegue) · Jenkins (CI)
|
|
||||||
|
|
||||||
---
|
#### Requisitos:
|
||||||
|
- Python 3.8 o superior.
|
||||||
|
- pip.
|
||||||
|
|
||||||
## Desarrollo local
|
#### Pasos:
|
||||||
|
1. Clona el repositorio usando Git:
|
||||||
Por defecto, en local la aplicación usa **SQLite**, así que no necesitas
|
|
||||||
levantar ninguna base de datos para empezar.
|
|
||||||
|
|
||||||
### Requisitos
|
|
||||||
|
|
||||||
- Python 3.11 (estos pasos asumen un entorno **conda**, pero sirve cualquier
|
|
||||||
entorno virtual).
|
|
||||||
|
|
||||||
### Pasos
|
|
||||||
|
|
||||||
1. Clona el repositorio:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://gitea.kuijper.es/jkuijperm/expenses_manager.git
|
|
||||||
cd expenses_manager
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Crea y activa el entorno conda:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
conda create -n gastos python=3.11
|
|
||||||
conda activate gastos
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Instala las dependencias:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
pip install -r expenses_manager/requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Crea el archivo `.env` (ver [Variables de entorno](#variables-de-entorno)).
|
|
||||||
Para desarrollo basta con:
|
|
||||||
|
|
||||||
```env
|
|
||||||
DEBUG=True
|
|
||||||
SECRET_KEY=cualquier-clave-para-desarrollo
|
|
||||||
```
|
|
||||||
|
|
||||||
Con `DEBUG=True` y sin variables `DB_*`, se usa SQLite automáticamente.
|
|
||||||
|
|
||||||
5. Aplica las migraciones y arranca el servidor:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd expenses_manager
|
|
||||||
python manage.py migrate
|
|
||||||
python manage.py runserver
|
|
||||||
```
|
|
||||||
|
|
||||||
6. Abre `http://127.0.0.1:8000/` en el navegador.
|
|
||||||
|
|
||||||
> **Datos de demostración (opcional):** con `DEBUG=True` puedes poblar la base
|
|
||||||
> de datos con un usuario y datos de ejemplo:
|
|
||||||
>
|
|
||||||
> ```sh
|
|
||||||
> python manage.py seed_demo
|
|
||||||
> ```
|
|
||||||
>
|
|
||||||
> El comando está protegido para no ejecutarse si `DEBUG=False`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Variables de entorno
|
|
||||||
|
|
||||||
La configuración se lee de un archivo `.env` (mediante `python-dotenv`) situado
|
|
||||||
en `expenses_manager/` (junto a `manage.py`). **Este archivo no se versiona.**
|
|
||||||
|
|
||||||
| Variable | Obligatoria | Por defecto | Descripción |
|
|
||||||
|---|---|---|---|
|
|
||||||
| `SECRET_KEY` | Sí en producción | — | Clave secreta de Django. Con `DEBUG=False` es obligatoria (si falta, la app no arranca). |
|
|
||||||
| `DEBUG` | No | `False` | `True` en desarrollo. Activa SQLite por defecto y desactiva el hardening. |
|
|
||||||
| `ALLOWED_HOSTS` | No | `localhost,127.0.0.1` | Lista separada por comas. |
|
|
||||||
| `CSRF_TRUSTED_ORIGINS` | No | (vacío) | Lista separada por comas (p. ej. `https://midominio.com`). |
|
|
||||||
| `DB_ENGINE` | No | `sqlite3` | `postgresql` para usar Postgres; cualquier otro valor usa SQLite. |
|
|
||||||
| `DB_NAME` | Con Postgres | — | Nombre de la base de datos. |
|
|
||||||
| `DB_USER` | Con Postgres | — | Usuario. |
|
|
||||||
| `DB_PASSWORD` | Con Postgres | — | Contraseña. |
|
|
||||||
| `DB_HOST` | No | `localhost` | Host de la base de datos (`db` en Docker Compose). |
|
|
||||||
| `DB_PORT` | No | `5432` | Puerto. |
|
|
||||||
|
|
||||||
En el repositorio hay un archivo **`.env.example`** con estas variables como
|
|
||||||
plantilla. Cópialo a `.env` y rellena los valores.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Despliegue con Docker
|
|
||||||
|
|
||||||
El despliegue en producción usa Docker con dos servicios: la aplicación Django
|
|
||||||
(servida por Gunicorn) y una base de datos PostgreSQL.
|
|
||||||
|
|
||||||
### Dockerfile
|
|
||||||
|
|
||||||
El `Dockerfile` está en el repositorio (`app/Dockerfile` en el árbol de
|
|
||||||
despliegue) y hace lo esencial: parte de `python:3.11-slim`, instala las
|
|
||||||
dependencias de `requirements.txt` y copia el código. A grandes rasgos:
|
|
||||||
|
|
||||||
```dockerfile
|
|
||||||
FROM python:3.11-slim
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1 \
|
|
||||||
PYTHONDONTWRITEBYTECODE=1
|
|
||||||
|
|
||||||
WORKDIR /app/expenses_manager
|
|
||||||
|
|
||||||
COPY expenses_manager/requirements.txt .
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
EXPOSE 8000
|
|
||||||
```
|
|
||||||
|
|
||||||
### docker-compose (no versionado)
|
|
||||||
|
|
||||||
El `docker-compose.yml` **no está en el repositorio**: es específico de la
|
|
||||||
infraestructura del NAS y vive fuera del proyecto. A continuación se documenta
|
|
||||||
qué debe contener, para poder reproducirlo. **Ningún secreto va escrito en el
|
|
||||||
archivo**: todos los valores sensibles se leen del `.env`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
db:
|
|
||||||
image: postgres:15
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: ${DB_NAME}
|
|
||||||
POSTGRES_USER: ${DB_USER}
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- ./postgres:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
web:
|
|
||||||
build: ./app
|
|
||||||
container_name: finanzas_web
|
|
||||||
command: gunicorn expenses_manager.wsgi:application --bind 0.0.0.0:8000
|
|
||||||
volumes:
|
|
||||||
- ./app:/app
|
|
||||||
ports:
|
|
||||||
- "8001:8000"
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
env_file:
|
|
||||||
- ./app/expenses_manager/.env
|
|
||||||
```
|
|
||||||
|
|
||||||
Notas:
|
|
||||||
|
|
||||||
- Las credenciales de Postgres (`DB_NAME`, `DB_USER`, `DB_PASSWORD`) las toma
|
|
||||||
Docker Compose de un `.env` situado **junto al `docker-compose.yml`**. Es un
|
|
||||||
archivo distinto del `.env` de Django (que va dentro del proyecto y lo carga
|
|
||||||
la propia app vía `env_file`).
|
|
||||||
- El servicio `web` no repite las variables de base de datos en un bloque
|
|
||||||
`environment`: las hereda del `.env` de Django a través de `env_file`.
|
|
||||||
|
|
||||||
### Puesta en marcha y actualizaciones
|
|
||||||
|
|
||||||
Desde el directorio que contiene el `docker-compose.yml`:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git -C app pull # traer los últimos cambios al repo montado
|
git clone https://gitea.kuijper.es/jkuijperm/expenses_manager.git
|
||||||
docker-compose down
|
|
||||||
docker-compose up -d --build
|
|
||||||
docker-compose exec web python manage.py migrate
|
|
||||||
docker-compose exec web python manage.py collectstatic --noinput
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- `migrate` solo es necesario si hay migraciones nuevas.
|
2. Navega al directorio del proyecto:
|
||||||
- `collectstatic` solo si han cambiado archivos estáticos (CSS/JS).
|
|
||||||
- **No** ejecutes `makemigrations` en producción: las migraciones se generan en
|
|
||||||
desarrollo y llegan versionadas con el `git pull`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
La suite usa `pytest` + `pytest-django`:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd expenses_manager
|
cd expenses_manager
|
||||||
pytest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
La integración continua (Jenkins) ejecuta los tests en cada cambio de la rama
|
3. Instala las dependencias necesarias:
|
||||||
`main`.
|
|
||||||
|
|
||||||
---
|
```sh
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
## Ramas
|
### Despliegue en Docker
|
||||||
|
|
||||||
- **`main`** — solo recibe cambios ya probados (vía merge desde `dev`).
|
#### Pasos:
|
||||||
- **`dev`** — rama de trabajo activa.
|
1. Clona el repositorio usando Git:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://gitea.kuijper.es/jkuijperm/expenses_manager.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Navega al directorio del proyecto:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd expenses_manager
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Construye la imagen Docker:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker build -t expenses_manager .
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Corre el contenedor:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run -p 5000:5000 expenses_manager
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuración
|
||||||
|
|
||||||
|
Después de clonar el repositorio y instalar las dependencias, puedes configurar la aplicación creando un archivo `.env` en el directorio raíz del proyecto con el siguiente contenido:
|
||||||
|
|
||||||
|
env
|
||||||
|
|
||||||
|
SECRET_KEY=mi_clave_secreta_única_y_segura
|
||||||
|
|
||||||
|
DATABASE_URL=sqlite:///expenses.db # Otra URL de base de datos si es necesario
|
||||||
|
|
||||||
|
## Uso
|
||||||
|
|
||||||
|
1. Inicia la aplicación:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Abre tu navegador y visita `http://localhost:5000` para acceder a la interfaz de usuario.
|
||||||
|
|
||||||
|
### Registro de Gastos
|
||||||
|
- Accede a la página de gastos y agrega nuevos registros manualmente o importa datos desde otras fuentes.
|
||||||
Loading…
Reference in New Issue
Block a user