# FREE 1.2.0 phase-2 CONTINUATION (waves 8-9) after the owner fixed the three
# wave-7 verifier findings directly on integration (commit 4ba2d1a: privacy
# class-name wiring + the missing wb_listora_recompute_listing_rating()
# canonical helper - live-verified: exporter + eraser register, recompute runs).
# Waves 5-7 are merged. The privacy-export-erase journey is carried into
# wave-8's functional tier so the FIXED flow gets its end-to-end browser pass.
version: 1

target:
  type: plugin
  slug: wb-listora
  path: "/Users/varundubey/Local Sites/wb-listora/app/public/wp-content/plugins/wb-listora"

goal: >
  Finish Free 1.2.0 phase 2: admin email-template editor MVP and bulk-edit
  listing actions, plus browser re-verification of the owner-fixed privacy
  export/erase flow. Additive minor only, 100k-scale, reuse-first.

contracts:
  hooks:
    actions:
      - "wb_listora_listing_submitted"
      - "wb_listora_after_bulk_moderate"
      - "wb_listora_listing_status_changed"
      - "wb_listora_search_resolved"
    filters:
      - "wb_listora_email_subject"
      - "wb_listora_email_content"
  options:
    - "wb_listora_settings"
  db_schema:
    - table: "listora_reviews"
    - table: "listora_claims"
    - table: "listora_favorites"
  email_output:
    - "wb_listora_email_subject"
    - "wb_listora_email_content"

migrations:
  - kind: option
    to: "wb_listora_email_templates"
    reason: >
      f8-email-editor-mvp: ONE new NON-AUTOLOADED option (update_option(...,
      false), AUD-F6 pattern) holding admin-edited subject+body per event. Read
      back via add_filter on the EXISTING wb_listora_email_subject_{event} /
      wb_listora_email_content_{event} filters - no template-file edits.
  - kind: hook
    to: "wb_listora_pre_bulk_edit"
    reason: >
      PRE-SANCTIONED headroom for f9-bulk-edit: if the implementer fires
      before/after actions around the bulk operations (consumers: audit,
      webhooks), properly wb_listora_-namespaced additive surface is approved
      in advance.
  - kind: hook
    to: "wb_listora_after_bulk_edit"
    reason: "Same pre-sanctioned headroom as wb_listora_pre_bulk_edit (f9-bulk-edit)."

standards:
  build_skills: [wp-plugin-development, ux-foundation, wp-i18n]
  audit_skills: [ux-audit, action-audit]
  phpstan_level: 6
  wpcs_standard: WordPress-Extra

gates:
  default_static: [php-lint, wpcs, phpstan]
  default_functional: [browser-smoke, qa-suite]

journeys:
  - id: privacy-export-erase
    role: admin
    steps:
      - "Tools -> Export Personal Data for a user with reviews + claims + favorites: the export ZIP includes WB Listora groups (wb-listora key registered - fixed in 4ba2d1a)"
      - "Tools -> Erase Personal Data: reviews anonymized AND search_index avg_rating/review_count recompute via wb_listora_recompute_listing_rating(); claims + favorites rows deleted"
      - "negative: a user with NO Listora PII produces an empty-but-valid response (no fatal); debug.log clean"
  - id: email-editor-roundtrip
    role: admin
    steps:
      - "Listora -> Settings -> Emails lists every notification event with an editable subject + body (textarea + allowed-placeholder legend)"
      - "edit subject + body for one event, save; the test-send (existing Notifications::send_test) renders the edited values"
      - "reset-to-default restores the shipped template; an UNEDITED event still renders from its template file (filter returns unchanged)"
      - "negative: paste a <script> into the body - kses strips it on save; reloaded value is sanitized"
      - "390px admin layout usable; ux-foundation card pattern; no native alert/confirm"
  - id: bulk-edit-listings
    role: admin
    steps:
      - "on the listings admin table, select several listings and choose a Listora bulk action: Approve, Reject, Assign category, or Feature/Unfeature"
      - "approve/reject transition status through Status_Manager (so notifications/webhooks fire); feature/unfeature route through the Featured service (so Pro credit rules apply)"
      - "a per-row result notice reports successes + failures; the action is capability-gated and nonce-protected"
      - "negative: a non-capable user does not see the actions; an invalid transition is reported as failed, not silently applied; batch bounded to 100/req"

waves:
  - id: wave-8-email-editor
    depends_on: []
    functional_gates: [browser-smoke, qa-suite]
    journeys: [email-editor-roundtrip, privacy-export-erase]
    directions:
      - id: f8-email-editor-mvp
        title: >
          Admin email-template editor MVP: a Settings -> Emails screen listing
          EVERY notification event (from the Notifications event map, including
          the new review_reminder) with an editable subject + body (textarea +
          allowed-placeholder legend) and per-event reset-to-default. Persist to
          ONE NON-AUTOLOADED option wb_listora_email_templates
          (update_option(..., false), AUD-F6 pattern). Read the saved values
          back by add_filter on the EXISTING wb_listora_email_subject_{event}
          ($subject,$vars) / wb_listora_email_content_{event} ($body,$vars)
          filters - NO template-file edits. Preview via the EXISTING
          Notifications::send_test(). kses-sanitize body on save. REUSE the
          ux-foundation settings-card pattern + admin header; render under the
          Notifications/Emails settings tab. MUST NOT add a rich builder, a new
          option per event, or an autoloaded option. 390px usable.
        journey: develop
        scope: ["includes/admin/class-email-templates-page.php", "includes/admin/class-settings-page.php", "assets/css/admin/email-templates*", "assets/js/admin/email-templates*"]
        skills: [wp-plugin-development, ux-foundation, wp-i18n]
        static_gates: [php-lint, wpcs, phpstan, ux-audit, wiring]

  - id: wave-9-bulk-edit
    depends_on: [wave-8-email-editor]
    functional_gates: [browser-smoke, qa-suite]
    journeys: [bulk-edit-listings]
    directions:
      - id: f9-bulk-edit
        title: >
          Bulk-edit listing actions on the WP listings table beyond core: bulk
          Approve/Reject, bulk Assign-category, bulk Feature/Unfeature. REUSE:
          the bulk-moderate transition semantics already in
          Listings_Controller::bulk_moderate (do NOT duplicate transition
          logic); Status_Manager::is_valid_transition()/get_statuses() for
          approve/reject so notifications + webhooks fire; the Featured service
          (Featured::feature_listing/unfeature_listing) so Pro credit rules
          apply; Term_Helper for category assignment. Capability-gated +
          nonce-protected; bounded batches (100/req, same as bulk-moderate);
          per-row result notice. Wire via the WP list-table bulk_actions /
          handle_bulk_actions hooks in a NEW class-listing-bulk-actions.php;
          do NOT bloat class-listing-columns.php.
        journey: develop
        scope: ["includes/admin/class-listing-bulk-actions.php", "assets/js/admin/bulk-edit*"]
        skills: [wp-plugin-development, ux-foundation]
        static_gates: [php-lint, wpcs, phpstan, wiring]
