Repository navigation
1.9.79: the optimizer's card says when its webhook stops receiving - #298
Merged
Merged
Conversation
My Account › API Integrations showed the Landing Page Optimizer pairing as "Connected" from lpo_status alone. Once the webhook the pairing made was marked dead (one delivery failed 6 times) or deleted in LTV Settings, the optimizer stopped receiving events and the card still said Connected. Prosper202\Lpo\PairingWebhook::state() reads the webhook lpo_bridge_config names by id, scoped to the account, and answers receiving, dead, off (disabled), gone or unnamed (the record names no webhook, or not as an integer above 0). The card reads "Connected" only while it is receiving. Dead, off and gone read "Not receiving events", with a sentence naming the webhook: a dead one is revived in LTV Settings once its endpoint answers again, and the card links there; one that is gone or off is paired again with Disconnect and Connect. An unnamed record, or a status read that fails (logged), reads "Status unknown": a read that does not know is never "Connected" (CLAUDE.md #11). Tests: PairingWebhookTest (each answer's sentence); PairingCardWebhook StatusIntegrationTest draws the real page as the account (page-runner) for each state, another account's webhook under the paired id, a failed read (the table renamed away) and an unpaired install. tests/live/lpo-card-webhook-status.sh is the live pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Contributor
Contributor
tearDownAfterClass() put a renamed-away 202_ltv_webhooks back with RENAME TABLE IF EXISTS, which is MariaDB's: MySQL 8.0 refuses it, and CI's integration job failed there after all eight tests passed. It now reads information_schema.TABLES and renames the table back, or drops the copy where the schema installer has made the table again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr
Brings in 1.9.79's new commits. The conflicts were in 202-config/changelogs.json, changelogs.txt, tests/live/README.md, where both sides added lines: the incoming lines are kept as they are and this branch's follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backlog: BZZ9
Not stacked. This branch is made from
1.9.79and depends on no open PR. The Revive button it points to arrives with #289. Until #289 merges, the card says "Fix the endpoint, then revive the webhook in LTV Settings." and uses none of #289's code.What was wrong
My Account › API Integrations showed the Landing Page Optimizer pairing as Connected from
lpo_statusalone. The pairing makes a wildcard LTV webhook and stores its id inlpo_bridge_config. That webhook can stop receiving events in two ways:deadonce one delivery fails 6 times, which, with 1.9.79: the minutely cron sends LTV webhooks, within a budget #273, is about an hour of a down endpoint;Either way the optimizer stops receiving conversions and engagement, and the card still said Connected. I measured this live: with the webhook dead, deleted, or not named by the pairing record, the card on
1.9.79read "Connected" every time.What changed
Prosper202\Lpo\PairingWebhook::state()reads the webhooklpo_bridge_confignames, throughMysqlWebhookRepository::get(), so the read is scoped to the account. Its answers:active;dead;disabled;(int)of what it finds, so"12abc"is no id.A database failure throws. The page logs it and reads it as unknown, never as an answer.
The card, local to the Landing Page Optimizer panel in
202-account/api-integrations.php:tracking202/analyze/ltv.php?view=settings)The sentences live in
PairingWebhook::notice(), so the page adds only a few lines. "6" isMysqlWebhookRepository::MAX_ATTEMPTS.p202-pill--bad/--warn, thep202_flash()helper (the kit's flash), and abtnin the existingp202-toolbar. Disconnect already handles a webhook that is gone: it catchesRecordNotFoundException.Decisions to check
ctx_keywas derived, is gone with it.disabled. 1.9.79: a dead LTV webhook can be revived, and is sent what it missed in the last 7 days #289'srevive()would take it, but LTV Settings shows Revive only on a dead row.enqueue()does not consultlpo_bridge_config. Saying it receives nothing would be a guess in the other direction.lpo_statusisactive. Unpaired installs render as before.Tests
tests/Lpo/PairingCardWebhookStatusIntegrationTest.php(@group integration, scratch database, 8 tests). It draws the real page as the account throughtests/Setup/fixtures/page-runner.php, with the account holdingaccess_to_api_integrations, and reads the card's<section>. The cases:'',not json,{},"Nabc",0and a list;202_ltv_webhooksrenamed away for the request;tests/Lpo/PairingWebhookTest.php: each answer's sentence, and that only receiving says nothing.mktemp, compared withcmpand restored:lpo_statusalonetestADeadWebhookSaysTheOptimizerGetsNothingAndWhereToReviveIttestAWebhookThatNoLongerExistsReadsAsNotReceivingtestADisabledWebhookReadsAsNotReceiving(int)testAPairingRecordThatNamesNoWebhookIsNotConnectedtestAWebhookThatCannotBeReadIsSaidSoNeverConnectedtestADeadWebhookSays…testAWebhookThatNoLongerExists…notice()says nothing for deadPairingWebhookTest::testADeadWebhookNamesItsIdAndWhereToReviveItMySQL 8 (a49cae7)
On 15c326d, CI's integration job failed in this test's
tearDownAfterClass(), after all 8 tests passed. The teardown usedRENAME TABLE IF EXISTS, which is MariaDB-only syntax; MySQL 8.0 refuses it. The teardown now readsinformation_schema.TABLESand then either:RENAME TABLE; orBoth branches ran here:
finallyrestore removed, the teardown renamed the table back.Not verified against MySQL 8 locally (only MariaDB 10.11 is here). The statements left are
SELECT … FROM information_schema.TABLES,RENAME TABLEandDROP TABLE, which MySQL 8 has. My other two branches' tests (#296, and 2RBE's) rename no table. TheirDROP TRIGGER IF EXISTSandCREATE TRIGGER … FOR EACH ROW IF … END IFare MySQL 8 syntax, the formTrackerLinkTransactionIntegrationTestalready runs in CI.Live pass
tests/live/lpo-card-webhook-status.sh(new) ran on an instance from this branch: PHP 8.3.6php -Sthrough the eval router, MariaDB 10.11, port 8321. 14 passed, 0 failed. The same script against1.9.79's page gave 4 passed and 10 failed: Connected in every state.202-login.php's own form and makes a wildcard webhook throughPOST /ltv/webhooks. It then writes the pairing as the card's Connect writes it:lpo_status = active, andlpo_bridge_confignaming the webhook. Connect itself was not pressed, because it calls the hosted optimizer (pairInit/pairComplete), which a scratch instance must not reach.DELETE /ltv/webhooks/{id}(204): "Not receiving events", the instruction to pair again, and no link.The pass puts the account's pairing back as it found it on exit.
Licence (the stub is down)
install.php's POST checks the key with my.tracking202.com, so I did not run it. A scratch script ran the installer's own steps without the licence form:INSTALL::install_databases(),InstallAccount::create(), the202_api_keysrow andinstall_database_partitions(). AutoCron and the daily email registration, which call outside services, were left out.HTTPS_PROXY,https_proxy,HTTP_PROXY,http_proxy) pointed athttp://127.0.0.1:9, a closed port, and withNO_PROXY=localhost,127.0.0.1, so there was no bypass for my.tracking202.com. The licence check then gets no answer, andAUTH::is_valid_api_key()fails open, as it does on any network failure. Every licence check in the server log isFailed to connect to 127.0.0.1 port 9. Nothing reached the licence service, and no code or session was changed for it.Verification
.claude/skills/p202-verify/scripts/verify.sh --since origin/1.9.79 --changed, on 15c326d, PHP 8.3.6. The unit tier ran 6,106 tests with 5 skipped: the 4 documented "User class requires DB singleton" skips, andCronEntryPointsFailLoudlyTest's executed case, which skips while the worktree holds the live instance's202-config.php. a49cae7 changes only the integration test's teardown; that suite was rerun after it (8 tests OK).Why phpcs FAILs. The ratchet counts
202-account/api-integrations.phpas made worse: 861 errors against 832 at HEAD, with 90 warnings at both.Generic.WhiteSpace.DisallowTabIndent, from the card's new lines.Beyond the script:
PairingCardWebhookStatusIntegrationTestagainst a scratch MariaDB 10.11 database: OK, 8 tests, 96 assertions.shellcheck --severity=warningon the new live script: clean.Not run:
tests/run-integration-suites.sh;Merging
api-integrations.phpis touched by 1.9.79: API Integrations lists the signed-in account's own DNI networks, and no key reaches the browser #266, 1.9.79: PayKickstart's product IPN, verified with each campaign's key #268, 1.9.79: JVZoo's JVZIPN at jvzoo.php, for affiliates and vendors (stacked on #268) #272 and 1.9.79: ClickBank's INS works for every account, decrypted with each account's own key #276. This change sits inside the Landing Page Optimizer panel's own PHP block and markup, so expect no overlap.tests/live/README.mdlines go after 1.9.79's.🤖 Generated with Claude Code
https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr