feat(cpt): consolidate peptide CPT with PSA; drop pr_peptide (v0.2.0)
Resolves the rewrite slug collision that was 404'ing all 89 production peptide detail pages. PR Core v0.1.1 registered an empty pr_peptide CPT claiming /peptides/%postname%/; WP's rewrite resolver picked it over PSA's populated peptide CPT. This release consolidates both registrations onto a single peptide CPT owned by PR Core. PSA v4.5.0 drops its registration in favor of this one. ## Contract (per CTO msg 02) - POST_TYPE: pr_peptide -> peptide - TAX_CATEGORY: pr_peptide_category -> peptide_category - TAX_FAMILY const removed (pr_peptide_family was never populated) - CPT + taxonomy registration guarded with post_type_exists() / taxonomy_exists() so deploy order between PR Core and PSA is forgiving - Args harmonized as superset of PSA + prior PR Core (thumbnail added to supports; capability_type + map_meta_cap preserved) - Activator: flush_rewrite_rules(false) on activation; new maybe_flush_on_version_change() handler hooked at init:999 for in-place updates that bypass the activation hook (e.g. SCP deploys) - uninstall.php: blanket DELETE replaced with JOIN on _pr_core_authored so PSA-authored peptide posts (the 89 canonical monographs) are never destroyed; peptide_category terms preserved (shared ownership) - Scrub scope: narrow — CPT-slug-derived identifiers only; class names, file names, PR_CORE_* constants, pr_core_* options, and pr-core/v1 REST namespace remain ## Docs - ARCHITECTURE.md: new Key Decision #7 (v0.2.0 consolidation) and §2.9 Uninstall specification - CONVENTIONS.md: CPT Ownership rule + _pr_core_authored flag contract ## Tests - Lightweight harness (tests/bootstrap.php) that stubs the handful of WP functions exercised by the CPT class - tests/unit/test-peptide-cpt.php asserts: constants match contract, TAX_FAMILY is removed, guard no-ops when post_type_exists/taxonomy_exists returns true, args payload shape (thumbnail in supports, rewrite slug, REST namespace), hooks wired - CI: new 'Unit tests (lightweight, no PHPUnit)' step in lint-php job, runs across PHP 8.1/8.2/8.3. Full PHPUnit + wp-env harness is a follow-up Refs: convo/prcore/threads/2026-04-peptides-cpt-collision/02-cto-correction.md
This commit is contained in:
@@ -61,3 +61,14 @@ Values: `prescription`, `ruo`, `otc`, `restricted`, `banned`, `unclear`. Validat
|
||||
## Supersede Pattern (Soft Delete)
|
||||
|
||||
Dosing rows and legal cells use a `superseded_by_id` column instead of hard deletes. When a correction is needed, the old row gets `superseded_by_id` set to the new row's ID. Queries for "active" data filter on `superseded_by_id IS NULL`. This preserves full audit history.
|
||||
|
||||
## CPT Ownership
|
||||
|
||||
- **One plugin owns each CPT.** PR Core owns the `peptide` CPT and the `peptide_category` taxonomy (as of v0.2.0). No other plugin in this ecosystem registers these post types or taxonomies directly.
|
||||
- **All registrations must guard with existence checks.** CPT registrations call `if ( post_type_exists( $slug ) ) return;` before `register_post_type()`, and taxonomy registrations call `if ( taxonomy_exists( $slug ) ) return;` before `register_taxonomy()`. This makes deploy order between plugins irrelevant — whichever runs first wins, the other no-ops — and prevents rewrite-slug collisions when two plugins temporarily overlap during a transition.
|
||||
- **Consumers read, do not register.** Plugins that need to query or display `peptide` posts (PSA, PR Theme, PRAutoBlogger, Peptide News, Tier 1 tools) call `get_posts( [ 'post_type' => 'peptide' ] )` / `WP_Query` without registering the CPT themselves. If a consumer plugin needs its own custom post type for a different domain (e.g., `reconstitution_protocol`), it registers its own slug and does not touch `peptide`.
|
||||
- **Meta keys are plugin-namespaced, not CPT-namespaced.** PR Core writes `_pr_core_*` or bare keys registered via `register_post_meta()`. PSA writes `psa_*`. The two namespaces coexist on the same `peptide` post because they don't collide.
|
||||
|
||||
## `_pr_core_authored` Flag
|
||||
|
||||
Any `peptide` post created via PR Core's own UI (not authored via PSA's meta boxes) must be tagged with post-meta key `_pr_core_authored` = `1`. This is the flag `uninstall.php` uses to scope teardown to plugin-owned posts only. Posts originating from PSA (the 89 canonical peptide monographs on production) do not carry this flag and are never deleted on PR Core uninstall.
|
||||
|
||||
Reference in New Issue
Block a user