Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 25 additions & 0 deletions .devcontainer/minio/public-assets/participation_report.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"execution_annotations": {
"date_printed": "2026-05-09T10:30:00+00:00",
"report_hash": "preview-report-hash",
"app_version": "preview",
"software_version": "preview",
"app_hash": "preview-app-hash",
"executer_username": "admin",
"results_hash": null
},
"participation": {
"scope": "election_event",
"tenant_id": "00000000-0000-0000-0000-000000000001",
"election_event_id": "00000000-0000-0000-0000-000000000002",
"election_id": null,
"election_event_name": "Election Event",
"election_name": null,
"generated_at": "2026-05-09T10:30:00+00:00",
"generated_timezone": "+00:00",
"total_voters": 1250,
"voted_voters": 895,
"participation_percentage": 71.6,
"votes_count": 910
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"pdf_options": {
"landscape": null,
"display_header_footer": null,
"print_background": true,
"scale": null,
"paper_width": null,
"paper_height": null,
"margin_top": null,
"margin_bottom": null,
"margin_left": null,
"margin_right": null,
"page_ranges": null,
"ignore_invalid_page_ranges": null,
"header_template": null,
"footer_template": null,
"prefer_css_page_size": null,
"transfer_mode": null
},
"report_options": {
"max_items_per_report": null,
"max_threads": null
},
"communication_templates": {
"email_config": {
"subject": "Participation Report",
"plaintext_body": "",
"html_body": null
},
"sms_config": {
"message": ""
}
}
}
104 changes: 104 additions & 0 deletions .devcontainer/minio/public-assets/participation_report_system.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{{!--
SPDX-FileCopyrightText: 2025 Sequent Tech Inc <legal@sequentech.io>

SPDX-License-Identifier: AGPL-3.0-only
--}}
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background: #ffffff;
color: #111111;
font-family: Arial, sans-serif;
margin: 0 auto;
max-width: 900px;
padding: 36px;
}

.report {
width: 100%;
}

.report-header {
border-bottom: 2px solid #111111;
margin-bottom: 28px;
padding-bottom: 16px;
}

.eyebrow {
font-size: 11px;
font-weight: bold;
letter-spacing: 0;
margin: 0 0 8px;
text-transform: uppercase;
}

h1 {
font-size: 24px;
line-height: 1.25;
margin: 0;
}

h2 {
font-size: 16px;
line-height: 1.35;
margin: 8px 0 0;
}

table {
border-collapse: collapse;
width: 100%;
}

th,
td {
border-bottom: 1px solid #d5d5d5;
font-size: 14px;
padding: 12px 10px;
text-align: left;
}

th {
font-weight: bold;
width: 45%;
}

td {
text-align: right;
}

.metadata {
color: #333333;
font-size: 11px;
margin-top: 32px;
word-break: break-word;
}

.metadata p {
margin: 4px 0;
}

.metadata span {
font-family: monospace;
}

@media print {
@page {
margin: 0.6in;
}

body {
font-size: 11px;
padding: 0;
}
}
</style>
</head>
<body>
{{{rendered_user_template}}}
</body>
</html>
52 changes: 52 additions & 0 deletions .devcontainer/minio/public-assets/participation_report_user.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{{!--
SPDX-FileCopyrightText: 2025 Sequent Tech Inc <legal@sequentech.io>

SPDX-License-Identifier: AGPL-3.0-only
--}}
<main class="report">
<header class="report-header">
<p class="eyebrow">Participation Report</p>
<h1>{{sanitize_html participation.election_event_name}}</h1>
{{#if participation.election_name}}
<h2>{{sanitize_html participation.election_name}}</h2>
{{/if}}
</header>

<section class="summary">
<table>
<tbody>
<tr>
<th>Total voters</th>
<td>{{format_u64 participation.total_voters}}</td>
</tr>
<tr>
<th>Voted voters</th>
<td>{{format_u64 participation.voted_voters}}</td>
</tr>
<tr>
<th>Participation</th>
<td>{{format_percentage participation.participation_percentage}}%</td>
</tr>
<tr>
<th>Votes</th>
<td>{{format_u64 participation.votes_count}}</td>
</tr>
<tr>
<th>Generated</th>
<td>{{datetime from_rfc3339=participation.generated_at output_format="%B %d, %Y %H:%M GMT %:z"}}</td>
</tr>
</tbody>
</table>
</section>

<section class="metadata">
<p>Tenant ID: <span>{{sanitize_html participation.tenant_id}}</span></p>
<p>Election event ID: <span>{{sanitize_html participation.election_event_id}}</span></p>
{{#if participation.election_id}}
<p>Election ID: <span>{{sanitize_html participation.election_id}}</span></p>
{{/if}}
<p>Report hash: <span>{{sanitize_html execution_annotations.report_hash}}</span></p>
<p>Software version: <span>{{sanitize_html execution_annotations.software_version}}</span></p>
<p>System hash: <span>{{sanitize_html execution_annotations.app_hash}}</span></p>
</section>
</main>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP INDEX IF EXISTS sequent_backend.cast_vote_participation_election_idx;
DROP INDEX IF EXISTS sequent_backend.cast_vote_participation_event_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE INDEX IF NOT EXISTS cast_vote_participation_event_idx
ON sequent_backend.cast_vote (tenant_id, election_event_id, voter_id_string);

CREATE INDEX IF NOT EXISTS cast_vote_participation_election_idx
ON sequent_backend.cast_vote (tenant_id, election_event_id, election_id, voter_id_string);
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/cat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,7 @@ const catalanTranslation: TranslationType = {
BALLOT_RECEIPT: "Rebut de la Papereta",
ELECTORAL_RESULTS: "Resultats Electorals",
MANUAL_VERIFICATION: "Verificació Manual",
PARTICIPATION_REPORT: "Informe de Participació",
STATISTICAL_REPORT: "Informe Estadístic",
OVCS_EVENTS: "Seguiment del Vot a l'Estranger - Esdeveniments OVCS",
AUDIT_LOGS: "Registres d'Auditoria",
Expand Down Expand Up @@ -2039,6 +2040,7 @@ const catalanTranslation: TranslationType = {
BALLOT_RECEIPT: "Rebut de Vot",
ACTIVITY_LOGS: "Registres d'Activitats",
MANUAL_VERIFICATION: "Verificació Manual",
PARTICIPATION_REPORT: "Informe de Participació",
},
method: {
email: "Email",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,7 @@ const englishTranslation = {
BALLOT_RECEIPT: "Ballot Receipt",
ELECTORAL_RESULTS: "Electoral Results",
MANUAL_VERIFICATION: "Manual Verification",
PARTICIPATION_REPORT: "Participation Report",
STATISTICAL_REPORT: "Statistical Report",
OVCS_EVENTS: "Overseas Voting Monitoring - OVCS Events",
AUDIT_LOGS: "Audit Logs",
Expand Down Expand Up @@ -2014,6 +2015,7 @@ const englishTranslation = {
BALLOT_RECEIPT: "Ballot Receipt",
ACTIVITY_LOGS: "Activity Logs",
MANUAL_VERIFICATION: "Manual Verification",
PARTICIPATION_REPORT: "Participation Report",
},
method: {
email: "Email",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ const spanishTranslation: TranslationType = {
BALLOT_RECEIPT: "Recibo de Voto",
ELECTORAL_RESULTS: "Resultados Electorales",
MANUAL_VERIFICATION: "Verificación Manual",
PARTICIPATION_REPORT: "Informe de Participación",
STATISTICAL_REPORT: "Informe Estadístico",
OVCS_EVENTS: "Monitoreo de Votación en el Extranjero - Eventos OVCS",
AUDIT_LOGS: "Registros de Auditoría",
Expand Down Expand Up @@ -2032,6 +2033,7 @@ const spanishTranslation: TranslationType = {
BALLOT_RECEIPT: "Recibo de Voto",
ACTIVITY_LOGS: "Registros de Actividades",
MANUAL_VERIFICATION: "Verificación Manual",
PARTICIPATION_REPORT: "Informe de Participación",
},
method: {
email: "Email",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/eu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ const basqueTranslation: TranslationType = {
BALLOT_RECEIPT: "Bozketa Jasoagiria",
ELECTORAL_RESULTS: "Hauteskunde Emaitzak",
MANUAL_VERIFICATION: "Eskuzko Egiaztapena",
PARTICIPATION_REPORT: "Parte-hartze Txostena",
STATISTICAL_REPORT: "Txosten Estatistikoa",
OVCS_EVENTS: "Atzerriko Bozketa Monitorizazioa - OVCS Gertaerak",
AUDIT_LOGS: "Auditoria Egunkariak",
Expand Down Expand Up @@ -2023,6 +2024,7 @@ const basqueTranslation: TranslationType = {
BALLOT_RECEIPT: "Bozketa Jasoagiria",
ACTIVITY_LOGS: "Jarduera Egunkariak",
MANUAL_VERIFICATION: "Eskuzko Egiaztapena",
PARTICIPATION_REPORT: "Parte-hartze Txostena",
},
method: {
email: "Emaila",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ const frenchTranslation: TranslationType = {
BALLOT_RECEIPT: "Reçu de Bulletin",
ELECTORAL_RESULTS: "Résultats Électoraux",
MANUAL_VERIFICATION: "Vérification Manuelle",
PARTICIPATION_REPORT: "Rapport de Participation",
STATISTICAL_REPORT: "Rapport Statistique",
OVCS_EVENTS: "Suivi du Vote à l'Étranger - Événements OVCS",
AUDIT_LOGS: "Journaux d'Audit",
Expand Down Expand Up @@ -2043,6 +2044,7 @@ const frenchTranslation: TranslationType = {
BALLOT_RECEIPT: "Reçu de Vote",
ACTIVITY_LOGS: "Journaux d'Activité",
MANUAL_VERIFICATION: "Vérification Manuelle",
PARTICIPATION_REPORT: "Rapport de Participation",
},
method: {
email: "Email",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/gl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ const galegoTranslation: TranslationType = {
BALLOT_RECEIPT: "Recibo da Papeleta",
ELECTORAL_RESULTS: "Resultados Electorais",
MANUAL_VERIFICATION: "Verificación Manual",
PARTICIPATION_REPORT: "Informe de Participación",
STATISTICAL_REPORT: "Informe Estatístico",
OVCS_EVENTS: "Monitorización de Votación no Estranxeiro - Eventos OVCS",
AUDIT_LOGS: "Rexistros de Auditoría",
Expand Down Expand Up @@ -2031,6 +2032,7 @@ const galegoTranslation: TranslationType = {
BALLOT_RECEIPT: "Recibo de Voto",
ACTIVITY_LOGS: "Registros de Actividades",
MANUAL_VERIFICATION: "Verificación Manual",
PARTICIPATION_REPORT: "Informe de Participación",
},
method: {
email: "Correo",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ const dutchTranslation: TranslationType = {
BALLOT_RECEIPT: "Ontvangstbewijs Stembiljet",
ELECTORAL_RESULTS: "Verkiezingsresultaten",
MANUAL_VERIFICATION: "Handmatige Verificatie",
PARTICIPATION_REPORT: "Participatierapport",
STATISTICAL_REPORT: "Statistisch Rapport",
OVCS_EVENTS: "Monitoring Stemmen Buitenland - OVCS Gebeurtenissen",
AUDIT_LOGS: "Auditlogs",
Expand Down Expand Up @@ -2026,6 +2027,7 @@ const dutchTranslation: TranslationType = {
BALLOT_RECEIPT: "Ontvangstbewijs Stembiljet",
ACTIVITY_LOGS: "Activiteitenlogs",
MANUAL_VERIFICATION: "Handmatige Verificatie",
PARTICIPATION_REPORT: "Participatierapport",
},
method: {
email: "E-mail",
Expand Down
2 changes: 2 additions & 0 deletions packages/admin-portal/src/translations/tl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ const tagalogTranslation: TranslationType = {
BALLOT_RECEIPT: "Resibo ng Balota",
ELECTORAL_RESULTS: "Mga Resulta ng Eleksyon",
MANUAL_VERIFICATION: "Manwal na Pag-verify",
PARTICIPATION_REPORT: "Ulat ng Pakikilahok",
STATISTICAL_REPORT: "Ulat ng Istatistika",
OVCS_EVENTS: "Pagsubaybay ng Botohan sa Ibang Bansa - Mga Kaganapan ng OVCS",
AUDIT_LOGS: "Mga Talaan ng Awdit",
Expand Down Expand Up @@ -2035,6 +2036,7 @@ const tagalogTranslation: TranslationType = {
BALLOT_RECEIPT: "Resibo ng Balota",
ACTIVITY_LOGS: "Mga Tala ng Aktibidad",
MANUAL_VERIFICATION: "Manwal na Pag-verify",
PARTICIPATION_REPORT: "Ulat ng Pakikilahok",
},
method: {
email: "Email",
Expand Down
13 changes: 13 additions & 0 deletions packages/admin-portal/src/types/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum EReportType {
BALLOT_RECEIPT = ETemplateType.BALLOT_RECEIPT,
ACTIVITY_LOGS = ETemplateType.ACTIVITY_LOGS,
MANUAL_VERIFICATION = ETemplateType.MANUAL_VERIFICATION,
PARTICIPATION_REPORT = ETemplateType.PARTICIPATION_REPORT,
}

export enum EReportElectionPolicy {
Expand Down Expand Up @@ -77,6 +78,18 @@ export const reportTypeConfig: {
electionPolicy: EReportElectionPolicy.ELECTION_NOT_ALLOWED,
associatedTemplateType: ETemplateType.MANUAL_VERIFICATION,
},
[EReportType.PARTICIPATION_REPORT]: {
actions: [
ReportActions.EDIT,
ReportActions.DELETE,
ReportActions.PREVIEW,
ReportActions.GENERATE,
ReportActions.GENERATE_SCHEDULED,
],
templateRequired: false,
electionPolicy: EReportElectionPolicy.ELECTION_ALLOWED,
associatedTemplateType: ETemplateType.PARTICIPATION_REPORT,
},
default: {
actions: [ReportActions.EDIT, ReportActions.DELETE, ReportActions.PREVIEW],
templateRequired: false,
Expand Down
1 change: 1 addition & 0 deletions packages/admin-portal/src/types/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export enum ETemplateType {
BALLOT_RECEIPT = "BALLOT_RECEIPT",
ACTIVITY_LOGS = "ACTIVITY_LOGS",
MANUAL_VERIFICATION = "MANUAL_VERIFICATION",
PARTICIPATION_REPORT = "PARTICIPATION_REPORT",
}

export enum ITemplateMethod {
Expand Down
Loading
Loading