|
| 1 | +# AST-based Validation Suite |
| 2 | + |
| 3 | +This comprehensive validation suite uses Abstract Syntax Tree (AST) analysis to enforce code quality standards across all packages in the devlog monorepo. It helps AI agents and developers maintain consistent, high-quality code by catching issues early. |
| 4 | + |
| 5 | +## 🎯 Overview |
| 6 | + |
| 7 | +The validation suite includes 5 specialized AST-based validation scripts that analyze TypeScript code for: |
| 8 | + |
| 9 | +- **TypeScript Best Practices** - Type safety, async patterns, error handling |
| 10 | +- **Architecture Patterns** - Manager classes, interfaces, service layers |
| 11 | +- **Testing Standards** - Test structure, isolation, async patterns |
| 12 | +- **Security & Performance** - Security vulnerabilities, performance anti-patterns |
| 13 | +- **Import Patterns** - ESM imports, cross-package dependencies |
| 14 | + |
| 15 | +## 🚀 Quick Start |
| 16 | + |
| 17 | +### Run All Validations |
| 18 | +```bash |
| 19 | +npm run validate |
| 20 | +# or |
| 21 | +node scripts/validate-all-ast.js |
| 22 | +``` |
| 23 | + |
| 24 | +### Run Specific Validation |
| 25 | +```bash |
| 26 | +npm run validate:typescript |
| 27 | +npm run validate:architecture |
| 28 | +npm run validate:testing |
| 29 | +npm run validate:security |
| 30 | +npm run validate:imports |
| 31 | +``` |
| 32 | + |
| 33 | +### Quick Mode (Skip Build/Type Checks) |
| 34 | +```bash |
| 35 | +npm run validate:quick |
| 36 | +# or |
| 37 | +node scripts/validate-all-ast.js --quick |
| 38 | +``` |
| 39 | + |
| 40 | +## 📋 Available Commands |
| 41 | + |
| 42 | +| Command | Description | |
| 43 | +|---------|-------------| |
| 44 | +| `npm run validate` | Run complete validation suite | |
| 45 | +| `npm run validate:quick` | Quick validation (no build/types) | |
| 46 | +| `npm run validate:list` | List all available validations | |
| 47 | +| `npm run validate:typescript` | TypeScript best practices | |
| 48 | +| `npm run validate:architecture` | Architecture patterns | |
| 49 | +| `npm run validate:testing` | Testing standards | |
| 50 | +| `npm run validate:security` | Security & performance | |
| 51 | +| `npm run validate:imports` | Import patterns | |
| 52 | + |
| 53 | +### Orchestrator Options |
| 54 | + |
| 55 | +```bash |
| 56 | +# Show help |
| 57 | +node scripts/validate-all-ast.js --help |
| 58 | + |
| 59 | +# List available scripts |
| 60 | +node scripts/validate-all-ast.js --list |
| 61 | + |
| 62 | +# Run specific script |
| 63 | +node scripts/validate-all-ast.js --script typescript |
| 64 | + |
| 65 | +# Skip build validation (faster) |
| 66 | +node scripts/validate-all-ast.js --no-build |
| 67 | + |
| 68 | +# Skip TypeScript compilation check |
| 69 | +node scripts/validate-all-ast.js --no-types |
| 70 | + |
| 71 | +# Quick mode (skip both) |
| 72 | +node scripts/validate-all-ast.js --quick |
| 73 | +``` |
| 74 | + |
| 75 | +## 🔍 Validation Details |
| 76 | + |
| 77 | +### 1. TypeScript Best Practices (`validate-typescript-best-practices-ast.js`) |
| 78 | + |
| 79 | +**Checks for:** |
| 80 | +- ❌ Usage of `any` type (warnings) |
| 81 | +- ❌ Non-null assertion operator overuse |
| 82 | +- ❌ Unsafe type assertions |
| 83 | +- ❌ Missing await on async methods |
| 84 | +- ❌ Async functions without error handling |
| 85 | +- ❌ Empty catch blocks (errors) |
| 86 | +- ❌ Throwing strings instead of Error objects |
| 87 | +- ❌ Missing JSDoc on exported APIs |
| 88 | +- ❌ Unconstrained generic types |
| 89 | + |
| 90 | +**Example Issues Caught:** |
| 91 | +```typescript |
| 92 | +// ❌ Will warn about 'any' usage |
| 93 | +function process(data: any) { ... } |
| 94 | + |
| 95 | +// ❌ Will error on empty catch |
| 96 | +try { ... } catch (e) { } |
| 97 | + |
| 98 | +// ❌ Will warn about missing await |
| 99 | +async function example() { |
| 100 | + manager.initialize(); // Should be: await manager.initialize() |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +### 2. Architecture Patterns (`validate-architecture-patterns-ast.js`) |
| 105 | + |
| 106 | +**Checks for:** |
| 107 | +- ❌ Manager classes missing `initialize()`/`dispose()` methods (errors) |
| 108 | +- ❌ Manager methods should be async |
| 109 | +- ❌ Missing dependency injection in constructors |
| 110 | +- ❌ Interfaces not prefixed with 'I' |
| 111 | +- ❌ Service classes with mutable state |
| 112 | +- ❌ Storage providers not extending base classes |
| 113 | +- ❌ Package-specific patterns (MCP tools, React components, etc.) |
| 114 | + |
| 115 | +**Example Issues Caught:** |
| 116 | +```typescript |
| 117 | +// ❌ Manager missing required methods |
| 118 | +export class UserManager { |
| 119 | + constructor(private storage: Storage) {} // ✅ Has DI |
| 120 | + // ❌ Missing initialize() and dispose() methods |
| 121 | +} |
| 122 | + |
| 123 | +// ❌ Interface naming |
| 124 | +interface StorageProvider { ... } // Should be: IStorageProvider |
| 125 | +``` |
| 126 | + |
| 127 | +### 3. Testing Standards (`validate-testing-standards-ast.js`) |
| 128 | + |
| 129 | +**Checks for:** |
| 130 | +- ❌ Test files missing testing framework imports (errors) |
| 131 | +- ❌ Tests without assertions |
| 132 | +- ❌ Missing test isolation (cleanup in afterEach) |
| 133 | +- ❌ Async tests without proper await patterns |
| 134 | +- ❌ File system operations without temporary directories |
| 135 | +- ❌ Mock usage without cleanup |
| 136 | +- ❌ Poor test naming (should start with "should") |
| 137 | + |
| 138 | +**Example Issues Caught:** |
| 139 | +```typescript |
| 140 | +// ❌ Missing framework import |
| 141 | +describe('Component', () => { ... }); // Missing: import { describe, it } from 'vitest' |
| 142 | + |
| 143 | +// ❌ Test without assertion |
| 144 | +it('should work', async () => { |
| 145 | + await component.doSomething(); |
| 146 | + // ❌ No expect() call |
| 147 | +}); |
| 148 | + |
| 149 | +// ❌ File operations without cleanup |
| 150 | +beforeEach(() => { |
| 151 | + fs.writeFileSync('test.txt', 'data'); // ❌ Should use temp directories |
| 152 | +}); |
| 153 | +``` |
| 154 | + |
| 155 | +### 4. Security & Performance (`validate-security-performance-ast.js`) |
| 156 | + |
| 157 | +**Security Checks:** |
| 158 | +- ❌ XSS vulnerabilities (`innerHTML` usage) (errors) |
| 159 | +- ❌ `eval()` usage (errors) |
| 160 | +- ❌ Hardcoded secrets/credentials (errors) |
| 161 | +- ❌ SQL injection patterns (errors) |
| 162 | +- ❌ Dangerous regex patterns (ReDoS) (warnings) |
| 163 | +- ❌ Path traversal vulnerabilities (warnings) |
| 164 | + |
| 165 | +**Performance Checks:** |
| 166 | +- ❌ Synchronous blocking operations (warnings) |
| 167 | +- ❌ Inefficient nested loops (warnings) |
| 168 | +- ❌ Memory leaks (timer cleanup, event listeners) (warnings) |
| 169 | +- ❌ Inefficient array operations (warnings) |
| 170 | +- ❌ Large object literals (warnings) |
| 171 | + |
| 172 | +**Example Issues Caught:** |
| 173 | +```typescript |
| 174 | +// ❌ Security: XSS vulnerability |
| 175 | +element.innerHTML = userInput; // Should sanitize or use textContent |
| 176 | + |
| 177 | +// ❌ Security: Hardcoded secret |
| 178 | +const apiKey = "sk-1234567890abcdef"; // Should use environment variables |
| 179 | + |
| 180 | +// ❌ Performance: Sync operation |
| 181 | +const data = fs.readFileSync('file.txt'); // Should use async version |
| 182 | + |
| 183 | +// ❌ Performance: Timer leak |
| 184 | +setInterval(() => { ... }, 1000); // Missing clearInterval in cleanup |
| 185 | +``` |
| 186 | + |
| 187 | +### 5. Import Patterns (`validate-imports.js`) |
| 188 | + |
| 189 | +**Checks for:** |
| 190 | +- ❌ Missing `.js` extensions on relative imports (errors) |
| 191 | +- ❌ Self-referencing `@/` aliases (outside web package) (errors) |
| 192 | +- ❌ Cross-package relative imports (errors) |
| 193 | +- ❌ Invalid package names in cross-package imports (errors) |
| 194 | + |
| 195 | +**Example Issues Caught:** |
| 196 | +```typescript |
| 197 | +// ❌ Missing .js extension |
| 198 | +import { Helper } from './helper'; // Should be: './helper.js' |
| 199 | + |
| 200 | +// ❌ Cross-package relative import |
| 201 | +import { CoreType } from '../../core/src/types'; // Should be: '@devlog/core' |
| 202 | + |
| 203 | +// ❌ Self-referencing alias (outside web package) |
| 204 | +import { Utils } from '@/utils'; // Should use relative: './utils.js' |
| 205 | +``` |
| 206 | + |
| 207 | +## 📊 Output Format |
| 208 | + |
| 209 | +The validation scripts provide detailed, actionable feedback: |
| 210 | + |
| 211 | +``` |
| 212 | +❌ Found 2 TypeScript best practice errors: |
| 213 | +
|
| 214 | +📁 packages/core/src/manager.ts:45 [EMPTY_CATCH_BLOCK] |
| 215 | + Empty catch block - errors should be handled |
| 216 | + 💡 Add error logging, re-throwing, or proper error handling |
| 217 | +
|
| 218 | +📁 packages/web/components/Button.tsx:12 [MISSING_JSDOC] |
| 219 | + Exported function "Button" missing JSDoc documentation |
| 220 | + 💡 Add JSDoc comments for public API documentation |
| 221 | +``` |
| 222 | + |
| 223 | +## 🎯 Exit Codes |
| 224 | + |
| 225 | +- **0**: All validations passed (or warnings only) |
| 226 | +- **1**: Critical errors found (must be fixed) |
| 227 | + |
| 228 | +## 🛠️ Integration |
| 229 | + |
| 230 | +### Pre-commit Hook |
| 231 | +The validation is integrated into the pre-commit hook: |
| 232 | +```json |
| 233 | +"pre-commit": "lint-staged && node scripts/validate-imports.js" |
| 234 | +``` |
| 235 | + |
| 236 | +### CI/CD Integration |
| 237 | +Add to your CI pipeline: |
| 238 | +```yaml |
| 239 | +- name: Validate Code Quality |
| 240 | + run: npm run validate |
| 241 | +``` |
| 242 | +
|
| 243 | +### Development Workflow |
| 244 | +```bash |
| 245 | +# Before committing |
| 246 | +npm run validate:quick |
| 247 | + |
| 248 | +# Full validation before PR |
| 249 | +npm run validate |
| 250 | + |
| 251 | +# Fix specific issues |
| 252 | +npm run validate:typescript |
| 253 | +``` |
| 254 | + |
| 255 | +## 📈 Benefits |
| 256 | + |
| 257 | +### For AI Agents |
| 258 | +- **Consistent Patterns**: Enforces architectural patterns AI can rely on |
| 259 | +- **Early Error Detection**: Catches issues before they compound |
| 260 | +- **Code Quality Gates**: Prevents degradation during automated changes |
| 261 | +- **Contextual Guidance**: Provides specific suggestions for fixes |
| 262 | + |
| 263 | +### For Developers |
| 264 | +- **Code Reviews**: Automated checks reduce manual review overhead |
| 265 | +- **Learning Tool**: Warnings teach best practices |
| 266 | +- **Refactoring Safety**: Catches regressions during code changes |
| 267 | +- **Documentation**: Enforces API documentation standards |
| 268 | + |
| 269 | +### For Project Maintenance |
| 270 | +- **Consistency**: Uniform code style across all packages |
| 271 | +- **Security**: Proactive security vulnerability detection |
| 272 | +- **Performance**: Early performance anti-pattern detection |
| 273 | +- **Scalability**: Maintains quality as codebase grows |
| 274 | + |
| 275 | +## 🔧 Customization |
| 276 | + |
| 277 | +### Adding New Validations |
| 278 | + |
| 279 | +1. Create new validation script in `scripts/` directory |
| 280 | +2. Follow naming pattern: `validate-{name}-ast.js` |
| 281 | +3. Export main function for orchestrator integration |
| 282 | +4. Add to `package.json` scripts section |
| 283 | + |
| 284 | +### Modifying Validation Rules |
| 285 | + |
| 286 | +Each validation script contains clearly marked sections for different types of checks. Modify the validation logic in the specific `validate*` functions within each script. |
| 287 | + |
| 288 | +### Package-Specific Rules |
| 289 | + |
| 290 | +The architecture validation includes package-specific checks: |
| 291 | +- **Core**: Manager exports, type exports |
| 292 | +- **MCP**: Tool patterns, error handling |
| 293 | +- **Web**: React patterns, Next.js routes |
| 294 | +- **AI**: Parser implementations |
| 295 | + |
| 296 | +## 🎁 Summary |
| 297 | + |
| 298 | +This AST-based validation suite provides comprehensive code quality enforcement that helps maintain a high-quality, consistent codebase. It's designed to work seamlessly with AI agents while providing valuable feedback to human developers. The modular design allows for easy extension and customization as the project evolves. |
0 commit comments