Poo fix
3 skills do Claude Code que impedem código duplicado. Detecta similar antes de criar (poo), audita codebase (poo-audit), refatora pra shared (poo-fix). DRY/SOLID/OOP.
npx -y skills add keysjoao/poo-skills --skill poo-fixAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Refactors duplicate code into shared components/utilities. Use after /poo audit finds duplicates. Trigger when: "fix duplicates", "consolidate components", "merge duplicates", "extract shared", "poo fix", "refactor to shared".
SKILL.md
3.7 KB, as published. Nobody here has run it
POO Fix — Consolidate Duplicates
Refactors identified duplicate code into shared, reusable components following OOP/SOLID principles.
Input
Either:
- Results from
/poo audit(list of duplicate pairs) - User pointing at specific files ("esses dois componentes fazem a mesma coisa")
- A file path to analyze
Workflow
Step 1: Analyze the Duplicates
For each duplicate pair:
- Read BOTH files completely
- Identify:
- Shared logic (identical or near-identical code)
- Differences (props, styling, edge cases)
- Dependencies (what each imports)
Step 2: Design the Shared Abstraction
Choose the right pattern:
| Pattern | When to Use | Example |
|---|---|---|
| Shared Component | Same UI, minor prop differences | <DownloadButton variant="primary"> |
| Composition | Same structure, different content | <Card><CardHeader/><CardBody/></Card> |
| Custom Hook | Same logic, different UI | useDownload() returns {download, loading, error} |
| Utility Function | Same operation, no UI | formatCurrency(value, locale) |
| Base Class/Interface | Same contract, different implementations | interface DataExporter { export(): void } |
| Higher-Order Component | Same wrapper behavior | withAuth(Component) |
| Render Props / Slots | Same logic, totally different UI | <DataFetcher render={data => ...}/> |
Step 3: Determine Location
1. Check if shared directory exists:
Glob: **/components/shared/** OR **/components/ui/** OR **/components/common/**
2. If not, check project conventions:
- Next.js: components/ at root or src/components/
- React: src/components/shared/
- Vue: src/components/common/
3. For utilities: utils/ or lib/
4. For hooks: hooks/ or composables/ (Vue)
5. For types: types/ or interfaces/
Step 4: Build the Shared Code
-
Create the shared component/utility with ALL variants:
- Use props/params to handle differences
- Add TypeScript types for all variants
- Export from a clean index file
-
Update ALL consumers:
- Replace duplicate imports with shared import
- Pass appropriate props/params
- Delete the old duplicate files
-
Verify nothing breaks:
- Check all imports resolve
- Check TypeScript compiles
- Run existing tests if available
Step 5: Report Changes
## POO Fix Report
### Created
- `components/shared/DownloadButton.tsx` — unified download button
### Updated (now using shared component)
- `pages/reports/index.tsx` — was: local DownloadBtn, now: shared DownloadButton
- `pages/exports/index.tsx` — was: local ExportDownload, now: shared DownloadButton
### Deleted (duplicates removed)
- `pages/reports/components/DownloadBtn.tsx`
- `pages/exports/components/ExportDownload.tsx`
### Props/Variants Added
- `variant`: "primary" | "secondary" | "icon-only"
- `format`: "csv" | "xlsx" | "pdf"
### Lines Saved: ~120 lines (2 files → 1 shared)
Refactoring Rules
- Never break existing functionality — the refactored code must work identically
- Preserve all edge cases — if one version handles an edge case, the shared version must too
- Use TypeScript generics when the types differ between consumers
- Add JSDoc comments explaining props/params that exist to support specific consumers
- Run type check after —
npx tsc --noEmitto verify - Update barrel exports — if the project uses index.ts re-exports