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
| Rule | Foco |
|---|---|
wp-plugin-patterns.md | Padroes de arquitetura para replicar |
wp-plugin-workflow.md | Ciclo de desenvolvimento (setup ate ship) |
wp-plugin-testing-strategy.md | Piramide de testes, metas de cobertura, guias |
wp-plugin-security-checklist.md | Deep-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/namespaceMiddag\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/vsWordPress/) - [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_callbackem TODA rota (nunca__return_truepara 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-Organizationheader - [ ] 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 hookinit - [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}Repositorypara migracao - [x] Toggle
middag_migration_completealterna CCT (JetEngine) <-> wp_posts
5. Internationalization — 10/10
- [x] Text domain corresponde ao slug do plugin (
middag-account) - [x]
Domain Path: /languagesno header - [x] Todas strings user-facing wrapped:
__(),_e(),esc_html__() - [x] Plural forms:
_n(),_nx()onde aplicavel - [x]
.potfile emlanguages/— regenerado viacomposer i18n:pot - [x]
.po/.mofiles 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]
.distignoreexclui: tests, docs, .claude, .aiox-core, node_modules, ui/ source - [x]
.gitattributescomexport-ignoreespelhando.distignore - [x]
composer install --no-dev --optimize-autoloaderno 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]
HookInterfacecontract: metodoregister()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_capfilter 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
| # | Area | Score | Status |
|---|---|---|---|
| 1 | Bootstrap | 10/10 | STRONG |
| 2 | Architecture | 10/10 | STRONG |
| 3 | Security | 9/10 | STRONG |
| 4 | Custom Post Types | 10/10 | STRONG |
| 5 | i18n | 10/10 | STRONG |
| 6 | Database | 8/10 | ADEQUATE |
| 7 | Assets & Build | 10/10 | STRONG |
| 8 | Distribution | 10/10 | STRONG |
| 9 | Testing | 8/10 | ADEQUATE |
| 10 | Hooks | 9/10 | STRONG |
| 11 | 9/10 | STRONG | |
| 12 | Templates | 9/10 | STRONG |
| 13 | Cron | 9/10 | STRONG |
| 14 | Capabilities | 10/10 | STRONG |
| 15 | Integrations | 8/10 | ADEQUATE |
| TOTAL | 139/150 | 93% — STRONG |
Quality Tiers
| Tier | Score | Significado |
|---|---|---|
| STRONG | Todos itens checked | Production-ready, padrao replicavel |
| ADEQUATE | 70%+ checked | Funcional, gaps menores a enderecar |
| WEAK | 50-69% checked | Precisa atencao antes de producao |
| MISSING | <50% checked | Rework significativo necessario |
Open Gaps (Priority Order)
- Migracao email templates — 11 templates restantes em
classes/(HIGH) - Integration tests — webhook handlers HubSpot/Stripe (HIGH)
- CI coverage threshold — enforcar minimo 70% (MEDIUM)
- Database cache priming — prevencao N+1 para list queries (MEDIUM)
- Jira API integration — planejada mas nao implementada (MEDIUM)
- Cron health notice — admin warning se cron atrasado (LOW)
- Query audit — verificar todas queries custom usam
$wpdb->prepare()(LOW) - Hooks documentation — documentacao completa para devs terceiros (LOW)
Derivado de: middag-account v4 audit — Morgan (@pm), Abril 2026