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:
copilot-swe-agent[bot]
2025-12-27 15:35:53 +00:00
parent e249268070
commit 7feb4491c0
2 changed files with 384 additions and 0 deletions

View 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)
```

View 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 }