Implements ADR-0002: canonical peptide schema as shared data layer for the peptiderepo.com ecosystem. All Tier 1 tools (Reconstitution Calculator, Dosage Reference, Legal Status Tracker, PSA enhancements) build on this. Includes: - pr_peptide CPT with REST, taxonomies, 11 meta fields - 3 custom tables: pr_dosing_rows, pr_legal_cells, pr_ai_candidate_queue - Sequential migration runner with schema versioning - 4 typed DTOs and 4 repository classes (full CRUD) - REST API (pr-core/v1): 6 endpoints (read public, write auth-gated) - Admin UI: 3 meta boxes, custom columns, AI candidate queue page - Shared disclaimer component (shortcode + static API) - JSON-LD Drug schema emission on single peptide pages - Seed data fixture (3 peptides, 10 dosing rows, 5 legal cells) - Full teardown in uninstall.php - CI: PHP lint 8.0-8.2, PHPCS WordPress, 300-line check All 22 PHP files under 300 lines. Highest: peptide-cpt at 265. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.1 KiB
3.1 KiB
Peptide Repo Core — Conventions
Naming
- Class prefix:
PR_Core_— all classes use this prefix. - Hook prefix:
pr_core_— all actions and filters start with this. - Option prefix:
pr_core_— all wp_options keys start with this. - Table prefix:
pr_— custom tables use{wpdb->prefix}pr_*. - CSS prefix:
.pr-core-— admin and frontend styles. - Text domain:
peptide-repo-core.
File Naming
Autoloader convention: PR_Core_Foo_Bar maps to class-pr-core-foo-bar.php.
Files live in includes/ or one level of subdirectory under includes/.
How To: Add a New Post-Meta Field
- Add the field to
PR_Core_Peptide_CPT::get_meta_fields()incpt/class-pr-core-peptide-cpt.php. - Add the field to
PR_Core_Peptide_DTOconstructor andto_array()indto/class-pr-core-peptide-dto.php. - Add the field to
PR_Core_Peptide_Repository::post_to_dto()inrepositories/class-pr-core-peptide-repository.php. - Add a form input in
PR_Core_Peptide_Metaboxes::render_identifiers_box()inadmin/class-pr-core-peptide-metaboxes.php. - The
save_meta()method reads from the same field list — no changes needed unless custom save logic applies.
How To: Add a New Migration
- Create
includes/migrations/class-pr-core-migration-NNNN-description.php. - The class must be named
PR_Core_Migration_NNNN_Descriptionwith a publicup()method. - Add the class name to
PR_Core_Migration_Runner::MIGRATIONSarray (index = version - 1). - Bump
PR_CORE_TARGET_SCHEMA_VERSIONinpeptide-repo-core.php. - All migrations must be idempotent (safe to run twice).
How To: Add a New REST Endpoint
- Add a
register_rest_route()call inPR_Core_Rest_Controller::register_routes(). - Implement the callback method in the same class.
- Use
check_write_permission()for any write endpoints. - Return typed DTOs via
->to_array()for consistent response shape.
How To: Add a New Disclaimer Surface
- Add a default text entry in
PR_Core_Disclaimer::DEFAULTS. - Use
[pr_disclaimer surface="new-surface"]in templates. - Custom copy can be set via
PR_Core_Disclaimer::update_disclaimer().
Error Handling
- Repository methods return
nullor0on failure, never throw. - REST endpoints return
WP_Errorwith appropriate HTTP status codes. - All database queries use
$wpdb->prepare()for parameterization. - Admin actions verify nonces and capabilities before processing.
Evidence Strength Enum
Ordered weakest to strongest: preclinical, case-series, observational, rct-small, rct-large, meta-analysis. Validated by PR_Core_Peptide_CPT::sanitize_evidence_strength().
Legal Status Enum
Values: prescription, ruo, otc, restricted, banned, unclear. Validated by PR_Core_Legal_Repository::sanitize_row().
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.