Skip to content

OM-524: Solicitud de banners promocionales por comercios - #197

Merged
CrisNAC merged 2 commits into
devfrom
OM-524-FS-Solicitud-de-banners-promocionales-por-comercios
Jun 4, 2026
Merged

CrisNAC merged 2 commits into
devfrom
OM-524-FS-Solicitud-de-banners-promocionales-por-comercios

Conversation

@josediaz33

@josediaz33 josediaz33 commented Jun 4, 2026 •

Copy link
Copy Markdown
Collaborator

Schema Prisma: Se agregaron 3 campos al modelo Banners existente: fk_store (FK opcional a Stores), approval_status (enum ApprovalStatus, default PENDING) y rejection_reason. image_url pasó a opcional. Se registró la relación inversa en Stores.

Nuevo módulo commerce/banner-requests: Los comercios (SELLER) pueden crear solicitudes de banner, ver su historial filtrado por estado y cancelar solicitudes pendientes.

POST /api/stores/:storeId/banner-requests
GET /api/stores/:storeId/banner-requests
DELETE /api/stores/:storeId/banner-requests/:requestId Extensión del módulo admin: El administrador puede revisar las solicitudes de comercios y aprobarlas o rechazarlas (con motivo obligatorio).

GET /api/admin/banners/requests
PATCH /api/admin/banners/requests/:id

Summary by CodeRabbit

  • New Features

    • Sistema de solicitudes de banners: comercios pueden crear, listar y cancelar solicitudes que quedan en estado pendiente hasta revisión.
    • Panel de administración: administradores pueden listar y procesar (aprobar/rechazar) solicitudes de banners.
  • Documentation

    • Esquemas OpenAPI/Swagger añadidos para describir creación, respuesta y listados paginados de BannerRequest.

Schema Prisma: Se agregaron 3 campos al modelo Banners existente: fk_store (FK opcional a Stores), approval_status (enum ApprovalStatus, default PENDING) y rejection_reason. image_url pasó a opcional. Se registró la relación inversa en Stores.

Nuevo módulo commerce/banner-requests: Los comercios (SELLER) pueden crear solicitudes de banner, ver su historial filtrado por estado y cancelar solicitudes pendientes.

POST /api/stores/:storeId/banner-requests
GET /api/stores/:storeId/banner-requests
DELETE /api/stores/:storeId/banner-requests/:requestId
Extensión del módulo admin: El administrador puede revisar las solicitudes de comercios y aprobarlas o rechazarlas (con motivo obligatorio).

GET /api/admin/banners/requests
PATCH /api/admin/banners/requests/:id
@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d91f1c4c-eeca-448d-91cb-46d5a8d0fb4c

📥 Commits

Reviewing files that changed from the base of the PR and between 52a50e0 and affd2e3.

📒 Files selected for processing (3)
  • src/modules/admin/banners/admin-banners.routes.js
  • src/modules/admin/banners/admin-banners.service.js
  • src/modules/commerce/banner-requests/banner-request.service.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/modules/admin/banners/admin-banners.routes.js
  • src/modules/admin/banners/admin-banners.service.js
  • src/modules/commerce/banner-requests/banner-request.service.js

📝 Walkthrough

Walkthrough

Agrega soporte de "banner requests": esquema (relación Banners ↔ Stores), documentación OpenAPI, rutas y controladores para vendedores (crear/listar/cancelar) y admin (listar/procesar aprobar/rechazar), con servicios que validan, persisten y gestionan estados de aprobación.

Cambios

Sistema de solicitudes de banners con aprobación

Layer / File(s) Resumen
Esquema de datos y documentación OpenAPI
prisma/schema.prisma, src/docs/schemas/commerce/banner-request.schema.js, src/docs/schemas/index.js
El modelo Banners se extiende con fk_store (relación opcional a Stores) y la relación inversa banner_requests en Stores. Se agregan esquemas OpenAPI para crear, responder y listar solicitudes con paginación y enum approvalStatus.
Configuración de rutas en aplicación
src/app.js
Se importa y monta el router de banner-requests bajo /api/stores/:storeId/banner-requests.
Endpoints de vendedores: crear, listar y cancelar
src/modules/commerce/banner-requests/banner-request.controller.js, src/modules/commerce/banner-requests/banner-request.routes.js, src/modules/commerce/banner-requests/banner-request.service.js
Controlador, rutas y servicios para que vendedores autenticados creen solicitudes (normalización y validación de título, URLs y fechas), las listan con filtro approval_status y paginación, y las cancelen si están en PENDING. Persisten en prisma.banners con approval_status: "PENDING" y is_active: false.
Endpoints de administrador: obtener y procesar decisiones
src/modules/admin/banners/admin-banners.controller.js, src/modules/admin/banners/admin-banners.routes.js, src/modules/admin/banners/admin-banners.service.js
Se agregan controladores, rutas y servicios para listar solicitudes (filtro y búsqueda) y procesar decisiones APPROVE/REJECT validando inputs y actualizando approval_status, is_active y rejection_reason. createAdminBannerService fija approval_status: "ACTIVE" para banners creados por admin.

Sequence Diagram(s):

sequenceDiagram
  participant Seller
  participant BannerRequestController
  participant BannerRequestService
  participant PrismaDB

  Seller->>BannerRequestController: POST /api/stores/:storeId/banner-requests
  BannerRequestController->>BannerRequestService: createBannerRequestService(payload)
  BannerRequestService->>PrismaDB: prisma.banners.create({fk_store, approval_status: "PENDING", is_active:false})
  PrismaDB-->>BannerRequestService: banner creado
  BannerRequestService-->>BannerRequestController: respuesta mapeada 201
  BannerRequestController-->>Seller: 201 Created
Loading
sequenceDiagram
  participant Admin
  participant AdminBannersController
  participant AdminBannersService
  participant PrismaDB

  Admin->>AdminBannersController: PATCH /api/admin/banners/requests/:id
  AdminBannersController->>AdminBannersService: processBannerRequestService(id, decision)
  AdminBannersService->>PrismaDB: updateMany where id & approval_status = PENDING
  alt decision = APPROVE
    PrismaDB-->>AdminBannersService: updated (approval_status=ACTIVE, is_active=true)
  else decision = REJECT
    PrismaDB-->>AdminBannersService: updated (approval_status=REJECTED, rejection_reason=...)
  end
  AdminBannersService-->>AdminBannersController: banner mapeado 200
  AdminBannersController-->>Admin: 200 OK
Loading

Esfuerzo estimado de revisión

🎯 4 (Complex) | ⏱️ ~45 minutes

PRs potencialmente relacionados

Revisores sugeridos

  • Andoumeda
  • leoAchu16

Poema

🐰 Soy un conejo con lupa y nogal,

vi banners pedir permiso al umbral,
vendedores crean, admins deciden con mimo,
en la pradera del código todo en buen ritmo. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed El título está completamente relacionado con el cambio principal: implementa un sistema de solicitud de banners promocionales por parte de comercios con flujo de aprobación administrativa.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch OM-524-FS-Solicitud-de-banners-promocionales-por-comercios

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@josediaz33

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@josediaz33 ¡Hola! Parece que me mencionaste pero no incluiste una solicitud específica. ¿En qué puedo ayudarte con este PR?

Aquí algunas cosas que puedo hacer:

  • Revisar los cambios del PR: @coderabbitai review
  • Aprobar el PR: @coderabbitai approve
  • Regenerar el resumen: @coderabbitai summary
  • Resolver comentarios: @coderabbitai resolve
  • Pausar revisiones automáticas: @coderabbitai pause
  • Responder preguntas sobre el código o la implementación.

¿Qué necesitas? 😊

(¯·.¸¸.·´¯·.¸¸.-> 🐰 <-.¸¸.·´¯`·.¸¸.·´¯)

@josediaz33

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/modules/admin/banners/admin-banners.routes.js`:
- Around line 170-176: OpenAPI paths and security in the swagger block are
inconsistent with the actual router: replace instances of the path string
'/api/admin/banner-requests' with '/api/admin/banners/requests' (and any other
mismatched path occurrences) and change the security scheme entries from
'bearerAuth' to 'cookieAuth' so they match the admin module's router; update all
occurrences referenced (the blocks around the existing path and security
entries) so the documented path and auth exactly mirror the real routes.

In `@src/modules/admin/banners/admin-banners.service.js`:
- Around line 302-305: The code uses a non-atomic check-then-update
(prisma.banners.findFirst) that allows race conditions when two admins act
concurrently; replace the findFirst + separate update with a single conditional
update (e.g., prisma.banners.updateMany or prisma.banners.update with a WHERE
that includes id_banner: id, fk_store: { not: null }, status: true and
approval_status: 'PENDING') and then check the returned count/rowsAffected to
determine if the update actually applied (if count === 0, return/conflict
because another process already handled it). Update the logic in the
admin-banners service around the existing prisma.banners.findFirst / subsequent
update calls so the change is done atomically and handle the no-op result as a
race-condition conflict.

In `@src/modules/commerce/banner-requests/banner-request.service.js`:
- Around line 140-154: The cancel flow has a TOCTOU: you read the banner row
into request then update by id only, so it can be changed between operations;
make the cancel atomic by performing a conditional update that includes the
pending state and active status check (e.g. replace the separate
read+prisma.banners.update with a single conditional update like
prisma.banners.updateMany or a transactional update where the where includes
id_banner, fk_store, approval_status: "PENDING", status: true) and then verify
the affected count/result — if zero, throw the same
ValidationError/NotFoundError as appropriate; reference the existing request
variable, prisma.banners.update call, and the "PENDING" approval_status check
when making this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 02245937-3fab-4496-8dd7-2c1a2650bfec

📥 Commits

Reviewing files that changed from the base of the PR and between 50e6983 and 52a50e0.

📒 Files selected for processing (10)
  • prisma/schema.prisma
  • src/app.js
  • src/docs/schemas/commerce/banner-request.schema.js
  • src/docs/schemas/index.js
  • src/modules/admin/banners/admin-banners.controller.js
  • src/modules/admin/banners/admin-banners.routes.js
  • src/modules/admin/banners/admin-banners.service.js
  • src/modules/commerce/banner-requests/banner-request.controller.js
  • src/modules/commerce/banner-requests/banner-request.routes.js
  • src/modules/commerce/banner-requests/banner-request.service.js

Comment thread src/modules/admin/banners/admin-banners.routes.js Outdated
Comment thread src/modules/admin/banners/admin-banners.service.js Outdated
Comment thread src/modules/commerce/banner-requests/banner-request.service.js Outdated
@sonarqubecloud

sonarqubecloud Bot commented Jun 4, 2026

Copy link
Copy Markdown

@CrisNAC
CrisNAC merged commit a99f8cf into dev Jun 4, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants