CompanyEvent


Evento gamificado que una compañía monta para sus clientes. Hoy el único tipo es coupon_gen: un sorteo en el que el cliente "agita" (endpoint events/shake) y puede ganar un cupón según las probabilidades configuradas.

Ciclo de vida y estados

Estado Cómo se llega Se puede
pending Al crear el evento. Editar (update), pasar a ready.
ready set-ready: fija starts_at/ends_at y valida la configuración. Volver a editar sólo si sigue pending.
running Automático al llegar starts_at. Participar (shake), pasar a finished.
finished set-finished, o automático al llegar ends_at. —

Sólo puede haber un evento running por compañía a la vez (EF408).

config

Objeto JSON; el trait de configuración lo expone además en accesores config_*. Claves visibles y editables:

Clave Descripción
winner_message Mensaje al ganador. Admite los marcadores $1 y $2 (valor y detalle del cupón).
already_won_message Mensaje cuando el cliente ya había ganado antes.
loser_message Mensaje cuando no gana.
coupon_seeds Semillas de los cupones a repartir (CouponSeed: max_count, win_rate, valor, mínimo de compra, ventana de disponibilidad, ...).
random_length Tamaño del espacio aleatorio; junto con win_rate de cada semilla fija la probabilidad de ganar.
expires_at Caducidad de los cupones generados.

Estructura de Datos

Atributo Tipo Descripción
id int
name string Nombre del evento.
type string Tipo de evento; hoy sólo coupon_gen.
status string Estado del evento: pending, ready, running o finished.
starts_at datetime\|null Inicio de la vigencia del evento.
ends_at datetime\|null Fin de la vigencia del evento.
config array Objeto JSON de configuración (ver tabla de claves arriba).
created_at datetime\|null Fecha de creación.
updated_at datetime\|null Fecha de última modificación.
deleted_at datetime\|null Fecha de borrado lógico.
company_id int Compañía dueña del evento (oculto en la respuesta).
allLogs ApiLog> Registros de auditoría de la API, incluidos los internos.
company Company Compañía dueña del evento.
config_already_won_message string Atajo de config.already_won_message.
config_coupon_seeds array\|null Atajo de config.coupon_seeds como lista de CouponSeed.
config_expires_at datetime\|null Atajo de config.expires_at.
config_loser_message string Atajo de config.loser_message.
config_random_length int\|null Atajo de config.random_length.
config_winner_message string Atajo de config.winner_message.
eventData CompanyEventData> Datos internos del evento (participaciones, tickets y ganadores).
logs ApiLog> Registros de auditoría de la API visibles.
{
    "id": 1,
    "name": "Navidad",
    "type": "coupon_gen",
    "status": "finished",
    "starts_at": "2020-12-17 20:10:53",
    "ends_at": null,
    "config": {
        "coupon_seeds": [
            {
                "win_rate": 50,
                "max_count": 12,
                "coupon_value_e2": 5,
                "coupon_min_purchase_e2": 0
            },
            {
                "win_rate": 10,
                "max_count": 5,
                "coupon_value_e2": 10,
                "coupon_min_purchase_e2": 0
            },
            {
                "win_rate": 5,
                "max_count": 2,
                "coupon_value_e2": 20,
                "coupon_min_purchase_e2": 0
            },
            {
                "win_rate": 1,
                "max_count": 1,
                "coupon_value_e2": 100,
                "coupon_min_purchase_e2": 0
            }
        ],
        "random_length": 100,
        "winner_message": "Felicidades! Has ganado <b></b>. Usa el código <b></b>",
        "expires_at": null,
        "loser_message": "Keep trying",
        "already_won_message": "Already won.  "
    },
    "created_at": "2020-12-17 20:09:59",
    "updated_at": "2020-12-19 15:30:57",
    "deleted_at": null
}

Endpoints

Insertar CompanyEvent

Crear un evento

Crea un CompanyEvent en estado pending (name, type, ventana opcional starts_at/ends_at y config).

Método URI Cabeceras
POST /companies/{companyId}/company-events Authorization
{
    "name": "required|string|max:64",
    "type": "required|string|in:coupon_gen",
    "starts_at": "date|after:now",
    "ends_at": "date|after:starts_at|after:now",
    "timezone": {
        "string": true,
        "regex": "/^[\+\-]([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
    },
    "config": {
        "coupon_seeds": [
            {
                "max_count": "required|integer|min:1",
                "coupon_value_e2": "integer|min:0",
                "coupon_value_prc": "numeric|between:0.0000,1.0000",
                "coupon_min_purchase_e2": "integer|min:0",
                "win_rate": "required|integer|min:1",
                "coupon_applies_to": "string|in:total,subtotal,base_price,service,delivery",
                "winner_message": "string|max:80",
                "already_won_message": "string|max:80",
                "available_since": "date",
                "available_until": "date"
            }
        ],
        "expires_at": "date|after:now",
        "random_length": "integer|min:1",
        "winner_message": "string|max:80",
        "already_won_message": "string|max:80",
        "loser_message": "string|max:80"
    }
}

Listar CompanyEvent

{info} Soporta: Paginación Filters Carga dinámica

Listar eventos

Devuelve los CompanyEvent de la compañía, paginados.

Método URI Cabeceras
GET /companies/{companyId}/company-events Authorization

Mostrar CompanyEvent

{info} Soporta: Carga dinámica

Ver un evento

Devuelve el CompanyEvent indicado.

Método URI Cabeceras
GET /companies/{companyId}/company-events/{companyEventId} Authorization

Actualizar CompanyEvent

Actualizar un evento

Modifica un CompanyEvent que siga en estado pending.

Método URI Cabeceras
PATCH /companies/{companyId}/company-events/{companyEventId} Authorization
{
    "name": "string|max:64",
    "type": "string|in:coupon_gen",
    "starts_at": "date|after:now",
    "ends_at": "date|after:starts_at|after:now",
    "timezone": {
        "string": true,
        "regex": "/^[\+\-]([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
    },
    "config": {
        "coupon_seeds": [
            {
                "max_count": "required|integer|min:1",
                "coupon_value_e2": "integer|min:0",
                "coupon_value_prc": "numeric|between:0.0000,1.0000",
                "coupon_min_purchase_e2": "integer|min:0",
                "win_rate": "required|integer|min:1",
                "coupon_applies_to": "string|in:total,subtotal,base_price,service,delivery",
                "winner_message": "string|max:80",
                "already_won_message": "string|max:80",
                "available_since": "date",
                "available_until": "date"
            }
        ],
        "expires_at": "date|after:now",
        "random_length": "integer|min:1",
        "winner_message": "string|max:80",
        "already_won_message": "string|max:80",
        "loser_message": "string|max:80"
    }
}

Errores de negocio

Código HTTP Cuándo ocurre
EF401 400 El evento no está en estado pending.

Acciones de CompanyEvent

Marcar un evento como listo

Pasa el CompanyEvent de pending a ready, fijando starts_at/ends_at (con timezone) y validando la configuración (semillas de cupón, probabilidades, fechas).

Método URI Cabeceras
POST /companies/{companyId}/company-events/{companyEventId}/set-ready Authorization
{
    "starts_at": "date|after:now",
    "ends_at": "date|after:starts_at|after:now",
    "timezone": {
        "string": true,
        "regex": "/^[\+\-]([0-1][0-9]|2[0-3]):[0-5][0-9]$/"
    }
}

Errores de negocio

Código HTTP Cuándo ocurre
EF401 400 El evento no está en estado pending.

Finalizar un evento

Pasa el CompanyEvent de running a finished; deja de aceptar participaciones.

Método URI Cabeceras
POST /companies/{companyId}/company-events/{companyEventId}/set-finished Authorization

Errores de negocio

Código HTTP Cuándo ocurre
EF405 400 El evento no está en estado running.

Participar en el evento activo

"Agita" el evento running de la compañía: registra la participación del usuario y devuelve el resultado (cupón ganado o mensaje de derrota). Si no hay ningún evento running responde {event: "none", result: "not_found"}.

Método URI Cabeceras
GET /companies/{companyId}/events/shake Authorization

Relaciones