|
| 1 | +# Copilot Instructions for n8n-nodes-jupiterone |
| 2 | + |
| 3 | +You are reviewing code for an n8n community node package that integrates with JupiterOne security platform. |
| 4 | + |
| 5 | +## Repository Context |
| 6 | +- **Type**: n8n community node package |
| 7 | +- **Purpose**: JupiterOne API integration (security/compliance platform) |
| 8 | +- **Language**: TypeScript with strict mode |
| 9 | +- **Architecture**: Credentials + Query Node + Webhook Node |
| 10 | + |
| 11 | +## Review Priority Levels |
| 12 | + |
| 13 | +### 🚨 CRITICAL - Must Fix Immediately |
| 14 | +- Security vulnerabilities in credential handling |
| 15 | +- Type safety violations (any types, implicit returns) |
| 16 | +- Authentication bypass or credential exposure |
| 17 | +- API endpoint security issues |
| 18 | +- Error handling that exposes sensitive data |
| 19 | + |
| 20 | +### ⚠️ HIGH - Should Fix Before Merge |
| 21 | +- n8n compliance violations |
| 22 | +- Performance issues (memory leaks, inefficient loops) |
| 23 | +- Poor user experience (unclear errors, missing validation) |
| 24 | +- Inappropriate logging of sensitive data |
| 25 | +- Missing input validation |
| 26 | + |
| 27 | +### 🔧 MEDIUM - Nice to Fix |
| 28 | +- Code consistency and formatting |
| 29 | +- Documentation gaps |
| 30 | +- Error handling improvements |
| 31 | +- Type definition enhancements |
| 32 | +- Test coverage gaps |
| 33 | + |
| 34 | +## n8n Framework Requirements |
| 35 | + |
| 36 | +### Credential Files (`.credentials.ts`) |
| 37 | +**REQUIRED:** |
| 38 | +- Implement `ICredentialType` interface |
| 39 | +- Include `authenticate` configuration |
| 40 | +- Use `typeOptions: { password: true }` for sensitive fields |
| 41 | +- Follow naming: `jupiteroneApi` (not `JupiterOneApi`) |
| 42 | +- Provide `test` property for validation |
| 43 | + |
| 44 | +### Node Files (`.node.ts`) |
| 45 | +**REQUIRED:** |
| 46 | +- Implement `INodeType` interface |
| 47 | +- Complete `description` object with all fields |
| 48 | +- Use `NodeConnectionType.Main` for I/O |
| 49 | +- Implement `execute()` method (regular nodes) |
| 50 | +- Implement `webhook()` method (webhook nodes) |
| 51 | +- Use `NodeApiError` for error handling |
| 52 | + |
| 53 | +### Security Requirements |
| 54 | +**CRITICAL:** |
| 55 | +- Validate ALL user inputs before API calls |
| 56 | +- Use `this.getCredentials()` for secure access |
| 57 | +- NEVER log sensitive data (tokens, passwords) |
| 58 | +- Handle authentication errors gracefully |
| 59 | +- Validate API responses before processing |
| 60 | + |
| 61 | +## Code Quality Standards |
| 62 | + |
| 63 | +### TypeScript Requirements |
| 64 | +**MANDATORY:** |
| 65 | +- Use strict TypeScript (`strict: true`) |
| 66 | +- NO `any` types - use proper interfaces |
| 67 | +- Handle null/undefined explicitly |
| 68 | +- Use proper type assertions |
| 69 | +- Implement error types and interfaces |
| 70 | + |
| 71 | +### Code Structure |
| 72 | +**REQUIRED:** |
| 73 | +- Consistent naming conventions |
| 74 | +- Meaningful variable/function names |
| 75 | +- Organize imports (n8n types first) |
| 76 | +- Use constants for magic values |
| 77 | +- Implement error boundaries |
| 78 | + |
| 79 | +### Error Handling |
| 80 | +**CRITICAL:** |
| 81 | +- Catch ALL potential errors |
| 82 | +- User-friendly error messages |
| 83 | +- Appropriate logging (no sensitive data) |
| 84 | +- Don't expose internal details |
| 85 | +- Validate API responses |
| 86 | + |
| 87 | +## JupiterOne Integration Requirements |
| 88 | + |
| 89 | +### API Integration |
| 90 | +**REQUIRED:** |
| 91 | +- Handle API rate limits gracefully |
| 92 | +- Validate J1QL queries before execution |
| 93 | +- Implement pagination for large results |
| 94 | +- Handle GraphQL errors properly |
| 95 | +- Use appropriate timeouts |
| 96 | + |
| 97 | +### Data Processing |
| 98 | +**REQUIRED:** |
| 99 | +- Validate query results before returning |
| 100 | +- Handle empty/malformed responses |
| 101 | +- Implement data transformation |
| 102 | +- Respect data limits and constraints |
| 103 | + |
| 104 | +## Common Anti-Patterns (REJECT THESE) |
| 105 | + |
| 106 | +### 🔴 Security Violations |
| 107 | +```typescript |
| 108 | +// ❌ REJECT: Logging sensitive data |
| 109 | +this.logger.info(`Token: ${accessToken}`); |
| 110 | + |
| 111 | +// ✅ ACCEPT: Redacted logging |
| 112 | +this.logger.info('Authorization: Bearer [REDACTED]'); |
| 113 | +``` |
| 114 | + |
| 115 | +### 🔴 Type Safety Violations |
| 116 | +```typescript |
| 117 | +// ❌ REJECT: Using any types |
| 118 | +const data: any = response.data; |
| 119 | + |
| 120 | +// ✅ ACCEPT: Proper interfaces |
| 121 | +const data: JupiterOneResponse = response.data; |
| 122 | +``` |
| 123 | + |
| 124 | +### 🔴 Error Handling Violations |
| 125 | +```typescript |
| 126 | +// ❌ REJECT: Ignoring errors |
| 127 | +const result = await apiCall(); |
| 128 | + |
| 129 | +// ✅ ACCEPT: Proper error handling |
| 130 | +try { |
| 131 | + const result = await apiCall(); |
| 132 | +} catch (error) { |
| 133 | + throw new NodeApiError(this.getNode(), { |
| 134 | + message: 'API call failed', |
| 135 | + description: error.message, |
| 136 | + }); |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +### 🔴 Input Validation Violations |
| 141 | +```typescript |
| 142 | +// ❌ REJECT: No input validation |
| 143 | +const query = this.getNodeParameter('query'); |
| 144 | + |
| 145 | +// ✅ ACCEPT: Input validation |
| 146 | +const query = this.getNodeParameter('query') as string; |
| 147 | +if (!query || query.trim().length === 0) { |
| 148 | + throw new NodeApiError(this.getNode(), { |
| 149 | + message: 'Query parameter is required', |
| 150 | + }); |
| 151 | +} |
| 152 | +``` |
| 153 | + |
| 154 | +## Performance Anti-Patterns (REJECT THESE) |
| 155 | + |
| 156 | +### 🔴 Inefficient Processing |
| 157 | +```typescript |
| 158 | +// ❌ REJECT: Blocking async operations |
| 159 | +for (let i = 0; i < items.length; i++) { |
| 160 | + await processItem(items[i]); // Blocks execution |
| 161 | +} |
| 162 | + |
| 163 | +// ✅ ACCEPT: Parallel processing |
| 164 | +const promises = items.map(item => processItem(item)); |
| 165 | +const results = await Promise.all(promises); |
| 166 | +``` |
| 167 | + |
| 168 | +### 🔴 Memory Issues |
| 169 | +```typescript |
| 170 | +// ❌ REJECT: Accumulating large arrays |
| 171 | +let allResults = []; |
| 172 | +for (const item of items) { |
| 173 | + allResults.push(await processItem(item)); |
| 174 | +} |
| 175 | + |
| 176 | +// ✅ ACCEPT: Batch processing |
| 177 | +const batchSize = 100; |
| 178 | +for (let i = 0; i < items.length; i += batchSize) { |
| 179 | + const batch = items.slice(i, i + batchSize); |
| 180 | + // Process batch |
| 181 | +} |
| 182 | +``` |
| 183 | + |
| 184 | +## Testing Requirements |
| 185 | + |
| 186 | +### Credential Testing |
| 187 | +**REQUIRED:** |
| 188 | +- Test authentication flow |
| 189 | +- Validate all credential fields |
| 190 | +- Handle test failures gracefully |
| 191 | +- Use appropriate test endpoints |
| 192 | + |
| 193 | +### Node Testing |
| 194 | +**REQUIRED:** |
| 195 | +- Validate all input parameters |
| 196 | +- Handle edge cases (empty inputs, large datasets) |
| 197 | +- Test error scenarios |
| 198 | +- Validate output data structure |
| 199 | + |
| 200 | +## Documentation Requirements |
| 201 | + |
| 202 | +### Code Comments |
| 203 | +**REQUIRED:** |
| 204 | +- Document complex business logic |
| 205 | +- Explain JupiterOne-specific concepts |
| 206 | +- Provide usage examples |
| 207 | +- Document error handling strategies |
| 208 | + |
| 209 | +### User Documentation |
| 210 | +**REQUIRED:** |
| 211 | +- Clear parameter descriptions |
| 212 | +- Example values and formats |
| 213 | +- Document limitations/constraints |
| 214 | +- Provide troubleshooting guidance |
| 215 | + |
| 216 | +## Review Checklist (Use This) |
| 217 | + |
| 218 | +### Pre-Approval Checklist |
| 219 | +- [ ] TypeScript errors resolved |
| 220 | +- [ ] ESLint rules passing |
| 221 | +- [ ] No security vulnerabilities |
| 222 | +- [ ] Proper error handling implemented |
| 223 | +- [ ] Input validation in place |
| 224 | +- [ ] Sensitive data not logged |
| 225 | +- [ ] n8n standards followed |
| 226 | +- [ ] JupiterOne API best practices followed |
| 227 | +- [ ] Performance considerations addressed |
| 228 | +- [ ] Documentation updated |
| 229 | + |
| 230 | +### Key Review Questions |
| 231 | +1. **Security**: Could this expose sensitive information? |
| 232 | +2. **Type Safety**: Are types properly defined and used? |
| 233 | +3. **Error Handling**: Are all error cases handled? |
| 234 | +4. **Performance**: Could this cause performance issues? |
| 235 | +5. **User Experience**: Is error messaging clear? |
| 236 | +6. **n8n Compliance**: Follows community standards? |
| 237 | +7. **JupiterOne Integration**: Best API interaction method? |
| 238 | + |
| 239 | +## Quick Reference Links |
| 240 | +- [n8n Community Nodes](https://docs.n8n.io/integrations/#community-nodes) |
| 241 | +- [n8n Workflow Types](https://docs.n8n.io/api/) |
| 242 | +- [JupiterOne API Docs](https://docs.jupiterone.io/) |
| 243 | +- [TypeScript Best Practices](https://www.typescriptlang.org/docs/) |
| 244 | +- [ESLint n8n Rules](https://github.com/n8n-io/eslint-plugin-n8n-nodes-base) |
| 245 | + |
| 246 | +--- |
| 247 | + |
| 248 | +**REMEMBER**: This is a SECURITY-FOCUSED JupiterOne integration. |
| 249 | +- 🚨 Security first |
| 250 | +- 🔒 Type safety required |
| 251 | +- 👥 User experience matters |
| 252 | +- 📋 n8n compliance mandatory |
0 commit comments