@sun-asterisk/impact-analyzer 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/copilot-instructions.md +116 -0
- package/.github/prompts/README.md +91 -0
- package/.github/prompts/task-001-refactor.prompt.md +241 -0
- package/.specify/bugs/bug-001-database-detector.md +222 -0
- package/.specify/plans/architecture.md +186 -0
- package/.specify/specs/features/api-impact-detection.md +317 -0
- package/.specify/specs/features/component-impact-detection.md +263 -0
- package/.specify/specs/features/database-impact-detection.md +247 -0
- package/.specify/tasks/task-001-refactor-api-detector.md +284 -0
- package/.specify/tasks/task-002-database-detector.md +593 -0
- package/.specify/tasks/task-003-component-detector.md +0 -0
- package/.specify/tasks/task-004-report.md +484 -0
- package/README.md +13 -19
- package/core/detectors/database-detector.js +702 -0
- package/{modules → core}/detectors/endpoint-detector.js +11 -8
- package/{modules → core}/report-generator.js +112 -23
- package/core/utils/logger.js +12 -0
- package/{modules → core}/utils/method-call-graph.js +20 -0
- package/index.js +6 -5
- package/package.json +1 -1
- package/modules/detectors/database-detector.js +0 -182
- /package/{modules → core}/change-detector.js +0 -0
- /package/{modules → core}/impact-analyzer.js +0 -0
- /package/{modules → core}/utils/ast-parser.js +0 -0
- /package/{modules → core}/utils/dependency-graph.js +0 -0
- /package/{modules → core}/utils/file-utils.js +0 -0
- /package/{modules → core}/utils/git-utils.js +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Feature Spec: Component Impact Detection
|
|
2
|
+
|
|
3
|
+
## 1. Overview
|
|
4
|
+
|
|
5
|
+
Identify UI components affected by code changes. This feature traces component dependencies to find parent components that may be impacted by changes to child components.
|
|
6
|
+
|
|
7
|
+
## 2. User Story
|
|
8
|
+
|
|
9
|
+
> As a developer reviewing a pull request,
|
|
10
|
+
> I want to see which UI components are affected by the code changes,
|
|
11
|
+
> So that I can plan visual testing and assess user-facing impact.
|
|
12
|
+
|
|
13
|
+
## 3. Functional Requirements
|
|
14
|
+
|
|
15
|
+
### FR-001: Detect Component Definitions
|
|
16
|
+
- **Description**: Identify React/Vue/Angular component definitions
|
|
17
|
+
- **Patterns to Support**:
|
|
18
|
+
- React functional components
|
|
19
|
+
- React class components
|
|
20
|
+
- React. FC type annotation
|
|
21
|
+
- Vue Single File Components (SFC)
|
|
22
|
+
- Vue Composition API (script setup)
|
|
23
|
+
- Angular @Component decorator
|
|
24
|
+
- **Acceptance Criteria**:
|
|
25
|
+
- Detects function components (named and arrow)
|
|
26
|
+
- Detects class components extending React.Component
|
|
27
|
+
- Detects Vue SFC script blocks
|
|
28
|
+
- Detects Angular component classes
|
|
29
|
+
|
|
30
|
+
### FR-002: Build Component Dependency Tree
|
|
31
|
+
- **Description**: Map component import/usage relationships
|
|
32
|
+
- **Input**: Changed component names
|
|
33
|
+
- **Output**: Tree of parent components
|
|
34
|
+
- **Acceptance Criteria**:
|
|
35
|
+
- Traces JSX/TSX component usage
|
|
36
|
+
- Resolves import statements
|
|
37
|
+
- Handles re-exports
|
|
38
|
+
- Handles dynamic imports
|
|
39
|
+
|
|
40
|
+
### FR-003: Detect Props/Interface Changes
|
|
41
|
+
- **Description**: Identify changes to component props
|
|
42
|
+
- **Patterns to Support**:
|
|
43
|
+
- TypeScript interface: `interface Props { }`
|
|
44
|
+
- TypeScript type: `type Props = { }`
|
|
45
|
+
- PropTypes definition
|
|
46
|
+
- Vue defineProps
|
|
47
|
+
- Angular @Input() decorator
|
|
48
|
+
- **Acceptance Criteria**:
|
|
49
|
+
- Detects added props
|
|
50
|
+
- Detects removed props
|
|
51
|
+
- Detects prop type changes
|
|
52
|
+
- Flags breaking prop changes
|
|
53
|
+
|
|
54
|
+
### FR-004: Find Parent Components
|
|
55
|
+
- **Description**: Locate all components that use the changed component
|
|
56
|
+
- **Input**: Changed component name and file
|
|
57
|
+
- **Output**: List of parent components with usage count
|
|
58
|
+
- **Acceptance Criteria**:
|
|
59
|
+
- Searches all component files in project
|
|
60
|
+
- Finds JSX usage: `<ComponentName />`
|
|
61
|
+
- Handles aliased imports
|
|
62
|
+
- Counts usage instances
|
|
63
|
+
|
|
64
|
+
### FR-005: Classify Component Type
|
|
65
|
+
- **Description**: Categorize the component framework and style
|
|
66
|
+
- **Types**:
|
|
67
|
+
- `react-functional`: React function components
|
|
68
|
+
- `react-class`: React class components
|
|
69
|
+
- `vue-sfc`: Vue Single File Components
|
|
70
|
+
- `vue-composition`: Vue Composition API
|
|
71
|
+
- `angular`: Angular components
|
|
72
|
+
- **Acceptance Criteria**:
|
|
73
|
+
- Correctly identifies React components
|
|
74
|
+
- Correctly identifies Vue components
|
|
75
|
+
- Correctly identifies Angular components
|
|
76
|
+
|
|
77
|
+
### FR-006: Generate Component Report
|
|
78
|
+
- **Description**: Compile component impacts into structured report
|
|
79
|
+
- **Output**: `ComponentImpact[]` array
|
|
80
|
+
- **Acceptance Criteria**:
|
|
81
|
+
- Includes component name and type
|
|
82
|
+
- Includes parent component list
|
|
83
|
+
- Indicates props changes
|
|
84
|
+
- Includes severity based on usage
|
|
85
|
+
|
|
86
|
+
## 4. Non-Functional Requirements
|
|
87
|
+
|
|
88
|
+
### NFR-001: Performance
|
|
89
|
+
- Analysis should add <10 seconds to total analysis time
|
|
90
|
+
- Should handle projects with 500+ components
|
|
91
|
+
|
|
92
|
+
### NFR-002: Accuracy
|
|
93
|
+
- Should detect >90% of component changes
|
|
94
|
+
- Should find >85% of parent component relationships
|
|
95
|
+
|
|
96
|
+
## 5. Output Schema
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
/**
|
|
100
|
+
* @typedef {Object} ComponentImpact
|
|
101
|
+
* @property {string} componentName - Component name
|
|
102
|
+
* @property {string} filePath - Path to component file
|
|
103
|
+
* @property {'react-functional'|'react-class'|'vue-sfc'|'vue-composition'|'angular'} componentType
|
|
104
|
+
* @property {ParentComponent[]} parentComponents
|
|
105
|
+
* @property {boolean} propsChanged - Whether props interface was modified
|
|
106
|
+
* @property {FileChange} changeSource
|
|
107
|
+
* @property {'low'|'medium'|'high'|'critical'} severity
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @typedef {Object} ParentComponent
|
|
112
|
+
* @property {string} name - Parent component name
|
|
113
|
+
* @property {string} filePath - Path to parent component
|
|
114
|
+
* @property {number} usageCount - How many times child is used
|
|
115
|
+
*/
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 6. Severity Classification
|
|
119
|
+
|
|
120
|
+
| Severity | Criteria |
|
|
121
|
+
|----------|----------|
|
|
122
|
+
| Critical | Props changed + >10 parent components |
|
|
123
|
+
| High | Props changed OR >10 parent components |
|
|
124
|
+
| Medium | 3-10 parent components |
|
|
125
|
+
| Low | <3 parent components |
|
|
126
|
+
|
|
127
|
+
## 7. Component Detection Patterns
|
|
128
|
+
|
|
129
|
+
### React Functional Components
|
|
130
|
+
```javascript
|
|
131
|
+
// Named function
|
|
132
|
+
function Button({ label }) {
|
|
133
|
+
return <button>{label}</button>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Arrow function
|
|
137
|
+
const Button = ({ label }) => <button>{label}</button>;
|
|
138
|
+
|
|
139
|
+
// React. FC type
|
|
140
|
+
const Button: React.FC<ButtonProps> = ({ label }) => { };
|
|
141
|
+
|
|
142
|
+
// forwardRef
|
|
143
|
+
const Button = forwardRef((props, ref) => { });
|
|
144
|
+
|
|
145
|
+
// memo
|
|
146
|
+
const Button = memo(({ label }) => { });
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### React Class Components
|
|
150
|
+
```javascript
|
|
151
|
+
class Button extends React.Component { }
|
|
152
|
+
class Button extends Component { }
|
|
153
|
+
class Button extends React.PureComponent { }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Vue Components
|
|
157
|
+
```vue
|
|
158
|
+
<!-- Options API -->
|
|
159
|
+
<script>
|
|
160
|
+
export default {
|
|
161
|
+
name: 'Button',
|
|
162
|
+
props: { label: String }
|
|
163
|
+
}
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<!-- Composition API -->
|
|
167
|
+
<script setup>
|
|
168
|
+
defineProps({ label: String })
|
|
169
|
+
</script>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Angular Components
|
|
173
|
+
```typescript
|
|
174
|
+
@Component({
|
|
175
|
+
selector: 'app-button',
|
|
176
|
+
template: '<button>{{label}}</button>'
|
|
177
|
+
})
|
|
178
|
+
export class ButtonComponent {
|
|
179
|
+
@Input() label: string;
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 8. Test Scenarios
|
|
184
|
+
|
|
185
|
+
### Scenario 1: Direct Component Change
|
|
186
|
+
- **Given**: A component's JSX is modified
|
|
187
|
+
- **When**: Analysis runs
|
|
188
|
+
- **Then**: Component is detected with its parent components
|
|
189
|
+
|
|
190
|
+
### Scenario 2: Props Interface Change
|
|
191
|
+
- **Given**: A component's Props interface is modified
|
|
192
|
+
- **When**: Analysis runs
|
|
193
|
+
- **Then**: `propsChanged` is true and severity is elevated
|
|
194
|
+
|
|
195
|
+
### Scenario 3: Shared Component Change
|
|
196
|
+
- **Given**: A shared component (used by 15+ parents) is modified
|
|
197
|
+
- **When**: Analysis runs
|
|
198
|
+
- **Then**: All parent components are listed, severity is high
|
|
199
|
+
|
|
200
|
+
### Scenario 4: Isolated Component Change
|
|
201
|
+
- **Given**: A component with no parents is modified
|
|
202
|
+
- **When**: Analysis runs
|
|
203
|
+
- **Then**: Component is detected with empty parent list
|
|
204
|
+
|
|
205
|
+
### Scenario 5: Style-Only Change
|
|
206
|
+
- **Given**: Only CSS/styles in a component file change
|
|
207
|
+
- **When**: Analysis runs
|
|
208
|
+
- **Then**: Component is detected with low severity
|
|
209
|
+
|
|
210
|
+
## 9. Edge Cases
|
|
211
|
+
|
|
212
|
+
| Case | Expected Behavior |
|
|
213
|
+
|------|-------------------|
|
|
214
|
+
| Higher-order components | Detect both wrapper and wrapped |
|
|
215
|
+
| Render props | Detect component, not render function |
|
|
216
|
+
| Context providers | Detect as component |
|
|
217
|
+
| CSS-only files | Skip, not a component |
|
|
218
|
+
| Test files | Skip (excluded by pattern) |
|
|
219
|
+
| Storybook files | Skip (excluded by pattern) |
|
|
220
|
+
|
|
221
|
+
## 10. Example
|
|
222
|
+
|
|
223
|
+
### Input
|
|
224
|
+
```javascript
|
|
225
|
+
// Changed file: src/components/Button/Button.jsx
|
|
226
|
+
// Modified lines: 5-8
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @typedef {Object} ButtonProps
|
|
230
|
+
* @property {string} label
|
|
231
|
+
* @property {string} variant // Line 5 - ADDED
|
|
232
|
+
* @property {() => void} onClick
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
function Button({ label, variant, onClick }) { // Line 8 - CHANGED
|
|
236
|
+
return (
|
|
237
|
+
<button className={variant} onClick={onClick}>
|
|
238
|
+
{label}
|
|
239
|
+
</button>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Expected Output
|
|
245
|
+
```javascript
|
|
246
|
+
{
|
|
247
|
+
component: [
|
|
248
|
+
{
|
|
249
|
+
componentName: "Button",
|
|
250
|
+
filePath: "src/components/Button/Button.jsx",
|
|
251
|
+
componentType: "react-functional",
|
|
252
|
+
parentComponents: [
|
|
253
|
+
{ name: "Header", filePath: "src/components/Header. jsx", usageCount: 2 },
|
|
254
|
+
{ name: "Modal", filePath: "src/components/Modal.jsx", usageCount: 1 },
|
|
255
|
+
{ name: "Form", filePath: "src/components/Form.jsx", usageCount: 3 }
|
|
256
|
+
],
|
|
257
|
+
propsChanged: true,
|
|
258
|
+
changeSource: { path: "src/components/Button/Button.jsx", ... },
|
|
259
|
+
severity: "medium"
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
```
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Feature Spec: Database Impact Detection
|
|
2
|
+
|
|
3
|
+
## 1. Overview
|
|
4
|
+
|
|
5
|
+
Identify database tables and models affected by code changes. This helps developers understand data layer impacts and plan database-related testing or migrations.
|
|
6
|
+
|
|
7
|
+
## 2. User Story
|
|
8
|
+
|
|
9
|
+
> As a developer reviewing a pull request,
|
|
10
|
+
> I want to see which database tables are affected by the code changes,
|
|
11
|
+
> So that I can assess data integrity risks and plan database testing.
|
|
12
|
+
|
|
13
|
+
## 3. Functional Requirements
|
|
14
|
+
|
|
15
|
+
### FR-001: Detect Entity/Model Changes
|
|
16
|
+
- **Description**: Identify changes to ORM entity or model files
|
|
17
|
+
- **Patterns to Support**:
|
|
18
|
+
- TypeORM: `@Entity()` decorator
|
|
19
|
+
- Sequelize: `@Table()` decorator, `Model.init()`
|
|
20
|
+
- Mongoose: `mongoose.model()`, `new Schema()`
|
|
21
|
+
- Prisma: Changes to `schema.prisma`
|
|
22
|
+
- **Acceptance Criteria**:
|
|
23
|
+
- Detects new entity definitions
|
|
24
|
+
- Detects modified entity properties
|
|
25
|
+
- Detects deleted entities
|
|
26
|
+
- Detects relation changes
|
|
27
|
+
|
|
28
|
+
### FR-002: Extract Table Names
|
|
29
|
+
- **Description**: Determine database table name from entity definition
|
|
30
|
+
- **Sources**:
|
|
31
|
+
- Explicit table name in decorator: `@Entity('users')`
|
|
32
|
+
- Decorator options: `@Entity({ name: 'users' })`
|
|
33
|
+
- Class name conversion (PascalCase → snake_case)
|
|
34
|
+
- Sequelize tableName option
|
|
35
|
+
- Mongoose collection name
|
|
36
|
+
- **Acceptance Criteria**:
|
|
37
|
+
- Correctly extracts explicit table names
|
|
38
|
+
- Correctly converts class names when not specified
|
|
39
|
+
- Handles custom naming strategies
|
|
40
|
+
|
|
41
|
+
### FR-003: Detect Repository/DAO Changes
|
|
42
|
+
- **Description**: Find changes to data access layer code
|
|
43
|
+
- **Patterns to Support**:
|
|
44
|
+
- TypeORM Repository pattern
|
|
45
|
+
- Custom repository classes
|
|
46
|
+
- Query builder usage
|
|
47
|
+
- Raw SQL queries
|
|
48
|
+
- **Acceptance Criteria**:
|
|
49
|
+
- Identifies affected entity from repository
|
|
50
|
+
- Detects query method changes
|
|
51
|
+
- Identifies CRUD operations
|
|
52
|
+
|
|
53
|
+
### FR-004: Classify Impact Type
|
|
54
|
+
- **Description**: Categorize the type of database impact
|
|
55
|
+
- **Categories**:
|
|
56
|
+
- `schema`: Column/property changes, new entities
|
|
57
|
+
- `query`: Repository method changes
|
|
58
|
+
- `relation`: Foreign key/relation changes
|
|
59
|
+
- `migration`: Migration file changes
|
|
60
|
+
- **Acceptance Criteria**:
|
|
61
|
+
- Correctly classifies schema changes
|
|
62
|
+
- Correctly classifies query-only changes
|
|
63
|
+
- Correctly classifies relation changes
|
|
64
|
+
|
|
65
|
+
### FR-005: Identify CRUD Operations
|
|
66
|
+
- **Description**: Determine which database operations are affected
|
|
67
|
+
- **Operations**: SELECT, INSERT, UPDATE, DELETE
|
|
68
|
+
- **Detection Methods**:
|
|
69
|
+
- Method name analysis (find*, create*, update*, delete*)
|
|
70
|
+
- Query builder analysis
|
|
71
|
+
- Decorator analysis (@Query, etc.)
|
|
72
|
+
- **Acceptance Criteria**:
|
|
73
|
+
- Correctly identifies read operations
|
|
74
|
+
- Correctly identifies write operations
|
|
75
|
+
- Handles mixed operations
|
|
76
|
+
|
|
77
|
+
### FR-006: Generate Database Report
|
|
78
|
+
- **Description**: Compile database impacts into structured report
|
|
79
|
+
- **Output**: `DatabaseImpact[]` array
|
|
80
|
+
- **Acceptance Criteria**:
|
|
81
|
+
- Includes table name and model name
|
|
82
|
+
- Includes impact classification
|
|
83
|
+
- Includes affected operations
|
|
84
|
+
- Deduplicates by table/impact type
|
|
85
|
+
|
|
86
|
+
## 4. Non-Functional Requirements
|
|
87
|
+
|
|
88
|
+
### NFR-001: Performance
|
|
89
|
+
- Analysis should add <5 seconds to total analysis time
|
|
90
|
+
|
|
91
|
+
### NFR-002: Accuracy
|
|
92
|
+
- Should detect >95% of schema changes
|
|
93
|
+
- Should detect >85% of query changes
|
|
94
|
+
|
|
95
|
+
## 5. Output Schema
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
/**
|
|
99
|
+
* @typedef {Object} DatabaseImpact
|
|
100
|
+
* @property {string} tableName - Database table name (snake_case)
|
|
101
|
+
* @property {string} modelName - Entity/Model class name
|
|
102
|
+
* @property {string} modelPath - File path to model definition
|
|
103
|
+
* @property {'schema'|'query'|'relation'|'migration'} impactType
|
|
104
|
+
* @property {('SELECT'|'INSERT'|'UPDATE'|'DELETE')[]} operations
|
|
105
|
+
* @property {FileChange} changeSource
|
|
106
|
+
* @property {'low'|'medium'|'high'|'critical'} severity
|
|
107
|
+
*/
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 6. Severity Classification
|
|
111
|
+
|
|
112
|
+
| Severity | Criteria |
|
|
113
|
+
|----------|----------|
|
|
114
|
+
| Critical | Schema changes (columns, constraints) |
|
|
115
|
+
| High | Relation changes, DELETE operations |
|
|
116
|
+
| Medium | INSERT, UPDATE operations |
|
|
117
|
+
| Low | SELECT-only query changes |
|
|
118
|
+
|
|
119
|
+
## 7. ORM Detection Patterns
|
|
120
|
+
|
|
121
|
+
### TypeORM
|
|
122
|
+
```javascript
|
|
123
|
+
// Entity detection
|
|
124
|
+
@Entity('users')
|
|
125
|
+
@Entity({ name: 'users' })
|
|
126
|
+
class User { }
|
|
127
|
+
|
|
128
|
+
// Column detection
|
|
129
|
+
@Column()
|
|
130
|
+
@PrimaryColumn()
|
|
131
|
+
@PrimaryGeneratedColumn()
|
|
132
|
+
|
|
133
|
+
// Relation detection
|
|
134
|
+
@OneToMany()
|
|
135
|
+
@ManyToOne()
|
|
136
|
+
@OneToOne()
|
|
137
|
+
@ManyToMany()
|
|
138
|
+
|
|
139
|
+
// Repository detection
|
|
140
|
+
class UserRepository extends Repository<User> { }
|
|
141
|
+
@EntityRepository(User)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Sequelize
|
|
145
|
+
```javascript
|
|
146
|
+
// Model detection
|
|
147
|
+
@Table({ tableName: 'users' })
|
|
148
|
+
class User extends Model { }
|
|
149
|
+
|
|
150
|
+
User.init({ }, { tableName: 'users' })
|
|
151
|
+
|
|
152
|
+
// Column detection
|
|
153
|
+
@Column
|
|
154
|
+
@PrimaryKey
|
|
155
|
+
@AutoIncrement
|
|
156
|
+
|
|
157
|
+
// Relation detection
|
|
158
|
+
@HasMany()
|
|
159
|
+
@BelongsTo()
|
|
160
|
+
@BelongsToMany()
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Mongoose
|
|
164
|
+
```javascript
|
|
165
|
+
// Schema detection
|
|
166
|
+
const userSchema = new Schema({ })
|
|
167
|
+
mongoose.model('User', userSchema)
|
|
168
|
+
|
|
169
|
+
// Collection override
|
|
170
|
+
mongoose.model('User', userSchema, 'custom_users')
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Prisma
|
|
174
|
+
```prisma
|
|
175
|
+
// Model detection in schema. prisma
|
|
176
|
+
model User {
|
|
177
|
+
id Int @id @default(autoincrement())
|
|
178
|
+
email String @unique
|
|
179
|
+
posts Post[]
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 8. Test Scenarios
|
|
184
|
+
|
|
185
|
+
### Scenario 1: Entity Column Change
|
|
186
|
+
- **Given**: A property in an entity class is modified
|
|
187
|
+
- **When**: Analysis runs
|
|
188
|
+
- **Then**: Impact type is "schema" with high severity
|
|
189
|
+
|
|
190
|
+
### Scenario 2: New Relation Added
|
|
191
|
+
- **Given**: A new relation decorator is added
|
|
192
|
+
- **When**: Analysis runs
|
|
193
|
+
- **Then**: Impact type is "relation"
|
|
194
|
+
|
|
195
|
+
### Scenario 3: Repository Query Change
|
|
196
|
+
- **Given**: A repository method is modified
|
|
197
|
+
- **When**: Analysis runs
|
|
198
|
+
- **Then**: Impact type is "query" with affected operations
|
|
199
|
+
|
|
200
|
+
### Scenario 4: Prisma Schema Change
|
|
201
|
+
- **Given**: schema.prisma is modified
|
|
202
|
+
- **When**: Analysis runs
|
|
203
|
+
- **Then**: Affected models are detected
|
|
204
|
+
|
|
205
|
+
## 9. Edge Cases
|
|
206
|
+
|
|
207
|
+
| Case | Expected Behavior |
|
|
208
|
+
|------|-------------------|
|
|
209
|
+
| No ORM detected | Return empty array |
|
|
210
|
+
| Dynamic table names | Log warning, use class name |
|
|
211
|
+
| Abstract entities | Skip, not mapped to table |
|
|
212
|
+
| Embedded entities | Include in parent entity impact |
|
|
213
|
+
| View entities | Mark as "view" in output |
|
|
214
|
+
|
|
215
|
+
## 10. Example
|
|
216
|
+
|
|
217
|
+
### Input
|
|
218
|
+
```javascript
|
|
219
|
+
// Changed file: src/entities/user.entity. js
|
|
220
|
+
// Modified lines: 8-10
|
|
221
|
+
|
|
222
|
+
@Entity('users')
|
|
223
|
+
class User {
|
|
224
|
+
@Column()
|
|
225
|
+
email; // Line 8 - CHANGED
|
|
226
|
+
|
|
227
|
+
@Column({ nullable: true }) // Line 9 - ADDED
|
|
228
|
+
phone; // Line 10 - ADDED
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Expected Output
|
|
233
|
+
```javascript
|
|
234
|
+
{
|
|
235
|
+
database: [
|
|
236
|
+
{
|
|
237
|
+
tableName: "users",
|
|
238
|
+
modelName: "User",
|
|
239
|
+
modelPath: "src/entities/user.entity.js",
|
|
240
|
+
impactType: "schema",
|
|
241
|
+
operations: ["SELECT", "INSERT", "UPDATE"],
|
|
242
|
+
changeSource: { path: "src/entities/user. entity.js", ... },
|
|
243
|
+
severity: "critical"
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
```
|