Trac Notifications: ticket-read DAO methods + Trac_API caching layer#655
Draft
obenland wants to merge 7 commits into
Draft
Trac Notifications: ticket-read DAO methods + Trac_API caching layer#655obenland wants to merge 7 commits into
obenland wants to merge 7 commits into
Conversation
…layer. Adds the data and caching plumbing the upcoming JSON API endpoint and MCP abilities will share. Lays the foundation without yet exposing any new HTTP surface — that lands in a follow-up PR. Trac_Notifications_DB gains five read methods covering data the existing class did not expose: comment bodies, comment count, the non-comment changelog, attachments, and the full custom-fields map. The composite get_trac_ticket_full() assembles a single ticket payload and returns the most recent N comments in chronological order using count + offset. class-trac-api.php is a new wp.org-side wrapper around Trac_Notifications_HTTP_Client. It memoises calls in memcached with separate fresh and stale TTLs, falls back to stale data when Trac is unreachable, and trips a per-trac circuit breaker so a degraded Trac is not hammered by retries. Missing tickets are negatively cached (sentinel) to absorb 404 floods. A missing TRAC_NOTIFICATIONS_API_KEY is logged loudly so a permanent misconfiguration is distinguishable from a transient outage. Includes a standalone PHPUnit suite (36 tests, 90 assertions) following the pattern used by other no-WP-dependency tests in the repo, plus a CI matrix entry to run them on every PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Declares the `$db` property explicitly on Trac_Notifications_DB so PHP 8.2+ no longer flags dynamic-property creation. Switches the two new test classes from `@group` docblock metadata to `#[Group]` attributes, which PHPUnit 12 will require. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aab7b1b to
31f45be
Compare
Brings the new files in line with --standard=WordPress (stricter than the project's tuned ruleset that CI enforces). Adds the short descriptions WPCS expects on every docblock, capitalises a couple of sentences, and fully-stops the trailing inline comments inside the composite fixtures. Moves the three test-fake classes from tests/ into tests/includes/ to mirror the WordPress core test-scaffold convention and keep the tests/ directory focused on actual TestCase classes. bootstrap.php now requires them from the new path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lets external callers (HTTP API endpoint, future MCP abilities) discover tickets by an allowlisted set of equality filters plus optional focuses / keywords substring matches and a changed_since date range. Returns a richer column set than the existing get_tickets_by(): id, summary, status, resolution, type, component, priority, milestone, owner, reporter, changetime. A safety guard refuses unscoped focuses / keywords LIKE queries — the worst performance shape, since neither field is indexed. Callers must combine those filters with at least one equality scope or changed_since to limit blast radius. The existing equality filters all narrow the row set the LIKE evaluates against. get_trac_ticket_focuses() now delegates to get_trac_ticket_custom_fields() to drop the duplicate ticket_custom query. Return contract preserved. Both new closures use the `static` keyword so they don't bind `$this`. 54 unit tests, 123 assertions, all passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trac_API now calls wp_cache_get/wp_cache_set directly with the 'trac_api' group instead of going through an injectable cache backend. Drops the class-trac-api-wpcache.php adapter — it existed only to make tests inject a stateful in-memory cache, which we now achieve with a thin wp_cache_* polyfill in tests/bootstrap.php backed by a static Test_Cache class. Net result is the same testability with one less production class. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trust callers — the HTTP gateway and MCP ability will each validate their own trac slug input (URL allowlist for the gateway, enum schema for MCP) before reaching this class. A bad slug now flows through to a failing HTTP call and the breaker, which is the same path that a flaky Trac box takes. One less premature validation point. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The earlier commit added the entry again on top of the one upstream already shipped (3622a12). Keep the new .phpunit.cache/ directory entry, drop the duplicate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
First of a planned multi-PR feature that surfaces WordPress.org Trac data as JSON over HTTP. This PR lays the data and caching plumbing inside the
trac-notificationsplugin without yet exposing any new HTTP surface — that lands in follow-up work.Architecture context
What's in this PR
Trac_Notifications_DBgains five read methods for data the existing class did not expose:get_trac_ticket_full( $id, $opts )— composite payload (one Trac round-trip per ticket)get_trac_ticket_comments( $id, $limit, $offset )— ASC-ordered window of comment bodiesget_trac_ticket_comment_count( $id )— total, for pagination + most-recent-N mathget_trac_ticket_changelog( $id )— every non-comment field change (status, owner, keywords, milestone, …)get_trac_ticket_attachments( $id )— filename, size, time, description, authorget_trac_ticket_custom_fields( $id )— fullname => valuemap (generalises the focuses-only accessor)The composite returns the most recent N comments in chronological order by computing
offset = max(0, total - limit), so large tickets don't dump hundreds of KB by default. All time columns are returned raw (microseconds since epoch) —Trac_APIconverts them at the output boundary.Trac_API(new) is the wp.org-side caching wrapper aroundTrac_Notifications_HTTP_Client:core.tracoutage cannot blockmeta.traccallsTRAC_NOTIFICATIONS_API_KEYis logged loudly (operational config error ≠ transient outage)Unit tests: new PHPUnit setup at
wordpress.org/public_html/wp-content/plugins/trac-notifications/, 36 tests, 90 assertions, no WordPress dependency. Follows the existingcore/serve-happy/1.0/testsandcommon/includes/tests/slack/tracpatterns. Added a matrix entry to.github/workflows/unit-tests.yml.What's NOT in this PR
api.wordpress.org/dotorg/trac/...— separate PRwporg-abilities— separate PR/core/trac-search/1.0/endpoint — separate taskcontributors/,keywords/,releases/,components/) — these mostly read Make/Handbook content rather than Trac DB, so each becomes its own small PRDeployment notes
The DAO additions need to be deployed to the Trac boxes (core.trac and meta.trac) before the follow-up HTTP gateway PR can be tested end-to-end. The wp.org-side caching layer can be exercised against the existing
wpapiendpoint as long as only existing methods are called.Test plan
BASE_REF=trunk php .github/bin/phpcs-branch.phpreports no violations🤖 Generated with Claude Code