Skip to content

feat(remote): GET /counts — WordPress's published counts per type and media, for a price before payment; /about names the capability - #58

Merged
ABB65 merged 3 commits into
mainfrom
feat/about-counts
Oct 9, 2026
Merged

ABB65 merged 3 commits into
mainfrom
feat/about-counts

Conversation

@ABB65

@ABB65 ABB65 commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

What

Gate item 10, S3 (Migrate's sitemap pricing, design .internal/runs/2026-10-09/t8/sitemap-pricing-design.md). A site whose REST API is closed to readers (rest_blocked) can still be priced exactly, by Bridge, before payment. Migrate then recounts a Bridge site on what WordPress itself counts, not on a sitemap figure (S2b, the Migrate side, comes after Bridge 0.7.0).

  • GET /contentrain-bridge/v1/counts:
    • Permission: the same reader permission as an export (permitted: an application password of an administrator with the export capability, or the paired key). Never public.
    • Answer: { format: 'contentrain-bridge-counts@1', published: { <type>: n }, attachments: n }.
      • published uses wp_count_posts(type)->publish over the same content types an export reads (Source::content_types()), sorted.
      • attachments is the media count (inherit).
    • Numbers only: no titles, no addresses, no site data.
  • GET /about now carries capabilities: ['counts'], so a reader can tell an older plugin without comparing versions. It still carries no site data.
  • README route table updated.

Merge with t3's robots toggle (wordpress-bridge#57): both touch about(). Whichever merges second makes it 'capabilities' => array( 'counts', 'robots_allow' ). t3 then writes the 0.7.0 bump + WP.org readme PR; ORK pushes the tag.

Tests

tests/key.php (Docker acceptance):

  • /about names the counts capability and carries no site data.
  • /counts signed out with no key → 401, never public.
  • /counts with the paired key → 200, and the numbers equal wp_count_posts per type and media.
  • The site's administrator without the export capability → 403 bridge_key_forbidden.

Gate

Docker acceptance on 2601293 (base main 88b5e8e, unchanged since), under its own compose project (COMPOSE_PROJECT_NAME=t8s3, port 8194), with containers and volumes down afterwards:

  • tests/run.sh (integration): 394 checks passed.
  • tests/coverage.sh: coverage 57 checks, key.php 51 checks (incl. the 4 above), the remote-export suite 80 checks.
    • Its last step, coverage-rawir.mjs, first failed with ERR_MODULE_NOT_FOUND @contentrain/wp-import: the worktree had no npm ci, an environment fault. After npm ci it was re-run on the same Docker output: RawIR parity 12/12, and verify-store passed (contentrain validate: 10 models, 48 entries; canonical byte parity: 46 files; 16 documents with frontmatter).
  • tests/check-plugin.sh: Plugin Check 0 errors, 26 warnings (not compared with main here; the 19 lines this PR adds add no new function calls besides wp_count_posts).
  • npm test: 13/13. test:secrets: 86 files, 0 secrets (negative control passes).

Reviewer: t3.

Update 2026-10-09 19:25: main merged (#57) + t3's SHOULD

  • Merged bridge main 2a712aa (feat(robots): the owner can let Contentrain Migrate read the site through robots.txt #57, robots toggle). No rebase. In about() the capabilities are now array( 'counts', 'robots_allow' ) and the robots state is kept. tests/key.php expects both capabilities; README /about row updated.
  • t3's SHOULD, done here, not in 0.7.0: /counts published lists content types only. attachment is left out (media is attachments), and so are WordPress's site-building types (wp_block, wp_template, wp_template_part, wp_navigation, wp_font_family, wp_font_face, wp_global_styles, nav_menu_item). That is the same list as migrate's NOT_CONTENT_TYPES (packages/discover/src/credentials.ts:104), minus post/page, which are content here. Pinned in tests/key.php.
  • Docker acceptance on 2103eda (project t8s3, port 8194, down afterwards):
    • run.sh 394 ✓
    • coverage 57 ✓
    • remote 80 ✓
    • key.php 52 ✓ (+1, the content-types-only check)
    • robots 61 ✓
    • RawIR parity 12/12
    • Plugin Check 0 errors / 26 warnings
    • npm test 13/13

ABB65 and others added 2 commits October 9, 2026 15:54
… media, for a price before payment; /about names the capability
# Conflicts:
#	includes/class-contentrain-bridge-remote.php
@ABB65

ABB65 commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

Code review (t3, head 2601293). Nothing blocking. Main (with #57) is already merged in, and capabilities is array( 'counts', 'robots_allow' ) as agreed. CI is still running.

OK

  • /counts uses the export's own permission (permitted); the test shows it is never public (401/403 signed out).
  • The response is numbers only (asserted), counted by wp_count_posts.
  • /about carries no site data.

SHOULD (either here or in the 0.7.0 PR)
Source::content_types() is the export's list, so published also has entries that are not content to price:

  • attachment: publish is always 0, because attachments are inherit. The real number is the separate attachments field, so the two fields can be confused.
  • wp_block, wp_navigation, wp_template and wp_template_part.

Either leave those out of published, or say in the README row that a reader prices only its own content types. Migrate's reader has to know which to use either way.

@ABB65
ABB65 merged commit 440aa52 into main Oct 9, 2026
9 checks passed
@ABB65
ABB65 deleted the feat/about-counts branch October 9, 2026 16:32
@ABB65 ABB65 mentioned this pull request Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant