mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
Add refactoring tracker tool and progress report for 106 large files
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
141
docs/todo/LAMBDA_REFACTOR_PROGRESS.md
Normal file
141
docs/todo/LAMBDA_REFACTOR_PROGRESS.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Lambda-per-File Refactoring Progress
|
||||
|
||||
**Generated:** 2025-12-27T15:35:24.150Z
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total files > 150 lines:** 106
|
||||
- **Pending:** 94
|
||||
- **In Progress:** 0
|
||||
- **Completed:** 0
|
||||
- **Skipped:** 12
|
||||
|
||||
## By Category
|
||||
|
||||
- **component:** 60
|
||||
- **dbal:** 12
|
||||
- **library:** 11
|
||||
- **tool:** 10
|
||||
- **test:** 10
|
||||
- **type:** 2
|
||||
- **other:** 1
|
||||
|
||||
## Refactoring Queue
|
||||
|
||||
Files are prioritized by ease of refactoring and impact.
|
||||
|
||||
### High Priority (20 files)
|
||||
|
||||
Library and tool files - easiest to refactor
|
||||
|
||||
- [ ] `frontends/nextjs/src/lib/nerd-mode-ide/templates/template-configs.ts` (267 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/db/core/index.ts` (216 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/security/functions/patterns/javascript-patterns.ts` (184 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/rendering/page/page-renderer.ts` (178 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/github/workflows/analysis/runs/analyze-workflow-runs.ts` (164 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/rendering/page/page-definition-builder.ts` (483 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/db/database-admin/seed-default-data.ts` (471 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/components/component-catalog.ts` (337 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/schema/default-schema.ts` (308 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/lua/snippets/lua-snippets-data.ts` (983 lines)
|
||||
- [ ] `tools/analysis/code/analyze-render-performance.ts` (294 lines)
|
||||
- [ ] `tools/misc/metrics/enforce-size-limits.ts` (249 lines)
|
||||
- [ ] `tools/refactoring/refactor-to-lambda.ts` (243 lines)
|
||||
- [ ] `tools/analysis/test/analyze-implementation-completeness.ts` (230 lines)
|
||||
- [ ] `tools/detection/detect-stub-implementations.ts` (215 lines)
|
||||
- [ ] `tools/generation/generate-stub-report.ts` (204 lines)
|
||||
- [ ] `tools/quality/code/check-code-complexity.ts` (175 lines)
|
||||
- [ ] `tools/generation/generate-quality-summary.ts` (159 lines)
|
||||
- [ ] `dbal/shared/tools/cpp-build-assistant.ts` (342 lines)
|
||||
- [ ] `tools/analysis/test/analyze-test-coverage.ts` (332 lines)
|
||||
|
||||
### Medium Priority (68 files)
|
||||
|
||||
DBAL and component files - moderate complexity
|
||||
|
||||
- [ ] `frontends/nextjs/src/lib/packages/core/package-catalog.ts` (1169 lines)
|
||||
- [ ] `dbal/development/src/blob/providers/tenant-aware-storage.ts` (260 lines)
|
||||
- [ ] `dbal/development/src/adapters/acl-adapter.ts` (258 lines)
|
||||
- [ ] `dbal/development/src/blob/providers/memory-storage.ts` (230 lines)
|
||||
- [ ] `dbal/development/src/core/foundation/types.ts` (216 lines)
|
||||
- [ ] `dbal/development/src/core/entities/operations/core/user-operations.ts` (185 lines)
|
||||
- [ ] `dbal/development/src/core/entities/operations/system/package-operations.ts` (185 lines)
|
||||
- [ ] `dbal/development/src/bridges/websocket-bridge.ts` (168 lines)
|
||||
- [ ] `dbal/development/src/blob/providers/filesystem-storage.ts` (410 lines)
|
||||
- [ ] `dbal/development/src/blob/providers/s3-storage.ts` (361 lines)
|
||||
- [ ] `dbal/development/src/adapters/prisma-adapter.ts` (350 lines)
|
||||
- [ ] `frontends/nextjs/src/lib/dbal/core/client/dbal-integration.ts` (313 lines)
|
||||
- [ ] `dbal/development/src/core/foundation/kv-store.ts` (307 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/data/QuickGuide.tsx` (297 lines)
|
||||
- [ ] `frontends/nextjs/src/components/editors/ThemeEditor.tsx` (294 lines)
|
||||
- [ ] `frontends/nextjs/src/components/managers/PageRoutesManager.tsx` (290 lines)
|
||||
- [ ] `frontends/nextjs/src/components/managers/component/ComponentConfigDialog.tsx` (290 lines)
|
||||
- [ ] `frontends/nextjs/src/components/level/levels/Level5.tsx` (289 lines)
|
||||
- [ ] `frontends/nextjs/src/components/editors/lua/LuaSnippetLibrary.tsx` (285 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/data/GenericPage.tsx` (274 lines)
|
||||
- ... and 48 more
|
||||
|
||||
### Low Priority (6 files)
|
||||
|
||||
- [ ] `frontends/nextjs/src/components/editors/lua/LuaEditor.tsx` (681 lines)
|
||||
- [ ] `frontends/nextjs/src/components/managers/package/PackageImportExport.tsx` (594 lines)
|
||||
- [ ] `frontends/nextjs/src/components/workflow/WorkflowEditor.tsx` (508 lines)
|
||||
- [ ] `frontends/nextjs/src/components/ui/index.ts` (263 lines)
|
||||
- [ ] `frontends/nextjs/src/components/misc/github/GitHubActionsFetcher.tsx` (1069 lines)
|
||||
- [ ] `frontends/nextjs/src/components/editors/lua/LuaBlocksEditor.tsx` (1048 lines)
|
||||
|
||||
### Skipped Files (12)
|
||||
|
||||
These files do not need refactoring:
|
||||
|
||||
- `frontends/nextjs/src/hooks/ui/state/useAutoRefresh.test.ts` (268 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/lib/rendering/tests/page-renderer.test.ts` (265 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/lib/security/scanner/security-scanner.test.ts` (257 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/theme/types/theme.d.ts` (200 lines) - Type definition files are typically large
|
||||
- `frontends/nextjs/src/hooks/data/useKV.test.ts` (196 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/hooks/useAuth.test.ts` (181 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/types/dbal.d.ts` (154 lines) - Type definition files are typically large
|
||||
- `frontends/nextjs/src/lib/schema/schema-utils.test.ts` (440 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/lib/workflow/engine/workflow-engine.test.ts` (388 lines) - Test files can remain large for comprehensive coverage
|
||||
- `frontends/nextjs/src/lib/lua/engine/core/lua-engine.test.ts` (357 lines) - Test files can remain large for comprehensive coverage
|
||||
- ... and 2 more
|
||||
|
||||
## Refactoring Patterns
|
||||
|
||||
### For Library Files
|
||||
1. Create a `functions/` subdirectory
|
||||
2. Extract each function to its own file
|
||||
3. Create a class wrapper (like SchemaUtils)
|
||||
4. Update main file to re-export
|
||||
5. Verify tests still pass
|
||||
|
||||
### For Components
|
||||
1. Extract hooks into separate files
|
||||
2. Extract sub-components
|
||||
3. Extract utility functions
|
||||
4. Keep main component < 150 lines
|
||||
|
||||
### For DBAL Files
|
||||
1. Split adapters by operation type
|
||||
2. Extract provider implementations
|
||||
3. Keep interfaces separate from implementations
|
||||
|
||||
## Example: SchemaUtils Pattern
|
||||
|
||||
The `frontends/nextjs/src/lib/schema/` directory demonstrates the lambda-per-file pattern:
|
||||
|
||||
```
|
||||
schema/
|
||||
├── functions/
|
||||
│ ├── field/
|
||||
│ │ ├── get-field-label.ts
|
||||
│ │ ├── validate-field.ts
|
||||
│ │ └── ...
|
||||
│ ├── model/
|
||||
│ │ ├── find-model.ts
|
||||
│ │ └── ...
|
||||
│ └── index.ts (re-exports all)
|
||||
├── SchemaUtils.ts (class wrapper)
|
||||
└── schema-utils.ts (backward compat re-exports)
|
||||
```
|
||||
|
||||
243
tools/refactoring/refactor-to-lambda.ts
Normal file
243
tools/refactoring/refactor-to-lambda.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env ts-node
|
||||
/**
|
||||
* Refactor large TypeScript files into lambda-per-file structure
|
||||
*
|
||||
* This tool helps identify files exceeding 150 lines and tracks refactoring progress.
|
||||
*/
|
||||
|
||||
import { exec } from 'child_process'
|
||||
import { promisify } from 'util'
|
||||
import * as fs from 'fs/promises'
|
||||
import * as path from 'path'
|
||||
|
||||
const execAsync = promisify(exec)
|
||||
|
||||
interface FileInfo {
|
||||
path: string
|
||||
lines: number
|
||||
category: 'component' | 'library' | 'test' | 'tool' | 'dbal' | 'type' | 'other'
|
||||
priority: number
|
||||
status: 'pending' | 'in-progress' | 'completed' | 'skipped'
|
||||
reason?: string
|
||||
}
|
||||
|
||||
async function countLines(filePath: string): Promise<number> {
|
||||
try {
|
||||
const content = await fs.readFile(filePath, 'utf-8')
|
||||
return content.split('\n').length
|
||||
} catch {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
function categorizeFile(filePath: string): FileInfo['category'] {
|
||||
if (filePath.includes('.test.')) return 'test'
|
||||
if (filePath.endsWith('.tsx')) return 'component'
|
||||
if (filePath.includes('/tools/')) return 'tool'
|
||||
if (filePath.includes('/dbal/')) return 'dbal'
|
||||
if (filePath.includes('/types/') || filePath.endsWith('.d.ts')) return 'type'
|
||||
if (filePath.includes('/lib/') && filePath.endsWith('.ts')) return 'library'
|
||||
return 'other'
|
||||
}
|
||||
|
||||
function calculatePriority(file: FileInfo): number {
|
||||
// Higher priority for library files (easiest to refactor)
|
||||
// Lower priority for components (need more complex refactoring)
|
||||
// Skip tests and types
|
||||
const categoryPriority = {
|
||||
library: 10,
|
||||
tool: 8,
|
||||
dbal: 6,
|
||||
component: 4,
|
||||
test: 0, // Skip
|
||||
type: 0, // Skip
|
||||
other: 2,
|
||||
}
|
||||
|
||||
const base = categoryPriority[file.category]
|
||||
|
||||
// Prioritize moderately large files over extremely large ones
|
||||
// (easier to refactor step-by-step)
|
||||
if (file.lines > 1000) return base - 3
|
||||
if (file.lines > 500) return base - 1
|
||||
if (file.lines > 300) return base
|
||||
return base + 1
|
||||
}
|
||||
|
||||
async function findLargeFiles(rootDir: string, minLines: number = 150): Promise<FileInfo[]> {
|
||||
const { stdout } = await execAsync(
|
||||
`find ${rootDir} \\( -name "*.ts" -o -name "*.tsx" \\) ` +
|
||||
`-not -path "*/node_modules/*" ` +
|
||||
`-not -path "*/.next/*" ` +
|
||||
`-not -path "*/dist/*" ` +
|
||||
`-not -path "*/build/*" ` +
|
||||
`-exec sh -c 'lines=$(wc -l < "$1"); if [ "$lines" -gt ${minLines} ]; then echo "$lines $1"; fi' _ {} \\;`
|
||||
)
|
||||
|
||||
const files: FileInfo[] = []
|
||||
for (const line of stdout.trim().split('\n').filter(Boolean)) {
|
||||
const [linesStr, filePath] = line.trim().split(' ', 2)
|
||||
const lines = parseInt(linesStr, 10)
|
||||
const category = categorizeFile(filePath)
|
||||
const fileInfo: FileInfo = {
|
||||
path: filePath.replace(rootDir + '/', ''),
|
||||
lines,
|
||||
category,
|
||||
priority: 0,
|
||||
status: category === 'test' || category === 'type' ? 'skipped' : 'pending',
|
||||
reason: category === 'test' ? 'Test files can remain large for comprehensive coverage' :
|
||||
category === 'type' ? 'Type definition files are typically large' : undefined
|
||||
}
|
||||
fileInfo.priority = calculatePriority(fileInfo)
|
||||
files.push(fileInfo)
|
||||
}
|
||||
|
||||
return files.sort((a, b) => b.priority - a.priority || b.lines - a.lines)
|
||||
}
|
||||
|
||||
async function generateReport(files: FileInfo[]): Promise<string> {
|
||||
const total = files.length
|
||||
const byCategory = files.reduce((acc, f) => {
|
||||
acc[f.category] = (acc[f.category] || 0) + 1
|
||||
return acc
|
||||
}, {} as Record<string, number>)
|
||||
|
||||
const byStatus = files.reduce((acc, f) => {
|
||||
acc[f.status] = (acc[f.status] || 0) + 1
|
||||
return acc
|
||||
}, {} as Record<string, number>)
|
||||
|
||||
let report = '# Lambda-per-File Refactoring Progress\n\n'
|
||||
report += `**Generated:** ${new Date().toISOString()}\n\n`
|
||||
report += `## Summary\n\n`
|
||||
report += `- **Total files > 150 lines:** ${total}\n`
|
||||
report += `- **Pending:** ${byStatus.pending || 0}\n`
|
||||
report += `- **In Progress:** ${byStatus['in-progress'] || 0}\n`
|
||||
report += `- **Completed:** ${byStatus.completed || 0}\n`
|
||||
report += `- **Skipped:** ${byStatus.skipped || 0}\n\n`
|
||||
|
||||
report += `## By Category\n\n`
|
||||
for (const [category, count] of Object.entries(byCategory).sort((a, b) => b[1] - a[1])) {
|
||||
report += `- **${category}:** ${count}\n`
|
||||
}
|
||||
|
||||
report += `\n## Refactoring Queue\n\n`
|
||||
report += `Files are prioritized by ease of refactoring and impact.\n\n`
|
||||
|
||||
// Group by priority
|
||||
const highPriority = files.filter(f => f.priority >= 8 && f.status === 'pending')
|
||||
const medPriority = files.filter(f => f.priority >= 4 && f.priority < 8 && f.status === 'pending')
|
||||
const lowPriority = files.filter(f => f.priority < 4 && f.status === 'pending')
|
||||
|
||||
if (highPriority.length > 0) {
|
||||
report += `### High Priority (${highPriority.length} files)\n\n`
|
||||
report += `Library and tool files - easiest to refactor\n\n`
|
||||
for (const file of highPriority.slice(0, 20)) {
|
||||
report += `- [ ] \`${file.path}\` (${file.lines} lines)\n`
|
||||
}
|
||||
if (highPriority.length > 20) {
|
||||
report += `- ... and ${highPriority.length - 20} more\n`
|
||||
}
|
||||
report += `\n`
|
||||
}
|
||||
|
||||
if (medPriority.length > 0) {
|
||||
report += `### Medium Priority (${medPriority.length} files)\n\n`
|
||||
report += `DBAL and component files - moderate complexity\n\n`
|
||||
for (const file of medPriority.slice(0, 20)) {
|
||||
report += `- [ ] \`${file.path}\` (${file.lines} lines)\n`
|
||||
}
|
||||
if (medPriority.length > 20) {
|
||||
report += `- ... and ${medPriority.length - 20} more\n`
|
||||
}
|
||||
report += `\n`
|
||||
}
|
||||
|
||||
if (lowPriority.length > 0) {
|
||||
report += `### Low Priority (${lowPriority.length} files)\n\n`
|
||||
for (const file of lowPriority.slice(0, 20)) {
|
||||
report += `- [ ] \`${file.path}\` (${file.lines} lines)\n`
|
||||
}
|
||||
if (lowPriority.length > 20) {
|
||||
report += `- ... and ${lowPriority.length - 20} more\n`
|
||||
}
|
||||
report += `\n`
|
||||
}
|
||||
|
||||
// Skipped files
|
||||
const skipped = files.filter(f => f.status === 'skipped')
|
||||
if (skipped.length > 0) {
|
||||
report += `### Skipped Files (${skipped.length})\n\n`
|
||||
report += `These files do not need refactoring:\n\n`
|
||||
for (const file of skipped.slice(0, 10)) {
|
||||
report += `- \`${file.path}\` (${file.lines} lines) - ${file.reason}\n`
|
||||
}
|
||||
if (skipped.length > 10) {
|
||||
report += `- ... and ${skipped.length - 10} more\n`
|
||||
}
|
||||
report += `\n`
|
||||
}
|
||||
|
||||
report += `## Refactoring Patterns\n\n`
|
||||
report += `### For Library Files\n`
|
||||
report += `1. Create a \`functions/\` subdirectory\n`
|
||||
report += `2. Extract each function to its own file\n`
|
||||
report += `3. Create a class wrapper (like SchemaUtils)\n`
|
||||
report += `4. Update main file to re-export\n`
|
||||
report += `5. Verify tests still pass\n\n`
|
||||
|
||||
report += `### For Components\n`
|
||||
report += `1. Extract hooks into separate files\n`
|
||||
report += `2. Extract sub-components\n`
|
||||
report += `3. Extract utility functions\n`
|
||||
report += `4. Keep main component < 150 lines\n\n`
|
||||
|
||||
report += `### For DBAL Files\n`
|
||||
report += `1. Split adapters by operation type\n`
|
||||
report += `2. Extract provider implementations\n`
|
||||
report += `3. Keep interfaces separate from implementations\n\n`
|
||||
|
||||
report += `## Example: SchemaUtils Pattern\n\n`
|
||||
report += `The \`frontends/nextjs/src/lib/schema/\` directory demonstrates the lambda-per-file pattern:\n\n`
|
||||
report += `\`\`\`\n`
|
||||
report += `schema/\n`
|
||||
report += `├── functions/\n`
|
||||
report += `│ ├── field/\n`
|
||||
report += `│ │ ├── get-field-label.ts\n`
|
||||
report += `│ │ ├── validate-field.ts\n`
|
||||
report += `│ │ └── ...\n`
|
||||
report += `│ ├── model/\n`
|
||||
report += `│ │ ├── find-model.ts\n`
|
||||
report += `│ │ └── ...\n`
|
||||
report += `│ └── index.ts (re-exports all)\n`
|
||||
report += `├── SchemaUtils.ts (class wrapper)\n`
|
||||
report += `└── schema-utils.ts (backward compat re-exports)\n`
|
||||
report += `\`\`\`\n\n`
|
||||
|
||||
return report
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const rootDir = process.cwd()
|
||||
console.log('Scanning for TypeScript files exceeding 150 lines...')
|
||||
|
||||
const files = await findLargeFiles(rootDir, 150)
|
||||
console.log(`Found ${files.length} files`)
|
||||
|
||||
const report = await generateReport(files)
|
||||
|
||||
const outputPath = path.join(rootDir, 'docs', 'todo', 'LAMBDA_REFACTOR_PROGRESS.md')
|
||||
await fs.writeFile(outputPath, report, 'utf-8')
|
||||
|
||||
console.log(`Report generated: ${outputPath}`)
|
||||
console.log(`\nSummary:`)
|
||||
console.log(`- Total files: ${files.length}`)
|
||||
console.log(`- Pending refactor: ${files.filter(f => f.status === 'pending').length}`)
|
||||
console.log(`- Skipped: ${files.filter(f => f.status === 'skipped').length}`)
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch(console.error)
|
||||
}
|
||||
|
||||
export { findLargeFiles, generateReport }
|
||||
Reference in New Issue
Block a user