# Mailshot Implementation Plan ## 1. Purpose Define the implementation approach for delivering the Mailshot feature as a WordPress plugin while keeping plugin runtime code pure and minimally coupled to fixture/test concerns. This plan is governed by: * `requirements/environment.md` * `requirements/mailshot.md` * `requirements/mailshot_data_source.md` * `requirements/ui_design.md` * `requirements/test_environments.md` ## 2. Implementation Principles 1. Pure plugin runtime - Production plugin code must not branch on fixture/test mode. - No fixture-only conditionals in production classes. - Fixture behavior must be provided by bootstrap/injection, not by runtime feature flags. 2. Explicit dependency boundaries - Isolate WordPress APIs behind thin adapters/services. - Isolate DB access by repository + DB-router layers. - Isolate transport concerns (SMTP/IMAP, PDF, templating) behind interfaces. 3. Environment routing must be explicit - Write-path state/assets/logs in `MAILSHOTS_REMOTE_MYSQL_DB`. - Recipient/source-data reads in `MEMBERS_REMOTE_MYSQL_DB`. 4. Same code paths in fixture and production - Fixture should execute the same plugin service layer and SQL compilation paths. - Differences are only in bootstrap wiring and data source choice. ## 3. Target Architecture ## 3.1 Modules * `Admin/UI`: - WordPress admin pages and handlers. * `Application Services`: - Mailshot CRUD service - Data source DSL service (parse/validate/compile/preview) - Test/Run orchestration service - PDF generation/download service * `Infrastructure`: - DB router (`MAILSHOTS_REMOTE_MYSQL_DB` writes, `MEMBERS_REMOTE_MYSQL_DB` reads) - SMTP sender - IMAP sent-copy appender - Twig renderer - Dompdf renderer * `Repositories`: - Mailshots, queries, attachments, pdf assets, last run, credentials ## 3.2 WordPress API boundary Create wrapper interfaces for frequently used WordPress functions (for example current user lookup, capability checks, nonce checks, response helpers, URL builders), and inject implementations at bootstrap. This keeps fixture setup simple and keeps plugin code independent of direct global-function calls where practical. ## 4. Credentials Strategy (aligned to fixture goals) To minimize fixture complexity and avoid full WordPress-user emulation: 1. Store SMTP/IMAP credentials in a mailshots-side table in `MAILSHOTS_REMOTE_MYSQL_DB` (for example `mailshot_credentials`). 2. Resolve the active credential row via a credential-resolver service: - Production resolver: by current WordPress user id/capability context. - Fixture resolver: by explicit env key (for example `MAILSHOTS_FIXTURE_CREDENTIAL_KEY`) or a designated default row. 3. Keep resolver selection in bootstrap wiring only; service-layer send/run logic remains unchanged. This preserves pure plugin logic while making fixture execution straightforward. ## 5. Fixture Environment Design ## 5.1 Fixture responsibilities * Provide WordPress-specific runtime expectations needed by plugin code: - function availability - hook registration behavior - request context stubs * Execute plugin endpoints/services against real remote DBs where available. * Optionally run against local emulated datasets for faster iteration. ## 5.2 Fixture composition * `tests/fixture/wp_shim.php` - Provide minimal implementations for required WP functions used by plugin code. * `tests/fixture/bootstrap.php` - Load env, initialize adapters, include plugin entrypoints. * `tests/fixture/router.php` (or equivalent) - Route fixture HTTP/API requests into plugin handlers. * `tests/fixture/data/` - Optional local SQL snapshots/seed data. ## 5.3 Data access modes Mode A: Remote-backed (default for integration confidence) * Reads from `MEMBERS_REMOTE_MYSQL_DB` * Writes to `MAILSHOTS_REMOTE_MYSQL_DB` Mode B: Local-emulated (optional for fast dev loops) * Local DB seeded from fixture snapshots * Same SQL/compiler/service code paths as Mode A * Used for rapid debugging and CI speed where remote access is constrained ## 6. Delivery Phases ## Phase 0: Foundation and contracts * Finalize table contracts (including new credential table and migration SQL scripts). * Finalize DB router config contracts. * Define plugin capability names and admin-page slugs. * Add implementation traceability map from requirements -> modules/tests. Exit criteria: * DB and API contracts documented and approved. ## Phase 1: Infrastructure skeleton * Implement DB router and repository scaffolds. * Implement WP adapter interfaces + production implementations. * Implement fixture bootstrap + WP shim baseline. * Implement structured error model and logging helpers. Exit criteria: * Plugin boots in WordPress and fixture with shared service container wiring. ## Phase 2: Data source pipeline * Implement DSL tokenizer/parser/validator/compiler modules. * Implement source-field metadata provider and preview endpoints. * Implement data-source CRUD APIs and admin page. * Add parser/validator/compile tests and preview shape tests. Exit criteria: * Data source CRUD + validate + preview working in both WordPress and fixture. ## Phase 3: Mailshot management and assets * Implement mailshot CRUD page and APIs. * Implement attachment and PDF asset CRUD + file handling. * Implement token insertion helpers for editor UI. * Implement last-run repository operations. Exit criteria: * Operators can configure mailshots and assets end-to-end. ## Phase 4: Test send, run send, and retry * Implement Twig rendering pipeline (`Subject`, `Message`, `PDFAttachment`). * Implement SMTP send + IMAP sent-copy contract behavior. * Implement run orchestration, counters, logging, and retry semantics. * Implement `MAILSHOT_TEST_TO_DEFAULT` blank/default validation behavior. Exit criteria: * Test send and run send pass integration tests with warning/error behavior aligned to requirements. ## Phase 5: PDF output and packaging * Implement per-recipient PDF generation, zip and merged output. * Finalize deployment/package scripts and release checks. * Capture verification evidence in `results/`. Exit criteria: * Full feature acceptance in staging/pre-production checklist. ## 7. Testing Plan 1. Unit/static tests - DSL parser/validator/compiler, repository-level behavior, renderer safety. 2. Fixture integration tests - WordPress shim + plugin services - Remote-backed and optional local-emulated modes - Send/run/retry and preview flows 3. WordPress integration tests - Admin-page registration, capability checks, nonce/auth behavior, endpoint wiring. 4. Staging tests - Real connectivity, credential resolution, IMAP sent-copy, operational observability. ## 8. Purity Guardrails (must-pass) * No `if fixture/test` branching in production services. * No fixture-specific env checks in core orchestration classes. * Fixture-specific code limited to `tests/fixture/*` (or equivalent harness folder). * All production runtime dependencies resolved via adapters/interfaces. ## 9. Deliverables * Migration SQL scripts for `MAILSHOTS_REMOTE_MYSQL_DB` tables (including credentials table). * Plugin modules/pages/APIs per requirements. * Fixture harness with WordPress function shim and remote/local data modes. * Automated test suite and verification evidence in `results/`. * Deployment/package scripts and release checklist updates. ## 10. Open Decisions To Confirm Before Phase 1 Completion 1. Final name/schema of credentials table in `MAILSHOTS_REMOTE_MYSQL_DB`. 2. Credential resolver rule precedence: - user-bound first vs explicit profile key first. 3. Local emulation scope: - full `members` subset vs targeted minimal fixture datasets. 4. CI strategy: - remote-backed only vs dual-mode (remote + local emulated).