=== ESP INSTANDA Start Quote Integration === Contributors: getfused Requires at least: 7.0 Requires PHP: 8.5 Stable tag: 1.1.0 Pushes Gravity Forms "Start a Quote" submissions into INSTANDA's Package API with write-ahead transaction logging, native entry recording, admin resubmit, and a test-mode lock. == Changelog == = 1.1.0 = Remediation of the 2026-07 security/reliability/PII audit (see docs/audit-esp-instanda-2026-07.md). No duplicate policies / no lost quotes: * Dedupe key is now content-addressed (form id + mapped field values) instead of a per-request token, so an identical re-POST or a retry-after-error reuses the existing quote instead of creating a second one at INSTANDA (F-01). Adds a 30-minute short-circuit window and a content-key race lock. * Refuse to resubmit an already-delivered transaction (F-12); scope the resubmit self-recovery guard to the content dedupe key so a customer's *different* event is not skipped (F-18). * A 2xx response with a missing/empty quoteRef is now recorded as ambiguous (possible_duplicate = 1), not a hard failure (F-10, F-17). * Aborts the StartQuote when the write-ahead insert fails, so no unaudited call is made (F-14). Go-live safety: * switch_to_live() now also sets the environment to Live; previously the go-live button left real quotes hitting the Test endpoint (F-03). * Go-live advisory flags when more than one active INSTANDA feed exists (F-02). Security & PII: * Corrected the at-rest-secret docblock: the "DB dump never exposes a secret" guarantee only holds when SPG_INSTANDA_KEY is set as a constant (F-04). * Retention now scrubs PII from stale failed/pending rows (previously kept forever) and exempts stranded delivered leads from the purge (F-05, F-13); wired WordPress's Erase Personal Data tool to delete a customer's transactions (F-05). * Uninstall now removes ALL plugin options and transients, including the encrypted password and its key (F-15). * Added per-IP (20/h) and per-email (5/h) rate limiting on the public create (F-06). Reliability & correctness: * Timestamps are written in UTC to match the retention/dedupe cutoffs and displayed in site-local time (F-07). NOTE: rows created before 1.1.0 were stored in site-local time; clear the transaction table (test data) at deploy to avoid a mixed-timezone history. * Fail closed on an unexpected error in the create path (no quote-less entry) and alert admins, instead of silently passing (F-11); log when async recording cannot resolve a transaction (F-09). * The "Gravity Forms required" admin notice is now shown even when Gravity Forms is inactive (F-16); the daily retention cron self-heals on admin_init (F-22). * Resubmit re-validates the stored payload before re-sending (F-19); the Retries count is now incremented and the resubmit-success notification event is dispatched (F-20). Theme: * The Form-5 date-range inline JS is emitted only on pages that embed a Gravity Form and its MutationObserver now disconnects instead of watching the DOM forever (F-23). Operations required alongside this release (see the audit report, Ops checklist): * Set SPG_INSTANDA_KEY + SPG_INSTANDA_USERNAME_LIVE/_PASSWORD_LIVE + SPG_INSTANDA_ENV in production wp-config.php (blocking) - OPS-1 / F-04. * Deactivate the INSTANDA feed on the test Form 6 in production (blocking) - OPS-3 / F-02. * Configure espinstanda_alert_emails and the quote-success notification (blocking) - OPS-4. * Rotate the SendGrid API key out of committed wp-config.php - OPS-2 / F-08. * Add reCAPTCHA/Akismet to the canonical quote form - OPS-5 / F-06. = 1.0.7 = * Initial audited release.