Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
4c657e0
login-front
Gabriel-cuenk Oct 10, 2025
97260ea
login-register
Gabriel-cuenk Oct 10, 2025
d0b28db
.
Gabriel-cuenk Oct 11, 2025
ea95a05
DBINSTALL-sqLite
Gabriel-cuenk Oct 11, 2025
6fa55e3
.
Gabriel-cuenk Oct 11, 2025
2ea54a6
.
Gabriel-cuenk Oct 11, 2025
711d914
.
Gabriel-cuenk Oct 12, 2025
1ee63bd
feat(user): hash de password y modelo user_profiles
BenjaNeu Oct 12, 2025
a2e75ed
.
BenjaNeu Oct 12, 2025
43bdd74
.
BenjaNeu Oct 12, 2025
71d9dad
.
BenjaNeu Oct 12, 2025
0ef3f2f
.
BenjaNeu Oct 12, 2025
b7bd817
.
Gabriel-cuenk Oct 12, 2025
eaff4c8
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Oct 12, 2025
9b1b29f
.
BenjaNeu Oct 12, 2025
b565445
.
BenjaNeu Oct 12, 2025
ed1bcd0
.
BenjaNeu Oct 12, 2025
fd556af
.
Gabriel-cuenk Oct 13, 2025
74d4da0
.
Gabriel-cuenk Oct 13, 2025
2daaaa2
.
BenjaNeu Oct 15, 2025
2533bb4
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Oct 15, 2025
2b039cd
.
Gabriel-cuenk Oct 15, 2025
4eafb3b
Agrego .gitignore y limpio archivos ignorados
facusotelo Oct 15, 2025
5251b17
.
BenjaNeu Oct 16, 2025
f98b8b0
.
BenjaNeu Oct 16, 2025
21615d8
.
Gabriel-cuenk Oct 16, 2025
4a99433
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Oct 16, 2025
fb2414e
.
BenjaNeu Oct 16, 2025
e0e5287
.
BenjaNeu Oct 16, 2025
38d8b65
.
BenjaNeu Oct 16, 2025
102c9b6
.
BenjaNeu Oct 16, 2025
f5739fc
.
BenjaNeu Oct 16, 2025
492466e
Resolver conflicto: aceptar versión upstream de app.db.sqlite y mante…
Gabriel-cuenk Oct 16, 2025
af5f188
Restaurar versión local de app.db.sqlite desde backup app.db.sqlite.l…
Gabriel-cuenk Oct 16, 2025
0c59f1c
Agregar .gitignore para no trackear DBs SQLite en backend y remover a…
Gabriel-cuenk Oct 16, 2025
13409e1
.
BenjaNeu Oct 16, 2025
29a2702
.
BenjaNeu Oct 16, 2025
f039cc6
.
Gabriel-cuenk Oct 16, 2025
8443d00
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Oct 16, 2025
49e8398
.
Gabriel-cuenk Oct 16, 2025
005031e
....
BenjaNeu Oct 16, 2025
0a44643
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Oct 16, 2025
ba35eab
.
Gabriel-cuenk Oct 16, 2025
027e305
.
Gabriel-cuenk Oct 16, 2025
cf7782b
.
Gabriel-cuenk Oct 16, 2025
10a318e
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Oct 16, 2025
aba577d
.
BenjaNeu Oct 16, 2025
5604ea7
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Oct 16, 2025
0cab5a4
.
Gabriel-cuenk Oct 16, 2025
a1dcdae
.
BenjaNeu Oct 17, 2025
65e9cf4
.
BenjaNeu Oct 17, 2025
bed89f7
.
Gabriel-cuenk Oct 17, 2025
8e7ea7e
.
Gabriel-cuenk Oct 17, 2025
2071abb
.
Gabriel-cuenk Oct 17, 2025
f46f4b1
.
BenjaNeu Oct 17, 2025
4770e6a
.
Gabriel-cuenk Oct 17, 2025
1d79522
.
BenjaNeu Oct 17, 2025
abb9f0d
.
Gabriel-cuenk Oct 17, 2025
0f87882
.
Gabriel-cuenk Oct 17, 2025
e17693e
.
Gabriel-cuenk Oct 17, 2025
1d635c0
.
Gabriel-cuenk Oct 17, 2025
ca54dd7
.
Gabriel-cuenk Oct 17, 2025
efab428
.
Gabriel-cuenk Oct 17, 2025
c307545
.
BenjaNeu Oct 17, 2025
6d6ef95
..
BenjaNeu Oct 17, 2025
51843e1
.
BenjaNeu Oct 17, 2025
9395d73
.
BenjaNeu Oct 17, 2025
7668c3f
.
Gabriel-cuenk Oct 17, 2025
79d55a1
.
Gabriel-cuenk Oct 17, 2025
7c50aef
Remove .pyc conflicts
Gabriel-cuenk Oct 17, 2025
aec1ecf
.
Gabriel-cuenk Oct 17, 2025
126bed0
.
Gabriel-cuenk Oct 19, 2025
31b16c2
.
Gabriel-cuenk Oct 19, 2025
a62a613
.
Gabriel-cuenk Oct 19, 2025
7c2d1f8
.
Gabriel-cuenk Oct 23, 2025
5faabed
.
Gabriel-cuenk Oct 23, 2025
61dc065
.
Gabriel-cuenk Oct 23, 2025
d781ef9
.
BenjaNeu Oct 23, 2025
9e05d62
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Oct 23, 2025
91531af
.
Gabriel-cuenk Nov 20, 2025
87083cf
.
BenjaNeu Nov 20, 2025
12090dd
.
BenjaNeu Nov 24, 2025
55a31c4
.
Gabriel-cuenk Nov 24, 2025
022ce39
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Nov 24, 2025
a90840b
.
Gabriel-cuenk Nov 24, 2025
426b8f1
.
Gabriel-cuenk Nov 24, 2025
14181a4
.
BenjaNeu Nov 24, 2025
f6ebf4d
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Nov 24, 2025
a6b9436
.
BenjaNeu Nov 24, 2025
ff87adb
.
BenjaNeu Nov 24, 2025
ed2d4dc
.
Gabriel-cuenk Nov 24, 2025
34a07b7
.
Gabriel-cuenk Nov 25, 2025
4e2cc34
.
Gabriel-cuenk Nov 25, 2025
4296414
.
BenjaNeu Nov 25, 2025
f2366e0
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Nov 25, 2025
5c65a1f
.
Gabriel-cuenk Nov 25, 2025
830f778
.
Gabriel-cuenk Nov 27, 2025
bf73953
.
Gabriel-cuenk Nov 28, 2025
5b10c4e
.
Gabriel-cuenk Nov 28, 2025
f8eb7ba
.
Gabriel-cuenk Nov 30, 2025
1a53f5f
.
BenjaNeu Nov 30, 2025
f88ad86
.
Gabriel-cuenk Nov 30, 2025
857fc7f
.
Gabriel-cuenk Nov 30, 2025
83f7dd0
.
BenjaNeu Dec 1, 2025
5da9a3f
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Dec 1, 2025
e71fbea
.
BenjaNeu Dec 1, 2025
1e39b09
.
Gabriel-cuenk Dec 1, 2025
78852b8
.
Gabriel-cuenk Dec 1, 2025
5fe5e88
.
Gabriel-cuenk Dec 4, 2025
ee58f98
.
BenjaNeu Dec 4, 2025
51ab59f
.
BenjaNeu Dec 4, 2025
2744cb5
.
BenjaNeu Dec 4, 2025
562d895
.
Gabriel-cuenk Dec 4, 2025
9243472
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Dec 4, 2025
d39a5f0
.
Gabriel-cuenk Dec 4, 2025
b029a20
.
BenjaNeu Dec 4, 2025
9ede523
.
Gabriel-cuenk Dec 4, 2025
6da56a5
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Dec 4, 2025
7506aad
.
Gabriel-cuenk Dec 4, 2025
16d2b99
.
BenjaNeu Dec 4, 2025
47b28e0
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
BenjaNeu Dec 4, 2025
dfae993
.
Gabriel-cuenk Dec 4, 2025
c7c0833
Merge branch 'develop' of https://github.com/FRRe-DS/2025-13-TPI into…
Gabriel-cuenk Dec 4, 2025
031acf3
.
Gabriel-cuenk Dec 4, 2025
2f6fc2f
.
Gabriel-cuenk Dec 4, 2025
26b137e
.-
BenjaNeu Dec 4, 2025
cc89e72
.
BenjaNeu Dec 4, 2025
6b6410c
.
BenjaNeu Dec 4, 2025
d94b51b
.
BenjaNeu Dec 4, 2025
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
43 changes: 43 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# === Entornos virtuales ===
.venv/
venv/

# === Archivos de compilación ===
__pycache__/
*.pyc
*.pyo
*.pyd
*.py[cod]

# === VS Code y PyCharm ===
.vscode/
.idea/

# === Logs y cachés ===
*.log
*.pot
*.pyc
*.pyo
*.pyd
*.sqlite3
*.db
*.pid
*.gz
*.egg-info/
.mypy_cache/
.pytest_cache/
.coverage
.env
htmlcov/

# === Sistema operativo ===
.DS_Store
Thumbs.db

# === Node (frontend) ===
node_modules/
.env
.env.local
.next/
dist/
build/
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
# 🛒 TPI - Grupo 13
**Desarrollo de Software 2025 - UTN FRRe**
# 🛒 TPI - Grupo 13

**Desarrollo de Software 2025 - UTN FRRe**

En construccion...

📌 Descripción
📌 Descripción
Este proyecto corresponde al Trabajo Práctico Integrador (TPI) de la cátedra **Desarrollo de Software**.
El objetivo es desarrollar un sistema de compras online compuesto por diferentes subsistemas (Compras, Stock, Logística), implementando APIs REST y comunicación entre servicios.
El objetivo es desarrollar un sistema de compras online compuesto por diferentes subsistemas (Compras, Stock, Logística), implementando APIs REST y comunicación entre servicios.

Nuestro grupo se encuentra a cargo del subsistema **Compras**.
Nuestro grupo se encuentra a cargo del subsistema **Compras**.

---

⚙️ Tecnologías principales
⚙️ Tecnologías principales

Backend
- [Python 3.11+](https://www.python.org/)
- [FastAPI](https://fastapi.tiangolo.com/) → framework para construir APIs rápidas y seguras.
- [Uvicorn](https://www.uvicorn.org/) → servidor ASGI para correr la app FastAPI.
- [JWT](https://jwt.io/) → autenticación de usuarios.
- Base de datos (a definir: PostgreSQL/MySQL/SQLite).
Backend

### Frontend
- [React](https://react.dev/)
- [Next.js](https://nextjs.org/) → framework para React con SSR/SSG.
- [TailwindCSS](https://tailwindcss.com/) → estilos rápidos y modernos.
- [Python 3.11+](https://www.python.org/)
- [FastAPI](https://fastapi.tiangolo.com/) → framework para construir APIs rápidas y seguras.
- [Uvicorn](https://www.uvicorn.org/) → servidor ASGI para correr la app FastAPI.
- [JWT](https://jwt.io/) → autenticación de usuarios.
- Base de datos [SQLite] - [SqlAlquemi] para migraciones [alembic] - [pydantic]

---
### Frontend

📂 Estructura del repositorio
- [React](https://react.dev/)
- [Next.js](https://nextjs.org/) → framework para React con SSR/SSG.
- [TailwindCSS](https://tailwindcss.com/) → estilos rápidos y modernos.

---

📂 Estructura del repositorio
Binary file added compras/.gitignore
Binary file not shown.
9 changes: 9 additions & 0 deletions compras/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__pycache__/
*.pyc
*.pyo
*.log
venv/
.env
*.db
.idea/
.vscode/
27 changes: 27 additions & 0 deletions compras/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Imagen base oficial de Python
FROM python:3.12-slim

# Directorio de trabajo dentro del contenedor
WORKDIR /app

# Evita que Python guarde archivos .pyc
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Instala dependencias del sistema necesarias
RUN apt-get update && apt-get install -y build-essential

# Copiamos el archivo de requerimientos
COPY requirements.txt .

# Instalamos las dependencias de Python
RUN pip install --no-cache-dir -r requirements.txt

# Copiamos el resto del proyecto
COPY . .

# Exponemos el puerto donde corre FastAPI
EXPOSE 8000

# Comando para ejecutar la app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
147 changes: 147 additions & 0 deletions compras/backend/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# A generic, single database configuration.

[alembic]
# path to migration scripts.
# this is typically a path given in POSIX (e.g. forward slashes)
# format, relative to the token %(here)s which refers to the location of this
# ini file
script_location = %(here)s/alembic

# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
# Uncomment the line below if you want the files to be prepended with date and time
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
# for all available tokens
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory. for multiple paths, the path separator
# is defined by "path_separator" below.
prepend_sys_path = .


# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the tzdata library which can be installed by adding
# `alembic[tz]` to the pip requirements.
# string value is passed to ZoneInfo()
# leave blank for localtime
# timezone =

# max length of characters to apply to the "slug" field
# truncate_slug_length = 40

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false

# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false

# version location specification; This defaults
# to <script_location>/versions. When using multiple version
# directories, initial revisions must be specified with --version-path.
# The path separator used here should be the separator specified by "path_separator"
# below.
# version_locations = %(here)s/bar:%(here)s/bat:%(here)s/alembic/versions

# path_separator; This indicates what character is used to split lists of file
# paths, including version_locations and prepend_sys_path within configparser
# files such as alembic.ini.
# The default rendered in new alembic.ini files is "os", which uses os.pathsep
# to provide os-dependent path splitting.
#
# Note that in order to support legacy alembic.ini files, this default does NOT
# take place if path_separator is not present in alembic.ini. If this
# option is omitted entirely, fallback logic is as follows:
#
# 1. Parsing of the version_locations option falls back to using the legacy
# "version_path_separator" key, which if absent then falls back to the legacy
# behavior of splitting on spaces and/or commas.
# 2. Parsing of the prepend_sys_path option falls back to the legacy
# behavior of splitting on spaces, commas, or colons.
#
# Valid values for path_separator are:
#
# path_separator = :
# path_separator = ;
# path_separator = space
# path_separator = newline
#
# Use os.pathsep. Default configuration used for new projects.
path_separator = os

# set to 'true' to search source files recursively
# in each "version_locations" directory
# new in Alembic version 1.10
# recursive_version_locations = false

# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8

# database URL. This is consumed by the user-maintained env.py script only.
# other means of configuring database URLs may be customized within the env.py
# file.
sqlalchemy.url = driver://user:pass@localhost/dbname


[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples

# format using "black" - use the console_scripts runner, against the "black" entrypoint
# hooks = black
# black.type = console_scripts
# black.entrypoint = black
# black.options = -l 79 REVISION_SCRIPT_FILENAME

# lint with attempts to fix using "ruff" - use the module runner, against the "ruff" module
# hooks = ruff
# ruff.type = module
# ruff.module = ruff
# ruff.options = check --fix REVISION_SCRIPT_FILENAME

# Alternatively, use the exec runner to execute a binary found on your PATH
# hooks = ruff
# ruff.type = exec
# ruff.executable = ruff
# ruff.options = check --fix REVISION_SCRIPT_FILENAME

# Logging configuration. This is also consumed by the user-maintained
# env.py script only.
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARNING
handlers = console
qualname =

[logger_sqlalchemy]
level = WARNING
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
1 change: 1 addition & 0 deletions compras/backend/alembic/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
100 changes: 100 additions & 0 deletions compras/backend/alembic/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool
from sqlalchemy import create_engine

from alembic import context
import os
import sys

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Asegurar que el paquete `app` sea importable cuando Alembic ejecute env.py
here = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if here not in sys.path:
sys.path.insert(0, here)

# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
try:
# Intentamos importar Base desde la configuración de la aplicación.
from app.db import Base, DATABASE_URL

target_metadata = Base.metadata
except Exception:
target_metadata = None

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.

This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.

Calls to context.execute() here emit the given string to the
script output.

"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)

with context.begin_transaction():
context.run_migrations()


def run_migrations_online() -> None:
"""Run migrations in 'online' mode.

In this scenario we need to create an Engine
and associate a connection with the context.

"""
# Obtener URL desde alembic.ini; si está en placeholder, usar la URL definida en app.db
db_url = config.get_main_option("sqlalchemy.url")
if not db_url or db_url.startswith("driver://"):
try:
from app.db import DATABASE_URL as app_database_url

db_url = app_database_url
except Exception:
raise RuntimeError(
"No se pudo determinar sqlalchemy.url. Configura sqlalchemy.url en alembic.ini o define DATABASE_URL en app.db"
)

connectable = create_engine(db_url, poolclass=pool.NullPool)

with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)

with context.begin_transaction():
context.run_migrations()


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
Loading