budtags/skills/verify-alignment/SKILL.md
Use this skill to verify that code aligns with BudTags coding standards, architectural patterns, and conventions before or after implementation.
npx skillsauth add jwilly246/budtags-claude-plugin verify-alignmentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are now equipped with comprehensive knowledge of BudTags coding standards via modular pattern files and scenario templates. This skill uses progressive disclosure to load only the patterns relevant to your verification task.
When the user invokes this skill, you can:
This skill has access to 11 focused pattern files and 6 scenario templates:
Backend Patterns:
patterns/backend-critical.md - Security, org scoping, logging (CRITICAL)patterns/backend-style.md - Method naming, request handling, DIpatterns/php8-brevity.md - PHP 8 shorthand patterns (??, fn(), ?->, match())patterns/backend-flash-messages.md - Flash message patterns (backend + frontend)patterns/database.md - Schema compliance, migrations, modelsFrontend Patterns:
patterns/frontend-critical.md - Component patterns, modal behaviorpatterns/frontend-typescript.md - Type safety, automated scanspatterns/frontend-data-fetching.md - React Query vs Inertia decision treeIntegration Patterns:
patterns/integrations.md - MetrcApi, QuickBooksApi, LeafLinkApiReal-Time Patterns:
patterns/websockets.md - Laravel Reverb, broadcasting, EventEmitterGit/Workflow Patterns:
patterns/git-workflow.md - Feature branch workflow, merge strategyscenarios/controller-method.md - New controller method checklistscenarios/migration.md - Migration and model checklistscenarios/react-component.md - React component checklistscenarios/inertia-form.md - Form submission checklist (MOST COMMON)scenarios/react-query-hook.md - React Query hook checklistscenarios/websocket-broadcast.md - WebSocket broadcasting checklist.claude/docs/frontend/data-fetching.md - Complete React Query guide (~400 lines).claude/docs/database-schema.md - Complete database schema (CRITICAL for DB work).claude/docs/backend/coding-style.md - Full backend coding standards.claude/docs/frontend/components.md - Complete component patterns.claude/docs/marketplace/pricing.md - Marketplace pricing (cents vs dollars, checkout conversion) (CRITICAL for Shop/Cart work).claude/docs/.claude/code-reviews/zpl-integration/06-typescript-type-safety.md - TypeScript violations and fixes.claude/code-reviews/*/ - Other code reviews documenting patterns and anti-patternsAsk the user:
"What work should I verify? Please provide:
Determine scope:
Identify verification depth:
IMPORTANT: Only load patterns relevant to the work scope. DO NOT load all patterns.
ALWAYS read:
patterns/backend-critical.md (security, org scoping, logging)patterns/backend-style.md (method naming, request handling)patterns/php8-brevity.md (PHP 8 shorthand: ??, fn(), ?->)IF forms/redirects:
patterns/backend-flash-messages.mdIF API calls:
patterns/integrations.mdALWAYS read:
patterns/database.md (schema compliance).claude/docs/database-schema.md (complete schema reference)ALSO read:
patterns/backend-critical.md (org scoping in queries)ALWAYS read:
patterns/frontend-critical.md (component patterns)IF TypeScript issues:
patterns/frontend-typescript.md (type safety + automated scans + thresholds).claude/code-reviews/zpl-integration/06-typescript-type-safety.md (past violations + fixes)IF data fetching:
patterns/frontend-data-fetching.md (React Query vs Inertia decision).claude/docs/frontend/data-fetching.md (full guide)IF forms:
patterns/backend-flash-messages.md (flash message patterns)ALWAYS read:
patterns/frontend-data-fetching.md (decision tree, anti-patterns).claude/docs/frontend/data-fetching.md (complete guide with examples)ALSO read:
patterns/frontend-typescript.md (type safety for hooks)ALWAYS read:
patterns/integrations.md (service patterns)IF Metrc: .claude/docs/integrations/metrc.md
IF QuickBooks: .claude/docs/integrations/quickbooks.md
ALWAYS read:
patterns/websockets.md (ShouldBroadcastNow, event enrichment, EventEmitter)ALSO read:
patterns/backend-critical.md (org scoping for channels)patterns/frontend-typescript.md (type alignment between PHP and TS)IF implementing new broadcast event: scenarios/websocket-broadcast.md
Match work type to scenario:
| Work Type | Scenario Template |
|-----------|------------------|
| New controller method | scenarios/controller-method.md |
| New migration or model | scenarios/migration.md |
| React component | scenarios/react-component.md |
| Inertia form submission | scenarios/inertia-form.md |
| React Query hook | scenarios/react-query-hook.md |
| WebSocket broadcast event | scenarios/websocket-broadcast.md |
If work doesn't match a scenario: Use loaded pattern files directly.
Using the loaded patterns and scenario template:
PHPStan + Larastan (level 10) and Pint are REQUIRED for all PHP files. Larastan provides Laravel-aware analysis (Eloquent, facades, request helpers). Code must be written with the intention of passing these inspections.
Run both in parallel on touched files:
./vendor/bin/phpstan analyse app/Http/Controllers/MyController.php --memory-limit=512M &
./vendor/bin/pint app/Http/Controllers/MyController.php --test &
wait
Pre-commit hook enforces this (.husky/pre-commit runs on ALL branches):
Write code to pass - don't fix after the fact.
For each issue found:
Provide a structured report with these sections:
## ✅ Alignment Summary
**Overall Status**: [Aligned | Minor Issues | Needs Revision]
**Work Reviewed**: [Brief description]
**Scope**: [Backend | Frontend | Full-stack]
**Files Checked**: [Count] files
**Patterns Loaded**: [List of pattern files used]
List each critical pattern with status:
## 🎯 Pattern Compliance
- ✅ **Organization Scoping**: All queries properly scoped
- ✅ **Method Naming**: snake_case verb-first naming
- ⚠️ **Service Layer**: Consider moving to protected method
- ❌ **Logging**: Uses Log::info() instead of LogService
- ✅ **Permission Checks**: Proper authorization
For each issue:
## 🔍 Specific Findings
### ❌ Critical Issue: Organization Scoping Missing
**Location**: `app/Http/Controllers/StrainController.php:45`
**Pattern**: `patterns/backend-critical.md` - Organization Scoping
**Issue**: Query not scoped to active organization
**Current Code**:
\`\`\`php
$strains = Strain::all();
\`\`\`
**Fix**:
\`\`\`php
$strains = request()->user()->active_org->strains()->get();
\`\`\`
**Priority**: CRITICAL (security issue)
Prioritized recommendations:
## 💡 Recommendations
### CRITICAL (Fix immediately - security/correctness)
1. Add organization scoping to all queries
2. Replace Log::info() with LogService::store()
### HIGH (Fix before merging)
1. Rename methods to snake_case
2. Add flash messages for user feedback
### MEDIUM (Improve when convenient)
1. Use method-level injection
2. Extract validation to inline rules
## 📚 Documentation References
**Patterns Consulted**:
- `patterns/backend-critical.md` - Security and org scoping
- `patterns/backend-style.md` - Method naming and structure
- `scenarios/controller-method.md` - Controller verification checklist
**Full Documentation** (if referenced):
- `.claude/docs/database-schema.md` - Schema compliance
After providing the report, ALWAYS:
Load:
Check:
Report:
Context: ~300 lines (74% reduction from monolithic)
Load:
Check:
Report:
Context: ~500 lines (57% reduction from monolithic)
Load:
Check:
Report:
Context: ~700 lines (40% reduction from monolithic)
When appropriate, run these bash commands:
# Count violations
grep -r "as any" resources/js --include="*.tsx" | wc -l
grep -r ": any" resources/js --include="*.tsx" | wc -l
# Find worst files
grep -r "as any\|: any" resources/js --include="*.tsx" -c | sort -t: -k2 -nr | head -10
# Check for suppressions
grep -r "@ts-ignore\|@ts-expect-error" resources/js --include="*.tsx"
Thresholds: 0-10 excellent, 11-30 acceptable, >30 critical
# Backend anti-patterns
grep -r "->with('success'" app/Http/Controllers --include="*.php"
# Frontend anti-patterns
grep -r "flash\?\.success" resources/js --include="*.tsx"
grep -r "onSuccess.*toast\.success" resources/js --include="*.tsx" -A 5
Thresholds: 0 excellent, 1-2 acceptable, >2 critical
# Find usage
grep -r "useQuery\|useMutation" resources/js --include="*.tsx"
# Check for global invalidation (anti-pattern)
grep -r "invalidateQueries()" resources/js --include="*.tsx"
// ✅ CORRECT
$items = request()->user()->active_org->items()->get();
$org_id = request()->user()->active_org_id;
// ❌ WRONG
$items = Item::all();
// ✅ CORRECT
public function create()
public function delete()
public function fetch_logs()
// ❌ WRONG
public function store()
public function destroy()
public function bulkAdjust()
// ✅ CORRECT - Short and clean
$name = $data['name'] ?? 'default';
$strains = $user->active_org?->strains()->get() ?? collect();
$slugs = $items->map(fn($i) => $i->slug);
$v = request()->validate([...]);
// ❌ WRONG - Verbose
$name = isset($data['name']) ? $data['name'] : 'default';
$strains = $user->active_org ? $user->active_org->strains()->get() : collect();
$slugs = $items->map(function($i) { return $i->slug; });
// ✅ CORRECT
LogService::store('Action', 'Description', $model);
// ❌ WRONG
Log::info('Action performed');
// ✅ CORRECT (Backend)
return redirect()->back()->with('message', 'Item created');
// ✅ CORRECT (Frontend)
onSuccess: () => { onClose(); } // MainLayout handles flash
// ❌ WRONG
return redirect()->back()->with('success', 'Item created');
onSuccess: (page) => { toast.success(page.props.flash.success); }
// ✅ Use React Query for: Read-heavy dashboards, inline editing, caching
const { data, refetch } = useQuickBooksInvoices();
// ✅ Use Inertia for: Forms, CRUD, navigation
const { post } = useForm({ name: '' });
post('/api/create');
// ❌ WRONG
const mutation = useMutation({ mutationFn: (data) => axios.post('/api/create', data) });
// ✅ CORRECT - Inline at point of use
$package->update(['status' => 'active']);
// ❌ WRONG - Premature abstraction
const STATUS_ACTIVE = 'active'; // Only if used 3+ times across files
// ✅ CORRECT - Convert cents to dollars for order line items
$unit_price_cents = (float) ($item['unit_price'] ?? 0);
$unit_price = $unit_price_cents / 100; // Convert cents to dollars
MarketplaceOrderLineItem::create(['unit_price' => $unit_price]);
// ❌ WRONG - Cart stores cents, order expects dollars
$unit_price = (float) ($item['unit_price'] ?? 0); // BUG: stores 42000 not 420.00
// ✅ CORRECT - formatPrice() expects cents
formatPrice(product.wholesale_price); // "420.00" from 42000
// ✅ CORRECT - Order line items already in dollars
`$${lineItem.unit_price.toFixed(2)}` // "$420.00" from 420.00
Reference: .claude/docs/marketplace/pricing.md
// ✅ CORRECT - Immediate broadcast for real-time UX
class LabelCreated implements ShouldBroadcastNow {
public string $org_id;
public string $label_id;
public string $label_type_name; // Include display data
}
// ❌ WRONG - Queued broadcast delays real-time updates
class LabelCreated implements ShouldBroadcast {
// ✅ CORRECT - Build state from event data (zero reloads)
onLabelCreated.on((data) => {
setLabels(prev => [...prev, buildLabelFromEvent(data)]);
});
// ❌ WRONG - Reload on every event (defeats WebSocket purpose)
onLabelCreated.on(() => {
router.reload();
});
Help users maintain high code quality and consistency in the BudTags codebase by:
You are a guardian of code quality with modular, focused knowledge of BudTags patterns. Use progressive disclosure to provide fast, relevant verification!
development
Use this skill when generating ZPL code, working with ZPL commands, creating Zebra printer labels, or troubleshooting ZPL syntax and formatting issues.
development
Use this skill when working with Unleashed Software inventory/order management API integration, syncing inventory, importing orders, managing stock adjustments, or handling customer/product data from Unleashed.
data-ai
TanStack Virtual patterns for virtualized lists, tables, and grids with high-performance rendering of large datasets
testing
Use when working with TanStack Table for data tables, datagrids, sorting, filtering, pagination, row selection, column customization, or virtualization. Load specific pattern files based on the feature needed.