feat: review received form submissions in the admin ui
This commit is contained in:
1 parent
f073a2014d
commit
cb2d64f2cd
19 files changed
+999
-7
No files matched your search
@@ -14,10 +14,13 @@ use Symfony\Component\Uid\Uuid;
|
||||
* first, other "collect it and let a human read it" forms later. Unrelated to
|
||||
* App\Entity\Application, which is a teamer applying for an assignment.
|
||||
*
|
||||
* Deliberately neither Blameable nor SoftDeletable: nothing in this application creates these
|
||||
* rows, and the retention rule for job applications asks for real deletion, so this is the one
|
||||
* entity here that gets an actual DELETE. A purge has to cover "details" and "payload" as
|
||||
* well - a json column is exactly what a deletion job forgets.
|
||||
* Deliberately neither Blameable nor SoftDeletable. Nothing here creates a row - TYPO3 does -
|
||||
* and the only thing staff write are the four follow-up dates, where the interesting fact is
|
||||
* that the mail went out or the call happened, not who ticked it off; who did is in the audit
|
||||
* log the mutating controllers write. No SoftDeletable because the retention rule for job
|
||||
* applications asks for real deletion, so this is the one entity here that gets an actual
|
||||
* DELETE. A purge has to cover "details" and "payload" as well - a json column is exactly what
|
||||
* a deletion job forgets.
|
||||
*
|
||||
* The typed columns are the mapped core agreed with the TYPO3 side and all nullable: a form is
|
||||
* configured without a field as often as with it. "details" is everything else the visitor
|
||||
@@ -86,14 +89,36 @@ class ApplicationFormSubmission implements TimestampableEntityInterface
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $city = null;
|
||||
|
||||
/**
|
||||
* The follow-up a reviewer works through after a submission arrived: two mails and two
|
||||
* phone calls, each stamped when it happened and null until it has. Staff state, never part
|
||||
* of the payload - fromDto() must not touch them.
|
||||
*
|
||||
* The mails carry a time because a send time is a machine fact and stays one once the
|
||||
* notification mail of §6 is automated. A held call does not: the reviewer records it
|
||||
* afterwards and knows the day, so storing an invented time would only look precise.
|
||||
*/
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
private ?\DateTimeImmutable $firstMailSentAt = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
private ?\DateTimeImmutable $secondMailSentAt = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
|
||||
private ?\DateTimeImmutable $firstCallHeldAt = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
|
||||
private ?\DateTimeImmutable $secondCallHeldAt = null;
|
||||
|
||||
/**
|
||||
* Everything the visitor filled in beyond the mapped core, keyed by the German field label.
|
||||
* Display only: the labels are staff-written and change on a reword, so nothing may query
|
||||
* this, build a column from it or migrate old rows to a new spelling (§3.3).
|
||||
*
|
||||
* Note the labels come back in MySQL's order, not the form's - a json column normalises an
|
||||
* object by sorting its keys by length. Render it in whatever order suits the reviewer; the
|
||||
* form's own order is still in $payload, which is read as one blob and never sorted by us.
|
||||
* The key order is whatever the engine hands back and is not part of what this carries: on
|
||||
* MariaDB (dev and production) JSON is an alias for LONGTEXT and the document survives
|
||||
* verbatim, on MySQL 8 an object is normalised and its keys come back sorted by length.
|
||||
* Render it in whatever order suits the reviewer rather than relying on either.
|
||||
*
|
||||
* @var array<string, string|bool|list<string>>
|
||||
*/
|
||||
@@ -309,6 +334,54 @@ class ApplicationFormSubmission implements TimestampableEntityInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstMailSentAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->firstMailSentAt;
|
||||
}
|
||||
|
||||
public function setFirstMailSentAt(?\DateTimeImmutable $firstMailSentAt): static
|
||||
{
|
||||
$this->firstMailSentAt = $firstMailSentAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSecondMailSentAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->secondMailSentAt;
|
||||
}
|
||||
|
||||
public function setSecondMailSentAt(?\DateTimeImmutable $secondMailSentAt): static
|
||||
{
|
||||
$this->secondMailSentAt = $secondMailSentAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstCallHeldAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->firstCallHeldAt;
|
||||
}
|
||||
|
||||
public function setFirstCallHeldAt(?\DateTimeImmutable $firstCallHeldAt): static
|
||||
{
|
||||
$this->firstCallHeldAt = $firstCallHeldAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSecondCallHeldAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->secondCallHeldAt;
|
||||
}
|
||||
|
||||
public function setSecondCallHeldAt(?\DateTimeImmutable $secondCallHeldAt): static
|
||||
{
|
||||
$this->secondCallHeldAt = $secondCallHeldAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string|bool|list<string>>
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user