# Project Workflow / Procedural Process (Voter System)

This document explains how the project works end-to-end (public voter flows + admin flows), with diagrams for easy understanding.

## 1) High-Level Architecture (How requests are routed)

**Routing overview**
- The app is deployed in a subfolder (example: `/voter`) using `BASE_PATH`.
- Public “pretty URLs” like `/vote` or `/admin/results` are resolved by the front controller + router.

Relevant files:
- [router.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/router.php)
- [public/.htaccess](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/.htaccess)
- [config.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/config/config.php)
- [security.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/security.php) (`base_url()`)

```mermaid
flowchart LR
  B[Browser] -->|GET /voter/anything| A[Apache/.htaccess]
  A -->|Rewrite to public/index.php| F[public/index.php]
  F -->|Loads config + db + helpers| C[PHP App]
  C -->|Resolves route| R[public/router.php]
  R -->|Serve file| S[public/*.php or public/assets/*]
  R -->|404| N[Not Found]
```

## 2) Core Data Model (Database tables)

The project uses these main tables (from [schema.sql](file:///Applications/XAMPP/xamppfiles/htdocs/voter/db/schema.sql)):
- `users`: registered voters (photo stored as blob), includes `voting_code`, `voter_uid`, `verified`
- `positions`: election positions (Chairman, etc.)
- `candidates`: maps a `user` to a `position` (+ manifesto)
- `votes`: one row per (voter-hash, position) selection
- `vote_receipts`: one receipt per voter per election round (prevents re-voting)
- `election_settings`: global switches: `registration_open`, `is_open`, `start_at`, `end_at`
- `audit_logs`: security/audit trail
- `admin_users`: admin accounts (roles: admin / superadmin)
- `election_archives`, `election_archive_results`: past election storage

```mermaid
erDiagram
  USERS {
    bigint id PK
    varchar full_name
    varchar email
    varchar phone
    varchar voting_code
    varchar voter_uid
    blob photo_blob
    varchar photo_mime
    tinyint verified
    timestamp created_at
  }
  ADMIN_USERS {
    bigint id PK
    varchar email
    varchar password_hash
    varchar role
    tinyint active
  }
  POSITIONS {
    bigint id PK
    varchar title
  }
  CANDIDATES {
    bigint id PK
    bigint position_id FK
    bigint user_id FK
    text manifesto
  }
  VOTES {
    bigint id PK
    char user_id
    bigint position_id FK
    bigint candidate_id FK
    blob voter_manifest
  }
  VOTE_RECEIPTS {
    bigint id PK
    char user_id
    char receipt_code
  }
  ELECTION_SETTINGS {
    tinyint id PK
    tinyint is_open
    tinyint registration_open
    datetime start_at
    datetime end_at
  }
  AUDIT_LOGS {
    bigint id PK
    varchar event_type
    varchar ip_address
    timestamp created_at
  }

  POSITIONS ||--o{ CANDIDATES : has
  USERS ||--o{ CANDIDATES : can_be
  CANDIDATES ||--o{ VOTES : receives
  POSITIONS ||--o{ VOTES : groups
```

## 3) Public Workflow (Voter Journey)

### 3.1 Registration (Public)

**Pages**
- Registration form: [register.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/register.php)
- Registration handler: [voter_enroll.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voter_enroll.php)

**Step-by-step**
1. Voter opens `/register`.
2. System checks `election_settings.registration_open` (registration can be enabled/disabled by admin).
3. Voter submits `full_name`, `phone`, optional `email`, and **a photo**.
4. Server:
   - validates input + photo type/size
   - generates unique `voter_uid` and 6-digit `voting_code`
   - inserts into `users` (currently sets `verified = 1` in [voter_enroll.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voter_enroll.php))
5. System generates a voter card PDF and emails it if email exists ([voter_card_pdf.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/voter_card_pdf.php))
6. System sends SMS with the voting code using both Termii and 80kobosms ([sms_helper.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/sms_helper.php))

```mermaid
sequenceDiagram
  participant V as Voter
  participant W as Website (/register)
  participant E as voter_enroll.php
  participant DB as MySQL
  participant SMS as SMS Providers
  participant M as Email

  V->>W: Fill form + upload photo
  W->>E: POST /voter_enroll (CSRF)
  E->>DB: Check registration_open
  E->>DB: INSERT users(full_name, phone, email, photo_blob,...)
  E->>M: Email voter card (if email provided)
  E->>SMS: Send voting code via Termii + 80kobosms
  E-->>V: Redirect back to /register with success message
```

### 3.2 Voting Login (No password, code-based)

**Pages**
- Code entry: [vote.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote.php)
- Verification handler: [vote_verify.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_verify.php)

**Step-by-step**
1. Voter opens `/vote`.
2. Enters phone number + 6-digit voting code.
3. Server verifies:
   - voting code exists
   - phone matches what is on the user record
   - voter is verified (`users.verified = 1`)
4. Server writes `$_SESSION['user_id']` and redirects to `/dashboard/ballot`.

```mermaid
flowchart TD
  A[/vote form/] --> B[/vote_verify.php/]
  B --> C{Code exists?}
  C --No--> X[Reject: Invalid voting code]
  C --Yes--> D{Phone matches?}
  D --No--> Y[Reject: Phone mismatch]
  D --Yes--> E{Verified?}
  E --No--> Z[Reject: Not verified]
  E --Yes--> S[Set session user_id] --> T[/dashboard/ballot/]
```

### 3.3 Ballot + Vote Submission

**Pages**
- Ballot UI: [dashboard/ballot.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/dashboard/ballot.php)
- Vote submit handler: [vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php)

**Ballot logic**
- Ballot page reads `election_settings` and decides if voting is allowed:
  - `is_open = 1`
  - schedule set (`start_at`, `end_at`)
  - current time is within schedule (UTC comparison)
- Ballot page loads `positions` + `candidates` and groups by position.

**Vote submission logic**
1. Voter submits “one candidate per position” to `/vote_process`.
2. Server blocks voting if:
   - `election_settings.is_open != 1`
   - time not within schedule
3. Server blocks duplicate voting using `vote_receipts`:
   - It hashes the real user id via `hash_user_id()` ([security.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/security.php))
   - Stores the hash in `vote_receipts.user_id`
4. For each selected position:
   - inserts `votes(user_id_hash, position_id, candidate_id, voter_manifest)`
5. Inserts `vote_receipts(user_id_hash, receipt_code)` for proof of participation.
6. Sends receipt via email (if email exists) and SMS (if phone exists).
7. Auto-close logic: if **all verified voters** have voted, election is closed early (see section 6).

```mermaid
sequenceDiagram
  participant V as Voter
  participant B as Ballot UI
  participant VP as vote_process.php
  participant DB as MySQL
  participant SMS as SMS
  participant M as Email

  V->>B: Select candidates (one per position)
  B->>VP: POST /vote_process (CSRF)
  VP->>DB: Read election_settings (is_open/start/end)
  VP->>DB: Check vote_receipts for this voter-hash
  VP->>DB: INSERT votes (one row per position)
  VP->>DB: INSERT vote_receipts (one per voter per round)
  VP->>M: Send receipt email (optional)
  VP->>SMS: Send receipt SMS (optional)
  VP-->>V: Redirect /dashboard/confirmation
```

## 4) Admin Workflow (Setup → Run election → Monitor → Export)

### 4.1 Admin Login

**Pages**
- Login page: [login.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/login.php)
- Login handler: [login_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/login_process.php)

**Step-by-step**
1. Admin opens `/login` and signs in (email + password).
2. `admin_login()` validates credentials against `admin_users` ([admin_auth.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/admin_auth.php)).
3. On success, server sets:
   - `$_SESSION['admin_id']`, `admin_role`, `admin_email`, `admin_name`
4. Redirects to admin dashboard: `/admin/` ([admin/index.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/index.php))

### 4.2 Setup Tasks (Before Election Starts)

Typical order:
1. Create positions (e.g., Chairman, Secretary):
   - [positions_create.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/positions_create.php)
2. Create candidates by linking a voter to a position:
   - [candidate_create.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/candidate_create.php)
3. Set voting schedule (UTC input):
   - handler: [update_schedule.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/update_schedule.php)
   - When schedule is updated for a new round, the system archives previous results and clears votes/receipts.
4. Toggle voting open:
   - [toggle_voting.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/toggle_voting.php)
5. (Optional) Enable/disable voter registration:
   - [operations.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/operations.php) + [toggle_registration.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/toggle_registration.php)

```mermaid
flowchart TB
  A[Admin Login] --> B[Admin Dashboard /admin/]
  B --> C[Create Positions]
  C --> D[Register/Verify Voters]
  D --> E[Create Candidates (link voter -> position)]
  E --> F[Set Schedule (UTC)]
  F --> G[Open Voting]
  G --> H[Monitor Results]
  H --> I[Export Results (CSV/PDF)]
```

### 4.3 Manage Voters (Verification, Resend, Edit)

**Voter list**
- [voters_list.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voters_list.php)

Admins can:
- search/filter voters
- verify/unverify voters ([voter_verify.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voter_verify.php))
- resend voting code (single or bulk):
  - [resend_code_single.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/resend_code_single.php)
  - [resend_codes.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/resend_codes.php)
- edit a voter’s profile + photo:
  - [voter_edit.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voter_edit.php)
  - [voter_update.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voter_update.php)

## 5) Results Workflow (Admin Dashboard + Live Updates)

**Admin results page**
- UI: [results.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results.php)
- Live JSON API: [results_api.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results_api.php)

How it works:
1. `results.php` renders the current totals + charts for each position.
2. JavaScript polls `results_api.php` every few seconds.
3. `results_api.php` recomputes:
   - total votes
   - unique voters
   - per-position candidate vote counts
4. The page updates numbers, charts, and tables without a manual refresh.

```mermaid
sequenceDiagram
  participant Admin as Admin Browser
  participant UI as /admin/results (results.php)
  participant API as /admin/results_api (results_api.php)
  participant DB as MySQL

  Admin->>UI: Open results page
  UI->>DB: Initial query (positions/candidates/votes)
  UI-->>Admin: Render charts + tables
  loop Every few seconds
    UI->>API: fetch JSON
    API->>DB: COUNT votes + group results
    API-->>UI: JSON payload
    UI-->>Admin: Update charts/tables
  end
```

## 6) Election End Rule (Whichever happens first)

The election ends when either:
1. the configured `end_at` time passes, OR
2. all **eligible voters** have voted.

**Eligible voters definition in this project**
- Currently: `users.verified = 1`

**How “all voted” is computed**
- eligible count: `SELECT COUNT(*) FROM users WHERE verified = 1`
- voted count: `SELECT COUNT(*) FROM vote_receipts`

Where it is enforced:
- After a successful vote submission: [vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php)
- Also checked inside results polling API as a safety: [results_api.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results_api.php)

When `all voted` becomes true:
- `election_settings.is_open` is set to `0`
- `end_at` is forced to the current UTC timestamp (if it was later)

## 7) Notifications (SMS + Email)

**Registration**
- SMS voting code sent via `send_sms_all()` ([sms_helper.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/sms_helper.php))
- Voter card email sent (if email exists) ([voter_enroll.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voter_enroll.php))

**Voting schedule updates**
- When admin saves schedule, the system sends bulk SMS to all verified voters ([update_schedule.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/update_schedule.php))

**Vote confirmation**
- Receipt is sent via SMS and optionally email after voting ([vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php))

**Winner notifications**
- Admin results page calls `check_and_notify_winners()` which sends SMS to winners after election end ([results.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results.php), [winner_notifications.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/winner_notifications.php))

## 8) Security & Integrity Controls (What prevents cheating)

Key controls:
- **CSRF tokens** for all POST forms ([security.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/security.php))
- **Session timeouts** for voters and admins ([security.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/security.php), [admin_auth.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/admin_auth.php))
- **Admin rate limiting** (per session) ([admin_auth.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/includes/admin_auth.php))
- **One vote per voter per election round**
  - enforced by `vote_receipts` check in [vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php)
- **One vote per position**
  - enforced by unique index `uniq_vote_user_position` in [schema.sql](file:///Applications/XAMPP/xamppfiles/htdocs/voter/db/schema.sql)
- **Voter privacy**
  - votes store `user_id` as a hash (HMAC) rather than the real user id (`hash_user_id()`)
- **Audit logs**
  - actions like voting + verification write to `audit_logs` (see [vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php) and [voter_verify.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voter_verify.php))

## 9) Quick URL Map (Cheat Sheet)

**Public**
- `/` → Home page ([index.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/index.php))
- `/register` → registration form ([register.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/register.php))
- `/voter_enroll` → registration submit ([voter_enroll.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voter_enroll.php))
- `/vote` → voting code login ([vote.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote.php))
- `/vote_verify` → verify code ([vote_verify.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_verify.php))
- `/dashboard/ballot` → ballot ([dashboard/ballot.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/dashboard/ballot.php))
- `/vote_process` → cast vote ([vote_process.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/vote_process.php))
- `/voters` → voters register list ([voters.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voters.php))
- `/voters_pdf` → voters PDF export ([voters_pdf.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/voters_pdf.php))

**Admin**
- `/login` → admin login ([login.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/login.php))
- `/admin/` → admin dashboard ([admin/index.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/index.php))
- `/admin/operations` → operations / registration toggle / reset ([operations.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/operations.php))
- `/admin/voters_list` → voters list (verify, resend, edit) ([voters_list.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/voters_list.php))
- `/admin/results` → live results dashboard ([results.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results.php))
- `/admin/results_api` → polling API ([results_api.php](file:///Applications/XAMPP/xamppfiles/htdocs/voter/public/admin/results_api.php))

