# Tasks: Event Management App

**Input**: Design documents from `/specs/001-event-management-app/`

**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, quickstart.md

**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.

## Format: `[ID] [P?] [Story] Description`

- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions

## Phase 1: Setup (Shared Infrastructure)

**Purpose**: Project initialization and basic structure

- [x] T001 Initialize PHP 8.4 project with Composer
- [x] T002 [P] Install Slim Framework v4, Twig, and Guzzle (for PocketBase API)
- [x] T003 [P] Configure PHPUnit for testing

---

## Phase 2: Foundational (Blocking Prerequisites)

**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented

**⚠️ CRITICAL**: No user story work can begin until this phase is complete

- [x] T004 Setup SQLite database and PDO connection in src/Dependencies.php
- [x] T005 [P] Implement authentication service (AdminUser via PocketBase REST API) in src/Services/PocketBaseAuth.php
- [x] T006 [P] Setup API routing and middleware structure in public/index.php
- [x] T007 Create database schema and migration script for Event, TicketCategory, TicketBatch, Order, Ticket models
- [x] T008 Configure error handling and logging infrastructure

**Checkpoint**: Foundation ready - user story implementation can now begin in parallel

---

## Phase 3: User Story 1 - Attendee Event Registration & Checkout (Priority: P1) 🎯 MVP

**Goal**: An attendee discovers an event, selects their ticket category and batch, and completes registration choosing between Pix or Credit Card via ASAAS.

**Independent Test**: Navigate to public page, select ticket, enter details (including CPF), and verify Pix QR code displays or redirect to ASAAS checkout occurs. Validate Docker Logs for any hidden 500 errors.

### Tests for User Story 1

> **NOTE: Write these tests FIRST, ensure they FAIL before implementation**

- [x] T009 [P] [US1] Integration test for attendee registration and ASAAS checkout flow in tests/Integration/RegistrationTest.php

### Implementation for User Story 1

- [x] T010 [P] [US1] Create Event, TicketCategory, and TicketBatch models in src/Models/
- [x] T011 [P] [US1] Create Order model in src/Models/Order.php with ASAAS fields (customer_id, payment_id, method, invoice_url, pix_qr)
- [x] T011a [US1] Create database migration for the new ASAAS fields in the `orders` table
- [x] T011b [US1] Implement AsaasClient in src/Services/AsaasClient.php to handle Customer and Payment creation
- [x] T012 [US1] Implement EventController to list events and batches in src/Controllers/EventController.php
- [x] T013 [US1] Create public registration form Twig template in templates/public/register.twig (including CPF and payment method selection)
- [x] T014 [US1] Implement OrderService to create pending orders and call AsaasClient based on selected method
- [x] T015 [US1] Implement Pix checkout Twig template displaying QR code in templates/public/checkout_pix.twig
- [x] T016 [US1] Add validation and error handling for registration submission
- [x] T016a [US1] Validate all flows by checking Docker logs (Constitution V)

**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently

---

## Phase 4: User Story 2 - Automated Payment Approval via Webhook & Admin Fallback (Priority: P1)

**Goal**: The system receives an asynchronous notification from ASAAS confirming payment, updates the order, and automatically issues the ticket. Admin can view orders and manually approve if needed.

**Independent Test**: Simulate an ASAAS webhook POST request, verify order status changes to approved, and confirm ticket email is dispatched within 10s. Verify Admin orders view.

### Tests for User Story 2

- [x] T017 [P] [US2] Integration test for webhook processing and manual fallback in tests/Integration/WebhookTest.php
- [x] T018 [P] [US2] Unit test for ticket generation in tests/Unit/TicketServiceTest.php

### Implementation for User Story 2

- [x] T019 [P] [US2] Create Ticket model in src/Models/Ticket.php
- [x] T020 [US2] Implement Admin authentication middleware in src/Middleware/AdminAuth.php
- [x] T021 [US2] Implement TicketService to generate ticket codes and dispatch emails in src/Services/TicketService.php
- [x] T022 [US2] Implement AdminOrderController for viewing and manually approving orders in src/Controllers/AdminOrderController.php
- [x] T023 [US2] Create Admin dashboard view for pending orders in templates/admin/orders.twig
- [x] T024 [US2] Implement background queue worker to guarantee 10s email SLA in scripts/worker.php and src/Jobs/SendTicketEmail.php
- [x] T024a [US2] Implement WebhookController (`POST /webhooks/asaas`) to receive ASAAS payloads and trigger TicketService
- [x] T024b [US2] Check Docker logs to ensure webhook requests succeed without silent failures (Constitution V)

**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently

---

## Phase 5: User Story 3 - Admin Event Management (Priority: P2)

**Goal**: An administrator creates a new event, configures the cover image and description, and sets up multiple ticket categories and date-based batches.

**Independent Test**: Can be tested by logging into the admin panel, filling out the event creation form including categories and batches, and verifying the event appears correctly on the public side.

### Tests for User Story 3

- [x] T025 [P] [US3] Integration test for event management flow in tests/Integration/EventManagementTest.php

### Implementation for User Story 3

- [x] T026 [P] [US3] Implement image upload service (PocketBase integration) in src/Services/PocketBaseFile.php
- [x] T027 [US3] Implement AdminEventController for CRUD operations on events, categories, and batches in src/Controllers/AdminEventController.php
- [x] T028 [US3] Create event management views (create/edit forms) in templates/admin/events/
- [x] T029 [US3] Add validation and error handling for event/batch configuration

**Checkpoint**: All P1 and P2 user stories should now be independently functional

---

## Phase 6: User Story 4 - Admin Manual Ticket Sales (Priority: P3)

**Goal**: An administrator manually processes a ticket sale directly from the backend for attendees paying in person or via other unlisted methods.

**Independent Test**: Can be tested by filling out the manual sale form in the backend and verifying the ticket is issued immediately.

### Tests for User Story 4

- [x] T030 [P] [US4] Integration test for manual backend ticket sale in tests/Integration/ManualSaleTest.php

### Implementation for User Story 4

- [x] T031 [US4] Implement AdminManualSaleController in src/Controllers/AdminManualSaleController.php
- [x] T032 [US4] Create manual sale form view in templates/admin/manual_sale.twig
- [x] T033 [US4] Integrate manual sale submission with OrderService and TicketService to bypass pending status

**Checkpoint**: All user stories should now be independently functional

---

## Phase 7: User Story 5 - Admin Auth & RBAC (Priority: P2)

**Goal**: Implement a login screen restricted to `/admin` and integrate authentication and Role-Based Access Control via PocketBase User Manager.

**Independent Test**: Can be tested by logging in with different roles and verifying access to endpoints (e.g., `superadmin` has full access, `financeiro` only to financial screens).

### Tests for User Story 5

- [x] T039 [P] [US5] Integration test for Admin Authentication and RBAC in tests/Integration/AdminRBACTest.php

### Implementation for User Story 5

- [x] T040 [US5] Update PocketBaseAuth middleware to support role-based access validation in src/Middleware/AdminAuthMiddleware.php
- [x] T041 [US5] Implement Admin Login screen Twig template in templates/admin/login.twig
- [x] T042 [US5] Implement AuthController to handle login form submission and session setup in src/Controllers/Admin/AuthController.php
- [x] T043 [US5] Create User Management interface to edit roles in templates/admin/users/
- [x] T044 [US5] Secure existing admin routes using the updated RBAC middleware in public/index.php

**Checkpoint**: Admin area is now fully protected and accessible only to authorized roles.

---

## Phase 8: User Story 6 - Admin Session & Profile Management (Priority: P2)

**Goal**: Implement a logout UI mechanism and a self-service profile section for admins to change their own passwords securely.

**Independent Test**: Can be tested by logging in as an admin, navigating to the Profile/Security section, successfully changing the password, logging out, and logging back in with the new password.

### Tests for User Story 6

- [x] T045 [P] [US6] Integration test for Admin Profile Management in tests/Integration/AdminProfileTest.php

### Implementation for User Story 6

- [x] T046 [US6] Implement logout UI button in the Admin layout Twig template in templates/admin/layout.twig
- [x] T047 [US6] Create ProfileController to handle password change submissions in src/Controllers/Admin/ProfileController.php
- [x] T048 [US6] Create Security/Profile view for password changing in templates/admin/profile.twig
- [x] T049 [US6] Register new profile routes in public/index.php

**Checkpoint**: Admins can now manage their own session and security credentials directly from the dashboard.

---

## Phase 9: UI Refactoring - Admin Panel (Priority: P2)

**Goal**: Standardize the administrative UI by ensuring all pages inherit from the base `layout.twig` and utilize a consistent set of CSS classes and components.

**Independent Test**: Load every admin page (login, dashboard, users list, events, categories, orders) and verify that the layout header, sidebar, and core styles are identical without duplicate `<html>` tags.

### Tests for UI Refactoring

- [x] T050 [P] Visual regression or manual walk-through to ensure no layout breakages occur during refactoring.

### Implementation for UI Refactoring

- [x] T051 [P] Refactor `templates/admin/login.twig` to use `layout.twig` (or a stripped-down auth layout) and standardize styles.
- [x] T052 [P] Refactor `templates/admin/orders.twig` to extend `layout.twig` and move styles to `extra_css`.
- [x] T053 [P] Refactor `templates/admin/users/list.twig` and `templates/admin/users/form.twig` to extend `layout.twig`.
- [x] T054 [P] Refactor `templates/admin/events/list.twig` and `templates/admin/events/form.twig` to extend `layout.twig`.
- [x] T055 [P] Refactor `templates/admin/categories/list.twig` and `templates/admin/categories/edit_batch.twig` to extend `layout.twig`.
- [x] T056 Ensure consistent styling (buttons, tables, input fields, badges) across all refactored `.twig` files.

**Checkpoint**: The entire admin panel is fully unified under a single structural layout.

---

## Phase 10: User Story 7 - Event & Ticket Management Dashboard (Priority: P2)

**Goal**: Display active events on the dashboard with capacity counters and provide a detailed view for managing issued tickets and sales summaries per event.

**Independent Test**: Can be tested by creating an active event with ticket batches, processing an order, and verifying the dashboard reflects the sold tickets. Also navigating to the event's ticket management page should show the correct sales summary and ticket list.

### Tests for User Story 7

- [x] T057 [P] [US7] Integration test for Dashboard active events list in tests/Integration/DashboardTest.php
- [x] T058 [P] [US7] Integration test for Event Tickets Management in tests/Integration/EventTicketsTest.php

### Implementation for User Story 7

- [x] T059 [P] [US7] Create migration script to add `event_date`, `location`, and `status` to `events` table in root directory.
- [x] T060 [US7] Update Event model (src/Models/Event.php) and admin event views (templates/admin/events/form.twig) to handle new fields.
- [x] T061 [US7] Update `DashboardController::index` to fetch active events and calculate sold/available capacity in src/Controllers/Admin/DashboardController.php.
- [x] T062 [US7] Update `templates/admin/dashboard.twig` to display the active events table/grid.
- [x] T063 [US7] Implement `listTickets` in src/Controllers/Admin/EventAdminController.php to fetch sales summary and tickets for an event.
- [x] T064 [US7] Create view `templates/admin/events/tickets.twig` to display sales summary and ticket list.

**Checkpoint**: The dashboard now properly shows active events, and admins can manage tickets on a per-event basis.

---

## Phase 12: User Story 8 - Admin Layout Refactoring (Priority: P2)

**Goal**: Standardize the administrative UI with a two-column layout (Sidebar + Main Content) and unified header structures for inner pages, including a global actions block and right-aligned contextual table actions.

**Independent Test**: Load every admin page (login, dashboard, users list, events, categories, orders) and verify that the layout header, sidebar, and core styles are identical, the sidebar remains fixed on the left, and action buttons are cleanly positioned.

### Tests for User Story 8

- [x] T065 [P] Visual regression or manual walk-through to ensure the new layout structures render correctly on all resolutions.

### Implementation for User Story 8

- [x] T066 [US8] Update `templates/admin/layout.twig` to implement a two-column layout (Sidebar + Content) and add the `global_actions` block.
- [x] T067 [US8] Update `templates/admin/events/list.twig` to move the "Novo Evento" button into `global_actions` and align table actions right.
- [x] T068 [US8] Update `templates/admin/users/list.twig` to move the "Novo Usuário" button into `global_actions` and align table actions right.
- [x] T069 [US8] Update `templates/admin/dashboard.twig` to properly align within the new content area and remove redundant titles.
- [x] T070 [US8] Review and update all other admin list/form views (e.g., categories, orders) to ensure proper styling with the new layout.

**Checkpoint**: The entire admin panel now has a modern, standardized sidebar and action header layout.

---

## Phase 14: Dashboard Actions Refinement

**Purpose**: Update active events table actions in the dashboard.

- [x] T071 [P] Test or manually verify that the public event link works correctly from the admin dashboard.
- [x] T072 Update `templates/admin/dashboard.twig` to replace "Editar" button with "Ver Página do Evento" pointing to `/event/{id}` for each active event.

**Checkpoint**: The dashboard now correctly links to the public event checkout page.

---

## Phase 15: Missing Integration Tests

**Purpose**: Create missing integration tests to cover critical user journeys.

- [x] T073 [P] [US1] Create `tests/Integration/RegistrationTest.php` to test public event registration and checkout form submission.

---

## Phase 16: System Info & Developer Contact Screen

**Purpose**: Implement a developer info screen and contact form accessible via a watermark button in the admin sidebar.

### Tests for Phase 16
- [x] T078a [P] Integration test for System Info and contact form submission in tests/Integration/SystemInfoTest.php

### Implementation for Phase 16
- [x] T074 Update `templates/admin/layout.twig` to add a watermark-style version button above the "Sair" link.
- [x] T075 Create `SystemInfoController` in `src/Controllers/Admin/SystemInfoController.php` with `index` and `sendContact` methods.
- [x] T076 Register `GET /admin/system-info` and `POST /admin/system-info/contact` in `public/index.php`.
- [x] T077 Create view `templates/admin/system_info.twig` displaying PHP, PocketBase, and App versions, plus the contact form and `logo_ectec.png`.
- [x] T078 Implement the contact form submission logic to send an email to `eduardogcorrea@gmail.com`.

---

## Phase 17: Global Settings Interface

**Purpose**: Implement database structure, routes, and views for managing global application settings (App Name, Visual Identity, and SMTP).

- [x] T079 Create a database migration script (e.g., `scripts/migrate_phase17.php`) to create the `app_settings` table in SQLite.
- [x] T080 Update `templates/admin/layout.twig` to display a dynamic logo placeholder next to "Administração" and add the "Configurações" link in the sidebar.
- [x] T081 Create `SettingsController` in `src/Controllers/Admin/SettingsController.php` handling both `index` (GET) and `process` (POST).
- [x] T082 Register `GET /admin/configuracoes` and `POST /admin/configuracoes` routes in `public/index.php`.
- [x] T083 Create the view `templates/admin/settings.twig` with sections for "Identidade Visual" and "Configurações de E-mail (SMTP)".
- [x] T084 Integrate `SettingsController::process` to upload image files to PocketBase (Favicon/Logo) and persist settings in SQLite.
- [x] T084a [P] Create `tests/Integration/SettingsTest.php` to verify global settings update flow.

---

## Phase 19: Event Deletion

**Purpose**: Implement event deletion from the admin dashboard edit view.

- [x] T085 Update `templates/admin/events/form.twig` (or edit view) to include a "Deletar Evento" button that triggers a JS `confirm()`.
- [x] T086 Register `POST /admin/events/{id}/delete` route in `public/index.php`.
- [x] T087 Implement `delete` method in `src/Controllers/Admin/EventAdminController.php` (or `EventController`) to remove the event from SQLite and redirect to `/admin`.
- [x] T087a [P] Create `tests/Integration/EventDeletionTest.php` to verify the event is correctly deleted and redirects to the dashboard.

---

## Phase 20: Debug Environment Variables Display

**Purpose**: Display loaded environment variables in the settings page when `DEBUG=true`.

- [x] T088 Update `src/Controllers/Admin/SettingsController.php` index method to check if `getenv('DEBUG') === 'true'` and pass `$_ENV` (or parsed `.env` variables) to the view as `env_vars`.
- [x] T089 Update `templates/admin/settings.twig` to display a table of `env_vars` if they are present.

---

## Phase 21: Event Shortcode (Slug) URLs

**Purpose**: Use a shortcode (slug) based on the event title for public URLs instead of the numerical ID.

- [x] T090 Create a migration script (e.g., `scripts/migrate_phase21.php`) to add the `slug` column to the `events` table and populate existing rows.
- [x] T091 Update `src/Services/AdminEventService.php` to generate and save the `slug` from the `title` during `createEvent` and `updateEvent`.
- [x] T092 Update `public/index.php` to route `GET /event/{slug}` to `EventController::show` (replacing `{id}`).
- [x] T093 Update `src/Controllers/EventController.php` to fetch the event by its `slug` in the `show` method.
- [x] T094 Update `templates/admin/dashboard.twig` (and any other admin views like `list.twig` linking to the public page) to use `/event/{{ event.slug }}` instead of `{{ event.id }}`.
- [x] T094a [P] Create `tests/Integration/EventSlugTest.php` to verify that slug generation works and the public event page is accessible via slug.

---

## Phase 22: Event Cover Image Styling

**Purpose**: Format the event cover image as a horizontal banner on the public event details page.

- [x] T095 Update `templates/event_details.twig` to apply CSS styling (`width: 100%; max-height: 350px; object-fit: cover; border-radius: 8px;` or a custom class) to the `<img>` element displaying the `event.cover_image_url`, ensuring it acts as a horizontal banner.

---

## Phase 23: Event Description Alignment

**Purpose**: Center the event description paragraph on the public event details page.

- [x] T096 Update `templates/event_details.twig` to add `text-align: center;` (via a CSS class or inline style) to the `<p>` tag that displays the `event.description`.

---

## Phase 24: Direct PIX Payment Configuration

**Purpose**: Allow admins to configure a direct PIX option (bypassing Asaas) that generates pending orders for manual approval.

- [x] T097 Create a migration script (e.g., `scripts/migrate_phase24.php`) to add `accepts_pix_direto` (BOOLEAN) and `pix_direto_instructions` (TEXT) to the `events` table.
- [x] T098 Create `EventPaymentSettingsController` (or update `EventAdminController`) with `GET` and `POST` routes on `/admin/events/{id}/payment-settings` to manage the settings. Register the routes in `public/index.php`.
- [x] T099 Create the view `templates/admin/events/payment_settings.twig` with the configuration form. Add a link to this page from the event management layout or dashboard.
- [x] T100 Update `CheckoutController::showForm` to fetch the event's payment configuration and pass it to the `checkout_form.twig` template.
- [x] T101 Update `templates/checkout_form.twig` to display a payment method selection (e.g., Radio buttons: "Asaas" vs "PIX Direto"). If "PIX Direto" is chosen, display the `pix_direto_instructions`.
- [x] T102 Update `CheckoutController::processForm` so that if "PIX Direto" is submitted, it bypasses the Asaas API call, creates the `Order` with `status='PENDING'`, and redirects to a success page displaying the payment instructions.
- [x] T103 Add/verify an action in the admin orders view (`templates/admin/events/tickets.twig` or similar) that allows an admin to manually approve a `PENDING` order, triggering ticket generation.
- [x] T103a [P] Create `tests/Integration/PixDiretoCheckoutTest.php` to test the manual PIX checkout flow and backend approval.

---

## Phase 25: Ticket Management and Printing

**Purpose**: Provide admin interface to view, print and resend tickets alphabetically.

### Tests for Phase 25
- [x] T109a [P] Integration test for printable ticket view and resend email triggers in tests/Integration/TicketPrintTest.php

### Implementation for Phase 25
- [x] T104 Update `AdminEventService::getEventTickets` to sort by `o.attendee_name ASC`.
- [x] T105 Update `templates/admin/events/list.twig` to add a "Ingressos Vendidos" button pointing to `/admin/events/{id}/tickets` (if not already acting as such, or make sure it exists alongside other options).
- [x] T106 Update `templates/admin/events/tickets.twig` to add an "Ações" column with buttons to "Imprimir" and "Reenviar E-mail".
- [x] T107 Add routes `GET /admin/events/{event_id}/tickets/{ticket_code}/print` and `POST /admin/events/{event_id}/tickets/{ticket_code}/send` in `public/index.php`.
- [x] T108 Implement the controller actions for printing and sending the ticket in `EventAdminController`.
- [x] T109 Create a printable ticket template `templates/admin/events/ticket_print.twig`.

---

## Phase 26: Event Order and Ticket Management Consolidation

**Purpose**: Show pending orders alongside issued tickets in the event's "Ingressos Vendidos" page with context-aware actions.

### Tests for Phase 26
- [x] T113a [P] Integration test for consolidated order and ticket management in tests/Integration/ConsolidatedOrdersTest.php

### Implementation for Phase 26
- [x] T110 Create `AdminEventService::getEventOrdersAndTickets` to query all orders for an event using `LEFT JOIN tickets`.
- [x] T111 Update `EventAdminController::listTickets` to use the new method and recalculate summary metrics (pending, approved, total revenue).
- [x] T112 Update `templates/admin/events/tickets.twig` to display both pending orders and confirmed tickets dynamically in the same list. Show "Aprovar Pagamento" for pending, and "Imprimir"/"Reenviar E-mail" for approved.
- [x] T113 Update `OrderController::approve` or its routes so that after approving an order from the event tickets view, the user is redirected back to the correct screen (or update the form action to hit a localized endpoint).

---

## Phase 27: Deployment and Database Migration Automation

**Purpose**: Ensure the production environment automatically applies SQLite and PocketBase migrations without relying on manual steps.

- [x] T114 Update `.github/workflows/deploy.yml` post-deploy script:
    - Add execution of `php scripts/migrate.php` inside the `app` container.
    - Add execution of `php scripts/migrate_orders_add_columns.php` (if applicable) inside the `app` container.
    - Add a slight delay (e.g., `sleep 5`) and execute `php scripts/setup_pocketbase.php` inside the `app` container.
- [x] T115 Check `docker-compose.yml` to verify the PocketBase container has `command: serve --http=0.0.0.0:8090 --dir=/pb_data` to ensure data persists correctly in `./pb_data`.

---

## Phase 28: Automated Migration Runner System

**Purpose**: Provide an automated and trackable way to run incremental database updates.

- [x] T116 Create `scripts/migrations/` directory and move `migrate_orders_add_columns.php` (and optionally other standalone migration scripts) into it, renaming to include a sequence prefix (e.g., `001_add_orders_columns.php`).
- [x] T117 Create `scripts/run_migrations.php`. This script should:
    - Connect to the DB and create `app_migrations` (`id`, `migration_name`, `executed_at`) if it doesn't exist.
    - Read and sort all `.php` files in `scripts/migrations/`.
    - Skip already executed migrations based on `app_migrations`.
    - Run unexecuted migrations using `exec("php " . escapeshellarg($path), $output, $returnVar)`.
    - Insert the migration name into `app_migrations` if `$returnVar === 0`.
- [x] T118 Update `.github/workflows/deploy.yml` post-deploy steps to replace the explicit individual SQLite migration commands with a single call to `docker-compose exec -T app php scripts/run_migrations.php` (along with `migrate.php`).

---

## Phase 29: PocketBase Configuration Alignment

**Purpose**: Fix PocketBase entrypoint overriding so that data is correctly initialized and persisted in `/pb_data`.

- [x] T119 Update `docker-compose.yml` to adjust `pocketbase` service:
    - Remove the `command: serve --http=0.0.0.0:8090 --dir=/pb_data` line.
    - Add `restart: unless-stopped`.
    - Add `environment:` block with `PB_HOST: 0.0.0.0` and `PB_PORT: 8090`.
    - Add `healthcheck:` block with `wget --no-verbose --tries=1 --spider http://localhost:8090/api/health`.

---

## Phase 30: UI Navigation and Link Refinements

**Purpose**: Remove redundant sidebar links and fix dashboard shortcode links.

- [x] T120 Update `templates/admin/layout.twig` to remove the "Pedidos" menu item from the sidebar navigation.
- [x] T121 Update `templates/admin/dashboard.twig` to use `{{ event.slug }}` in the "Ver Página do Evento" link.

---

## Phase 31: Dashboard Slug Bug Fix

**Purpose**: Ensure the dashboard queries and renders the event slug for public links.

- [x] T122 Update `AdminDashboardService::getActiveEvents` to include `e.slug` in the SELECT query.

---

## Phase 32: Extended Registration Form Fields

**Purpose**: Enrich the attendee registration form with additional contact and professional fields, persisted in the database.

### Tests for Phase 32
- [x] T127a [P] Integration test for extended registration form fields validation and persistence in tests/Integration/ExtendedFieldsTest.php

### Implementation for Phase 32
- [x] T123 Create `scripts/migrations/002_add_attendee_fields.php` to add columns `attendee_nationality`, `attendee_phone`, `attendee_country`, `attendee_state`, `attendee_city`, `attendee_oab` (all TEXT, nullable) to the `orders` table.
- [x] T124 Update `templates/checkout.twig` to add all new fields: Confirmar E-mail (required), Nacionalidade, Telefone Celular, País, Estado, Cidade, OAB (all optional). Include client-side JS validation that `attendee_email` matches `attendee_email_confirm`.
- [x] T125 Update `CheckoutController::processForm` to extract all new fields from `$data` and validate that `attendee_email` matches `attendee_email_confirm` server-side (return form with error message if mismatch).
- [x] T126 Update `OrderService::createOrder` and `OrderService::createDirectOrder` to include the new attendee fields in the `INSERT` SQL and bound parameters.
- [x] T127 Update `templates/admin/events/tickets.twig` to display the extra attendee fields (nationality, phone, country, state, city, OAB) in the ticket/order detail view.

---

## Phase 33: SITE_URL Global — Fix PocketBase Image URLs in Production

**Purpose**: Use `SITE_URL` from `.env` as the public base URL for PocketBase file/image links, so images are accessible in production (not localhost).

- [x] T128 Update `public/index.php` DI Container to read `SITE_URL` from env and pass it as the `publicUrl` argument to `PocketBaseClient` (replacing `POCKETBASE_PUBLIC_URL`). Also inject `site_url` as a Twig global variable.
- [x] T129 Update `docker-compose.yml` to add `SITE_URL` env variable to the `app` service (e.g. `SITE_URL=${SITE_URL}`) so the container reads it from `.env` at runtime.
- [x] T130 Create `scripts/fix_image_urls.php`: a one-time utility script that runs `UPDATE events SET cover_image_url = REPLACE(cover_image_url, 'http://localhost:8090', :site_url)` to repair existing records already saved with localhost URLs.

---

## Phase 34: Fix PocketBase Public URL — Restore POCKETBASE_PUBLIC_URL

**Purpose**: Decouple the PocketBase public file URL from SITE_URL; use a dedicated, explicitly configured env var so images load correctly in all environments.

- [x] T131 Update `docker-compose.yml` `app` service: replace `SITE_URL=${SITE_URL}` with `POCKETBASE_PUBLIC_URL=${POCKETBASE_PUBLIC_URL}`. Keep `SITE_URL` as a separate entry for the Twig global.
- [x] T132 Update `public/index.php`: restore `POCKETBASE_PUBLIC_URL` as the source for `PocketBaseClient` `publicUrl`. Keep `SITE_URL` only for the Twig global injection.
- [x] T133 Update `scripts/fix_image_urls.php` to replace using `SITE_URL` with `POCKETBASE_PUBLIC_URL` as the repair target URL.
- [x] T134 Run `scripts/fix_image_urls.php` inside the container to revert `https://app.abrat-sp.orb.local:8090` back to `http://localhost:8090` in all `cover_image_url` and `app_settings` records.

---

## Phase 35: Ticket Check-In Database Schema

**Purpose**: Add check-in status columns to database.

### Implementation for Phase 35
- [x] T135 Create `scripts/migrations/003_add_ticket_checkin.php` to add column `checked_in_at` (DATETIME, default NULL) to the `tickets` table.
- [x] T136 Update `tests/TestCase.php` to add `checked_in_at DATETIME` column to the `tickets` table schema in `runMigrations()`.

---

## Phase 36: QR Code Generation on Ticket Print

**Purpose**: Display QR Code on printable tickets.

### Implementation for Phase 36
- [x] T137 Update `templates/admin/events/ticket_print.twig` to display a QR Code image using api.qrserver.com based on the ticket code.

---

## Phase 37: Admin Check-In Dashboard Screen (Priority: P1)

**Goal**: Renders the check-in screen, accesses camera for QR code scanning, and allows checking in attendees.

**Independent Test**: Navigate to `/admin/checkin`, search a ticket code or scan QR, confirm check-in, and check if ticket has `checked_in_at` set.

### Tests for Phase 37
- [x] T138 [US5] Integration test for ticket check-in verification and confirmation in `tests/Integration/TicketCheckInTest.php`.

### Implementation for Phase 37
- [x] T139 [US5] Implement `checkInTicket(string $code): bool` in `src/Services/AdminEventService.php`.
- [x] T140 [US5] Create check-in controller `src/Controllers/Admin/CheckinController.php` with `showCheckinForm` (GET) and `confirmCheckin` (POST) actions.
- [x] T141 [US5] Register routing for `/admin/checkin` (GET and POST) in `public/index.php`.
- [x] T142 [US5] Create Twig template `templates/admin/checkin.twig` with `html5-qrcode` scanner, manual input form, feedback card, and recent check-in list.

---

## Phase 38: Security Role recepcao & RBAC Configuration (Priority: P2)

**Goal**: Create receptionist role, allow access to checkin screen, but block all other admin screens.

**Independent Test**: Login as user with role `recepcao`, access `/admin` and get redirected to `/admin/checkin`, try to access `/admin/users` and get 403 Forbidden.

### Implementation for Phase 38
- [x] T143 [US6] Add `recepcao` select option in `templates/admin/users/form.twig` and role badge styling in `templates/admin/users/list.twig`.
- [x] T144 [US6] Update `src/Middleware/AdminAuthMiddleware.php` to restrict `recepcao` to only check-in and login/logout routes, redirect `/admin` to check-in, and block other routes with 403. Allow `financeiro` to access `/admin/checkin`.

---

## Phase 39: Event Participant Attendance Report (Priority: P2)

**Goal**: Provide a dashboard showing check-in statistics and participant attendance log with CSV export capability.

**Independent Test**: Access `/admin/events/{id}/report`, filter check-in status, and download CSV report.

### Tests for Phase 39
- [x] T145 [US7] Integration test for attendance report listing and CSV export in `tests/Integration/AttendanceReportTest.php`.

### Implementation for Phase 39
- [x] T146 [US7] Implement `showAttendanceReport` and `exportAttendanceCsv` methods in `src/Controllers/Admin/EventAdminController.php`.
- [x] T147 [US7] Register routes `GET /admin/events/{id}/report` and `GET /admin/events/{id}/report/export` in `public/index.php`.
- [x] T148 [US7] Create Twig template `templates/admin/events/report.twig` with metrics cards, filterable participant list table, and CSV export link.
- [x] T149 [US7] Update `templates/admin/events/list.twig` and `templates/admin/events/tickets.twig` to add navigation buttons to the attendance report.

---

## Phase 40: Polish & Cross-Cutting Concerns

**Purpose**: Validation and final cleanup for check-in features.

- [x] T150 Run phpunit and confirm all integration tests pass.
- [x] T151 Check docker logs during test execution and manual check-in flows to ensure no hidden 500/routing errors exist.

---

## Phase 41: Event Badge Dimensions Configuration (Priority: P2)

**Goal**: Configure custom dimensions for attendee badges per event in the SQLite database and administrative forms.

**Independent Test**: Create or edit an event in the admin dashboard, save badge dimensions (e.g. 10.0 x 5.0 cm), and check if the database stores them correctly.

- [x] T152 Create migration `scripts/migrations/004_add_event_badge_settings.php` to add `badge_width_cm` (DECIMAL, default 8.0) and `badge_height_cm` (DECIMAL, default 4.0) to the `events` table.
- [x] T153 Update in-memory SQLite schema in `tests/TestCase.php` to add `badge_width_cm` and `badge_height_cm` to the `events` table definition.
- [x] T154 [P] Update `templates/admin/events/form.twig` to add width and height inputs.
- [x] T155 Update `src/Services/AdminEventService.php` to handle saving and loading badge dimensions.

---

## Phase 42: PDF Badge Generation & Automatic Print Trigger (Priority: P2)

**Goal**: Generate PDF badges on check-in and launch browser print dialogue.

**Independent Test**: Complete check-in for a ticket, ensure that `/admin/tickets/{code}/badge` returns a valid PDF, and that the check-in screen opens it automatically.

- [x] T156 Update `composer.json` to include `dompdf/dompdf` and run `composer install`.
- [x] T157 Create Twig template `templates/admin/events/badge.twig` with attendee's name centered.
- [x] T158 Register route `/admin/tickets/{ticket_code}/badge` in `public/index.php`.
- [x] T159 [US8] Write integration tests in `tests/Integration/BadgePrintTest.php` verifying badge PDF generation and access control.
- [x] T160 [US8] Implement `showBadgePdf` in `src/Controllers/Admin/CheckinController.php` converting dimensions (cm to points) and rendering PDF.
- [x] T161 [US8] Update check-in success JSON response in `CheckinController::confirmCheckin` to return `badge_url`.
- [x] T162 [US8] Update `templates/admin/checkin.twig` frontend handler to open `badge_url` upon successful AJAX check-in.

---

## Phase 43: Polish & Cross-Cutting Concerns

**Purpose**: Validation and final cleanup for badge printing features.

- [x] T163 Run phpunit and confirm all integration tests pass.
- [x] T164 Check docker logs during test execution and manual badge printing/check-in flows to ensure no hidden errors exist.

---

## Dependencies & Execution Order

### Phase Dependencies

- **Setup (Phase 1)**: No dependencies - can start immediately
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
- **User Stories (Phase 3+)**: All depend on Foundational phase completion
  - User stories can then proceed in parallel (if staffed)
  - Or sequentially in priority order (P1 → P2 → P3)
- **Polish (Final Phase)**: Depends on all desired user stories being complete

### User Story Dependencies

- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories
- **User Story 2 (P1)**: Can start after Foundational (Phase 2) - Integrates with US1 orders, but ticket generation and admin dashboard can be tested independently
- **User Story 3 (P2)**: Can start after Foundational (Phase 2) - No dependencies on other stories
- **User Story 4 (P3)**: Can start after US2 is complete, leveraging the ticket issuance system
- **User Story 5 (P1)**: Depends on US2 (Ticket generation).
- **User Story 6 (P2)**: Depends on US5 (Check-in screen).
- **User Story 7 (P2)**: Depends on US5 (Check-in status tracking).
- **User Story 8 (P2)**: Depends on US5 (Check-in status tracking) and Phase 41 (Database schema).

### Within Each User Story

- Tests MUST be written and fail before implementation
- Models/Migrations before services
- Services before endpoints
- Core implementation before integration
- Story complete before moving to next priority

### Parallel Opportunities

- Database migration and schema updates (Phase 41) can run in parallel with frontend template changes (Phase 41 - T154).
- Creating the badge template (Phase 42 - T157) and registering routing (Phase 42 - T158) can be developed in parallel.

---

## Implementation Strategy

### Incremental Delivery

1. Complete Phase 41: Event Badge Dimensions Configuration (migration, forms, and service updates).
2. Complete Phase 42: PDF Badge Generation & Automatic Print Trigger (composer, Twig, controller, and check-in UI updates).
3. Validate all tests and logs.
4. Deploy/demo.
