<?php
namespace App\Entity;
use App\Command\DatabaseCleanups;
use App\Utility\GuidUtility;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* Activity Monitoring Events: track what users do in order to decide if their behaviour is problematic and should be reported.
*
* While Business-, Application-, and Webrequest-Events are tracked for statistical use in the Data Warehouse, and Usage
* Events used to change the platform behaviour according to a user's behaviour, Activity Monitoring Events are collected
* to decide if a given user misuses or overuses the platform, which triggers an alarm.
*
* Usage and Activity Monitoring Events look very similar at first glance, but have some important differences and serve
* very different purposes:
*
* - Usage Events are much leaner - instead of writing a new event entry for every relevant action the user takes, we
* only store the info *that* he did something *at least* once, and merely update a counter if the action is repeated.
* This is because most of the time, decisions that are based on Usage Events only need to know if a user not yet did
* something, already did something, and sometimes, how often and when they did it the last time. In other words,
* this is a very *qualitative* perspective
*
* - Activity Monitoring Events, on the other hand, provide a much more *quantitative* perspective. Because we need to
* know if a user over-uses the platform, we need to know *how often* a user did something in a certain *time frame*.
* For example, while writing many conversation messages is fine, writing a thousand conversation messages within the
* last 24 hours would be considered over-use.
*
* In order to answer these "how often did user X do action Y in timeframe Z?" questions, we need to keep track of every
* single occurrence of the action, while for Usage Events, it's sufficient to only increase a counter.
*
* Also, Activity Monitoring is more short-lived; we normally won't be interested in tracking user behaviour over more
* than a couple of weeks, because alarming is based on misbehaviour during timeframes of hours or days. This is why
* old Activity Monitoring Events can be wiped on a regular base via @see DatabaseCleanups, which mitigates the
* disadvantage of their large data volume a bit.
*
* On the other hand, we generally keep Usage Events forever (or at least, until the related User is removed), because
* we need the answers they provide all the time - which is no problem data volume wise, because Usage Events are very
* lean.
*
* @ORM\Entity()
*
* @ORM\Table(
* name="activity_monitoring_events",
* indexes={
*
* @ORM\Index(name="timerange_search_idx", columns={"users_id", "event_type", "occurred_at"})
* }
* )
*/
class ActivityMonitoringEvent
{
public const EVENT_TYPE_CONVERSATION_MESSAGE_SENT_BY_USER = 1;
public const EVENT_TYPE_SEARCH_STARTED = 2;
/**
* @var string
*
* @ORM\GeneratedValue(strategy="CUSTOM")
*
* @ORM\CustomIdGenerator(class="App\Utility\DatabaseIdGenerator")
*
* @ORM\Column(name="id", type="guid")
*
* @ORM\Id
*/
protected $id;
public function getId()
{
return $this->id;
}
public function setId(string $id): void
{
GuidUtility::validOrThrow($id);
$this->id = $id;
}
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="App\Entity\User", cascade={"persist"})
*
* @ORM\JoinColumn(name="users_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $user;
public function getUser(): User
{
return $this->user;
}
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @var int
*
* @ORM\Column(name="event_type", type="smallint", nullable=false)
*/
protected $eventType;
public function getEventType(): int
{
return $this->eventType;
}
public function setEventType(int $eventType): void
{
$this->eventType = $eventType;
}
/**
* @var DateTime
*
* @ORM\Column(name="occurred_at", type="datetime", nullable=false)
*/
protected $occurredAt;
public function getOccurredAt(): DateTime
{
return $this->occurredAt;
}
public function setOccurredAt(DateTime $occurredAt): void
{
$this->occurredAt = $occurredAt;
}
}