Skip to content

WordPress Plugin Best Practices — Checklist

Checklist de qualidade reutilizavel para o plugin middag-account. Derivado do audit do middag-account v4 (Abril 2026). Claude Code carrega esta rule automaticamente ao editar arquivos do plugin.

Companion Rules

RuleFoco
wp-plugin-patterns.mdPadroes de arquitetura para replicar
wp-plugin-workflow.mdCiclo de desenvolvimento (setup ate ship)
wp-plugin-testing-strategy.mdPiramide de testes, metas de cobertura, guias
wp-plugin-security-checklist.mdDeep-dive de seguranca (60+ itens)

1. Bootstrap (main plugin file) — 10/10

  • [x] Header completo: Name, Description, Version, Author, License, Text Domain, Domain Path
  • [x] WC metadata: WC requires at least, WC tested up to
  • [x] WP/PHP version requirements: Requires at least, Requires PHP (8.4+)
  • [x] register_activation_hook() — capabilities, CPTs, rewrite flush
  • [x] register_deactivation_hook() — unregister crons, remove capabilities, flush rewrites
  • [x] uninstall.php — cleanup de options, transients, capabilities, CPT data
  • [x] Dependency check antes do boot (WooCommerce ativo? PHP version?)
  • [x] Admin notice se dependencias ausentes (nunca fatal error)
  • [x] Composer autoloader carregado com error handling
  • [x] Boot no hook plugins_loaded (nunca imediatamente)

2. Architecture — 10/10

  • [x] PSR-4 autoloading via Composer (src/ namespace Middag\Account\)
  • [x] Symfony DI Container 7.4 para autowiring
  • [x] Zero static global calls — todas dependencias injetadas via constructor
  • [x] Domain logic separada do WordPress layer (Domain/ vs WordPress/)
  • [x] Service auto-discovery por sufixo: Service, Repository, Controller, Handler, Hooks, Registrar
  • [x] Interface contracts para abstracoes core (Repository, Hook, Controller)
  • [x] 15 dominios DDD light em Domain/ (Organization, Collaborator, Order, Invoice, etc.)
  • [x] Integration layer (Integration/) para HubSpot, Stripe, ISSNet, Banco Inter, Cloudflare
  • [x] Inertia.js v2 + React 19 admin UI em ui/ (full SPA, nao React Islands)
  • [x] API v4 com ~81 REST endpoints no namespace middagaccount/v4

3. Security — 9/10

  • [x] REST API: permission_callback em TODA rota (nunca __return_true para write ops)
  • [x] current_user_can() checks antes de acoes state-changing
  • [x] sanitize_text_field(), absint(), sanitize_email() em toda entrada
  • [x] esc_html(), esc_attr(), esc_url() em toda saida
  • [x] wp_verify_nonce() em form submissions e AJAX
  • [x] $wpdb->prepare() em qualquer SQL raw (preferir WP wrappers quando possivel)
  • [x] Nunca usar extract() em templates — passar variaveis explicitas
  • [x] JWT RS256 auth para API externa (token issuance, refresh, RSA key pair)
  • [x] Organization-scoped permissions via X-Middag-Organization header
  • [ ] GAP: Auditoria completa de queries custom para cobertura $wpdb->prepare()

Deep-dive: ver wp-plugin-security-checklist.md

4. Custom Post Types (WordPress) — 10/10

  • [x] Cada dominio registra seu CPT via register_post_type() no hook init
  • [x] CPT slugs com prefixo middag_ para evitar colisoes
  • [x] Meta keys mapeados nos repository classes (Domain Entity <-> wp_posts)
  • [x] Usar get_post_meta() / update_post_meta() via Repository layer (nunca direto no Domain)
  • [x] Dual-repository pattern: Cct{Name}Repository + {Name}Repository para migracao
  • [x] Toggle middag_migration_complete alterna CCT (JetEngine) <-> wp_posts

5. Internationalization — 10/10

  • [x] Text domain corresponde ao slug do plugin (middag-account)
  • [x] Domain Path: /languages no header
  • [x] Todas strings user-facing wrapped: __(), _e(), esc_html__()
  • [x] Plural forms: _n(), _nx() onde aplicavel
  • [x] .pot file em languages/ — regenerado via composer i18n:pot
  • [x] .po / .mo files para locale pt_BR
  • [x] Composer scripts: i18n:pot, i18n:mo

6. Database — 8/10

  • [x] Usar WP APIs: WP_Query, get_posts(), get_post_meta() via Repositories
  • [x] Custom tables criadas via dbDelta() com charset collation correto
  • [x] Custom tables com indices em foreign keys e colunas frequentes
  • [x] $wpdb->prepare() para TODA query SQL custom
  • [ ] GAP: Cache priming para prevenir N+1 queries (update_postmeta_cache())
  • [x] Sem dados orfaos — cleanup no uninstall
  • [x] Dual persistence: JetEngine CCT (wp_jet_cct_*) + wp_posts com toggle

7. Assets & Build — 10/10

  • [x] Vite 6 para JS/CSS — IIFE output para WP compat (assets/dist/app.js)
  • [x] wp_enqueue_script() / wp_enqueue_style() com dependencias corretas
  • [x] Version parameter vinculado a constante de versao do plugin (cache busting)
  • [x] Scripts carregados apenas em admin pages relevantes (nao globalmente)
  • [x] wp_add_inline_script() para dados PHP-to-JS (Inertia page props)
  • [x] Diretorio ui/ separado com package.json proprio (isolar Node de PHP)
  • [x] Tailwind v4 para styling do admin UI

8. Distribution — 10/10

  • [x] .distignore exclui: tests, docs, .claude, .aiox-core, node_modules, ui/ source
  • [x] .gitattributes com export-ignore espelhando .distignore
  • [x] composer install --no-dev --optimize-autoloader no build script
  • [x] Assets built no CI antes de packaging (Bitbucket Pipelines)
  • [x] Sem .env, credenciais ou configs dev na distribuicao

9. Testing — 8/10

  • [x] PHPUnit 12 configurado com bootstrap e source coverage
  • [x] Unit tests para domain logic (908 testes, 3722 assertions)
  • [x] Brain\Monkey para unit tests sem WordPress bootstrap
  • [x] Test fixtures/factories para dados reproduziveis
  • [x] Composer scripts: test, test:unit, test:coverage
  • [x] 15 dominios com cobertura de testes
  • [ ] GAP: Coverage threshold enforced no CI (minimo 70%)
  • [ ] GAP: Integration tests para webhook handlers (HubSpot, Stripe)

Deep-dive: ver wp-plugin-testing-strategy.md

10. Hooks & Extensibility — 9/10

  • [x] HookInterface contract: metodo register() unico
  • [x] Todos hooks registrados via Hook classes dedicadas (auto-discovered)
  • [x] Custom action hooks em pontos-chave do lifecycle
  • [x] Custom filter hooks para transformacao de dados
  • [x] Prefixo de hook consistente: middag/
  • [x] Hooks publicos documentados em docs/
  • [ ] GAP: Documentacao completa de todos hooks publicos para desenvolvedores terceiros

11. Email (WooCommerce) — 9/10

  • [x] Email classes estendem WC_Email
  • [x] Registradas via filtro woocommerce_email_classes
  • [x] Templates usam wc_get_template() / wc_get_template_html()
  • [x] Theme-overridable: path middag-account/emails/
  • [x] Trigger method com binding correto de action hook
  • [ ] GAP: Migracao completa dos 11 email templates restantes em classes/

12. Templates — 9/10

  • [x] Suporte a theme override via TemplateRenderer
  • [x] Fallback para diretorio templates/ do plugin
  • [x] Sem extract() — passar array $args, acessar via $args['key']
  • [x] Escape em toda saida dentro de templates
  • [x] Before/after action hooks em template blocks para extensibilidade

13. Cron — 9/10

  • [x] Custom intervals registrados via filtro cron_schedules
  • [x] Events scheduled na ativacao, unscheduled na desativacao
  • [x] Guard contra scheduling duplicado (wp_next_scheduled() check)
  • [x] Error logging em falhas de cron handlers
  • [ ] GAP: Admin health notice se cron critico nao rodou recentemente

14. Capabilities — 10/10

  • [x] Custom capabilities com hierarquia clara
  • [x] Role mapping: administrator > shop_manager > customer > subscriber
  • [x] Capabilities adicionadas na ativacao, removidas na desativacao
  • [x] user_has_cap filter para expansao de capabilities (hierarquia)
  • [x] REST API e admin UI gated por capabilities
  • [x] Organization-scoped permissions (multi-tenant boundary)

15. Integrations — 8/10

  • [x] HubSpot: webhook handlers com signature validation
  • [x] Stripe: dual-account support (live + test), webhook handlers
  • [x] Banco Inter: gateway ativo, override pagador com CNPJ Organization
  • [x] ISSNet: integração NFSe (Brasília/DF)
  • [x] Cloudflare: DNS/SSL management para environments
  • [x] SolidAffiliate: programa de parceiros (ADR-306)
  • [ ] GAP: Jira API integration (planejada, nao implementada)
  • [ ] GAP: Testes de integracao end-to-end para cada provider

Score Summary

#AreaScoreStatus
1Bootstrap10/10STRONG
2Architecture10/10STRONG
3Security9/10STRONG
4Custom Post Types10/10STRONG
5i18n10/10STRONG
6Database8/10ADEQUATE
7Assets & Build10/10STRONG
8Distribution10/10STRONG
9Testing8/10ADEQUATE
10Hooks9/10STRONG
11Email9/10STRONG
12Templates9/10STRONG
13Cron9/10STRONG
14Capabilities10/10STRONG
15Integrations8/10ADEQUATE
TOTAL139/15093% — STRONG

Quality Tiers

TierScoreSignificado
STRONGTodos itens checkedProduction-ready, padrao replicavel
ADEQUATE70%+ checkedFuncional, gaps menores a enderecar
WEAK50-69% checkedPrecisa atencao antes de producao
MISSING<50% checkedRework significativo necessario

Open Gaps (Priority Order)

  1. Migracao email templates — 11 templates restantes em classes/ (HIGH)
  2. Integration tests — webhook handlers HubSpot/Stripe (HIGH)
  3. CI coverage threshold — enforcar minimo 70% (MEDIUM)
  4. Database cache priming — prevencao N+1 para list queries (MEDIUM)
  5. Jira API integration — planejada mas nao implementada (MEDIUM)
  6. Cron health notice — admin warning se cron atrasado (LOW)
  7. Query audit — verificar todas queries custom usam $wpdb->prepare() (LOW)
  8. Hooks documentation — documentacao completa para devs terceiros (LOW)

Derivado de: middag-account v4 audit — Morgan (@pm), Abril 2026