evnict-kit 0.2.1

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.
Files changed (138) hide show
  1. package/README.md +19 -0
  2. package/bin/cli.js +38 -0
  3. package/package.json +48 -0
  4. package/src/commands/add.js +129 -0
  5. package/src/commands/init-check.js +19 -0
  6. package/src/commands/init-context.js +37 -0
  7. package/src/commands/init-rules.js +42 -0
  8. package/src/commands/init-workflow.js +36 -0
  9. package/src/commands/init.js +722 -0
  10. package/src/utils/config.js +167 -0
  11. package/src/utils/file.js +53 -0
  12. package/templates/GETTING-STARTED.md +196 -0
  13. package/templates/content/context/AGENTS.md.template +462 -0
  14. package/templates/content/rules/01-evnict-kit-general-rules.md +303 -0
  15. package/templates/content/rules/02-evnict-kit-security-rules.md +423 -0
  16. package/templates/content/rules/03-evnict-kit-backend-conventions.md +383 -0
  17. package/templates/content/rules/04-evnict-kit-frontend-conventions.md +402 -0
  18. package/templates/content/rules/05-evnict-kit-project-conventions.md +228 -0
  19. package/templates/content/skills/evnict-kit-brainstorm/SKILL.md +140 -0
  20. package/templates/content/skills/evnict-kit-bug-fix/SKILL.md +108 -0
  21. package/templates/content/skills/evnict-kit-checkpoint/SKILL.md +156 -0
  22. package/templates/content/skills/evnict-kit-code-review/SKILL.md +158 -0
  23. package/templates/content/skills/evnict-kit-coordinate/SKILL.md +274 -0
  24. package/templates/content/skills/evnict-kit-create-api/SKILL.md +281 -0
  25. package/templates/content/skills/evnict-kit-create-component/SKILL.md +263 -0
  26. package/templates/content/skills/evnict-kit-create-page/SKILL.md +247 -0
  27. package/templates/content/skills/evnict-kit-database-migration/SKILL.md +164 -0
  28. package/templates/content/skills/evnict-kit-doc-postmortem/SKILL.md +93 -0
  29. package/templates/content/skills/evnict-kit-finish-branch/SKILL.md +87 -0
  30. package/templates/content/skills/evnict-kit-fix-attt/SKILL.md +129 -0
  31. package/templates/content/skills/evnict-kit-fix-business-logic/SKILL.md +89 -0
  32. package/templates/content/skills/evnict-kit-git-worktrees/SKILL.md +104 -0
  33. package/templates/content/skills/evnict-kit-merge-checklist/SKILL.md +108 -0
  34. package/templates/content/skills/evnict-kit-onboard/SKILL.md +143 -0
  35. package/templates/content/skills/evnict-kit-prompt-standard/SKILL.md +103 -0
  36. package/templates/content/skills/evnict-kit-receiving-review/SKILL.md +89 -0
  37. package/templates/content/skills/evnict-kit-security-audit/SKILL.md +190 -0
  38. package/templates/content/skills/evnict-kit-spec/SKILL.md +237 -0
  39. package/templates/content/skills/evnict-kit-tdd/SKILL.md +413 -0
  40. package/templates/content/skills/evnict-kit-wiki/SKILL.md +412 -0
  41. package/templates/content/workflows/evnict-kit-archive-wiki.md +100 -0
  42. package/templates/content/workflows/evnict-kit-attt.md +100 -0
  43. package/templates/content/workflows/evnict-kit-bug-fix.md +107 -0
  44. package/templates/content/workflows/evnict-kit-feature-large.md +393 -0
  45. package/templates/content/workflows/evnict-kit-feature-small.md +86 -0
  46. package/templates/content/workflows/evnict-kit-handoff.md +243 -0
  47. package/templates/content/workflows/evnict-kit-implement.md +247 -0
  48. package/templates/content/workflows/evnict-kit-init-check.md +76 -0
  49. package/templates/content/workflows/evnict-kit-init-context.md +58 -0
  50. package/templates/content/workflows/evnict-kit-init-rules.md +114 -0
  51. package/templates/content/workflows/evnict-kit-init-wiki.md +80 -0
  52. package/templates/content/workflows/evnict-kit-plan.md +308 -0
  53. package/templates/content/workflows/evnict-kit-review.md +53 -0
  54. package/templates/content/workflows/evnict-kit-spec-archive.md +53 -0
  55. package/templates/content/workflows/evnict-kit-wiki-archive-feature.md +164 -0
  56. package/templates/content/workflows/evnict-kit-wiki-query.md +91 -0
  57. package/templates/content/workflows/evnict-kit-wiki-scan-project.md +272 -0
  58. package/templates/context/AGENT.md.template +9 -0
  59. package/templates/context/AGENTS.md.template +462 -0
  60. package/templates/context/CLAUDE.md.template +301 -0
  61. package/templates/context/copilot-instructions.md.template +60 -0
  62. package/templates/context/cursorrules.template +114 -0
  63. package/templates/instruct/Instruct-Agent-AI.be.md +96 -0
  64. package/templates/instruct/Instruct-Agent-AI.fe.md +79 -0
  65. package/templates/rules/antigravity/01-evnict-kit-general-rules.md +303 -0
  66. package/templates/rules/antigravity/02-evnict-kit-security-rules.md +423 -0
  67. package/templates/rules/antigravity/03-evnict-kit-backend-conventions.md +383 -0
  68. package/templates/rules/antigravity/04-evnict-kit-frontend-conventions.md +402 -0
  69. package/templates/rules/antigravity/05-evnict-kit-project-conventions.md +228 -0
  70. package/templates/rules/claude/README.md +8 -0
  71. package/templates/rules/cursor/01-evnict-kit-general-rules.mdc +46 -0
  72. package/templates/rules/cursor/02-evnict-kit-security-rules.mdc +46 -0
  73. package/templates/rules/cursor/03-evnict-kit-backend-conventions.mdc +50 -0
  74. package/templates/rules/cursor/04-evnict-kit-frontend-conventions.mdc +43 -0
  75. package/templates/rules/cursor/05-evnict-kit-project-conventions.mdc +63 -0
  76. package/templates/rules/cursor/README.md +7 -0
  77. package/templates/skills/evnict-kit-brainstorm/SKILL.md +140 -0
  78. package/templates/skills/evnict-kit-bug-fix/SKILL.md +108 -0
  79. package/templates/skills/evnict-kit-checkpoint/SKILL.md +156 -0
  80. package/templates/skills/evnict-kit-code-review/SKILL.md +158 -0
  81. package/templates/skills/evnict-kit-coordinate/SKILL.md +274 -0
  82. package/templates/skills/evnict-kit-create-api/SKILL.md +281 -0
  83. package/templates/skills/evnict-kit-create-component/SKILL.md +263 -0
  84. package/templates/skills/evnict-kit-create-page/SKILL.md +247 -0
  85. package/templates/skills/evnict-kit-database-migration/SKILL.md +164 -0
  86. package/templates/skills/evnict-kit-doc-postmortem/SKILL.md +93 -0
  87. package/templates/skills/evnict-kit-finish-branch/SKILL.md +87 -0
  88. package/templates/skills/evnict-kit-fix-attt/SKILL.md +129 -0
  89. package/templates/skills/evnict-kit-fix-business-logic/SKILL.md +89 -0
  90. package/templates/skills/evnict-kit-git-worktrees/SKILL.md +104 -0
  91. package/templates/skills/evnict-kit-merge-checklist/SKILL.md +108 -0
  92. package/templates/skills/evnict-kit-onboard/SKILL.md +143 -0
  93. package/templates/skills/evnict-kit-prompt-standard/SKILL.md +103 -0
  94. package/templates/skills/evnict-kit-receiving-review/SKILL.md +89 -0
  95. package/templates/skills/evnict-kit-security-audit/SKILL.md +190 -0
  96. package/templates/skills/evnict-kit-spec/SKILL.md +237 -0
  97. package/templates/skills/evnict-kit-tdd/SKILL.md +413 -0
  98. package/templates/skills/evnict-kit-wiki/SKILL.md +412 -0
  99. package/templates/wiki/README.md +35 -0
  100. package/templates/wiki/config.example.yaml +17 -0
  101. package/templates/wiki/package.json +17 -0
  102. package/templates/wiki/raw/notes/.gitkeep +1 -0
  103. package/templates/wiki/scripts/ingest.js +66 -0
  104. package/templates/workflows/antigravity/evnict-kit-archive-wiki.md +100 -0
  105. package/templates/workflows/antigravity/evnict-kit-attt.md +100 -0
  106. package/templates/workflows/antigravity/evnict-kit-bug-fix.md +107 -0
  107. package/templates/workflows/antigravity/evnict-kit-feature-large.md +393 -0
  108. package/templates/workflows/antigravity/evnict-kit-feature-small.md +86 -0
  109. package/templates/workflows/antigravity/evnict-kit-handoff.md +243 -0
  110. package/templates/workflows/antigravity/evnict-kit-implement.md +247 -0
  111. package/templates/workflows/antigravity/evnict-kit-init-check.md +76 -0
  112. package/templates/workflows/antigravity/evnict-kit-init-context.md +58 -0
  113. package/templates/workflows/antigravity/evnict-kit-init-rules.md +114 -0
  114. package/templates/workflows/antigravity/evnict-kit-init-wiki.md +80 -0
  115. package/templates/workflows/antigravity/evnict-kit-plan.md +308 -0
  116. package/templates/workflows/antigravity/evnict-kit-review.md +53 -0
  117. package/templates/workflows/antigravity/evnict-kit-spec-archive.md +53 -0
  118. package/templates/workflows/antigravity/evnict-kit-wiki-archive-feature.md +164 -0
  119. package/templates/workflows/antigravity/evnict-kit-wiki-query.md +91 -0
  120. package/templates/workflows/antigravity/evnict-kit-wiki-scan-project.md +272 -0
  121. package/templates/workflows/claude/README.md +6 -0
  122. package/templates/workflows/claude/evnict-kit-archive-wiki.md +98 -0
  123. package/templates/workflows/claude/evnict-kit-attt.md +98 -0
  124. package/templates/workflows/claude/evnict-kit-bug-fix.md +105 -0
  125. package/templates/workflows/claude/evnict-kit-feature-large.md +391 -0
  126. package/templates/workflows/claude/evnict-kit-feature-small.md +84 -0
  127. package/templates/workflows/claude/evnict-kit-handoff.md +240 -0
  128. package/templates/workflows/claude/evnict-kit-implement.md +245 -0
  129. package/templates/workflows/claude/evnict-kit-init-check.md +74 -0
  130. package/templates/workflows/claude/evnict-kit-init-context.md +56 -0
  131. package/templates/workflows/claude/evnict-kit-init-rules.md +112 -0
  132. package/templates/workflows/claude/evnict-kit-init-wiki.md +78 -0
  133. package/templates/workflows/claude/evnict-kit-plan.md +305 -0
  134. package/templates/workflows/claude/evnict-kit-review.md +51 -0
  135. package/templates/workflows/claude/evnict-kit-spec-archive.md +51 -0
  136. package/templates/workflows/claude/evnict-kit-wiki-archive-feature.md +162 -0
  137. package/templates/workflows/claude/evnict-kit-wiki-query.md +89 -0
  138. package/templates/workflows/claude/evnict-kit-wiki-scan-project.md +270 -0
@@ -0,0 +1,402 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+ # Frontend Conventions — EVNICT Standard
5
+ **Activation Mode: Always On**
6
+ **Source: QĐ-TTPM Điều 8, Mục 8.6**
7
+ **Tech: Angular + PrimeNG**
8
+
9
+ > Áp dụng cho TẤT CẢ code frontend. Mọi code mới hoặc sửa đổi PHẢI tuân thủ.
10
+
11
+ ---
12
+
13
+ ## 1. NO INLINE STYLES (RF01)
14
+
15
+ ### Quy tắc
16
+ - KHÔNG sử dụng inline styles trực tiếp trong template
17
+ - Tất cả styles PHẢI đặt trong file `.scss` hoặc `.css` riêng
18
+ - Dùng CSS classes, KHÔNG dùng `[style]` binding
19
+ - Exception: dynamic styles từ business logic (VD: chart colors)
20
+
21
+ ### Code examples
22
+ ```html
23
+ <!-- ❌ SAI — Inline styles -->
24
+ <div style="color: red; font-size: 14px; margin-top: 10px">
25
+ {{ errorMessage }}
26
+ </div>
27
+ <div [style.color]="isError ? 'red' : 'green'">Status</div>
28
+
29
+ <!-- ✅ ĐÚNG — CSS class -->
30
+ <div class="error-message" [class.error]="isError" [class.success]="!isError">
31
+ {{ errorMessage }}
32
+ </div>
33
+ ```
34
+
35
+ ```scss
36
+ // ✅ Trong component.scss
37
+ .error-message {
38
+ font-size: 14px;
39
+ margin-top: 10px;
40
+
41
+ &.error { color: var(--color-error); }
42
+ &.success { color: var(--color-success); }
43
+ }
44
+ ```
45
+
46
+ ### Scan commands
47
+ ```bash
48
+ grep -rn "style=\"" --include="*.html" src/
49
+ grep -rn "\[style\." --include="*.html" src/
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 2. COMPONENT REUSE (RF02)
55
+
56
+ ### Quy tắc
57
+ - TRƯỚC KHI tạo component mới → kiểm tra đã có component tương tự chưa
58
+ - Tìm trong: `shared/components/`, PrimeNG library, project components
59
+ - Nếu đã có → reuse hoặc extend
60
+ - Component mới PHẢI đặt trong `shared/` nếu dùng ≥ 2 nơi
61
+
62
+ ### Component categories
63
+ ```
64
+ src/app/
65
+ ├── shared/
66
+ │ ├── components/ ← Reusable components (dùng ≥ 2 nơi)
67
+ │ │ ├── data-table/ ← Generic table wrapper
68
+ │ │ ├── form-field/ ← Form field với validation
69
+ │ │ ├── file-upload/ ← Upload component
70
+ │ │ └── confirm-dialog/
71
+ │ ├── pipes/ ← Shared pipes
72
+ │ ├── directives/ ← Shared directives
73
+ │ └── services/ ← Shared services
74
+ ├── features/
75
+ │ └── customer/
76
+ │ ├── components/ ← Feature-specific components
77
+ │ ├── pages/ ← Routed pages
78
+ │ └── services/ ← Feature services
79
+ ```
80
+
81
+ ### PrimeNG usage
82
+ ```typescript
83
+ // ✅ ĐÚNG — Dùng PrimeNG components trước khi tự viết
84
+ // Table → p-table
85
+ // Dialog → p-dialog
86
+ // Form elements → p-inputText, p-dropdown, p-calendar
87
+ // Toast → p-toast (qua MessageService)
88
+ // Confirm → p-confirmDialog (qua ConfirmationService)
89
+
90
+ // ❌ SAI — Tự viết component khi PrimeNG đã có
91
+ // Custom table → Dùng p-table
92
+ // Custom dropdown → Dùng p-dropdown
93
+ // Custom date picker → Dùng p-calendar
94
+ ```
95
+
96
+ ---
97
+
98
+ ## 3. NO HARDCODED TEXT / I18N (RF03)
99
+
100
+ ### Quy tắc
101
+ - KHÔNG hardcode text hiển thị trong template hoặc component
102
+ - Tất cả text PHẢI qua i18n (ngx-translate hoặc Angular i18n)
103
+ - Labels, messages, tooltips, placeholders → đều qua translate
104
+
105
+ ### Code examples
106
+ ```html
107
+ <!-- ❌ SAI — Hardcoded text -->
108
+ <button>Tạo mới</button>
109
+ <label>Tên khách hàng:</label>
110
+ <p-message severity="error" text="Không tìm thấy dữ liệu"></p-message>
111
+
112
+ <!-- ✅ ĐÚNG — i18n -->
113
+ <button>{{ 'button.create' | translate }}</button>
114
+ <label>{{ 'customer.name' | translate }}:</label>
115
+ <p-message severity="error" [text]="'message.notFound' | translate"></p-message>
116
+ ```
117
+
118
+ ```json
119
+ // vi.json
120
+ {
121
+ "button": {
122
+ "create": "Tạo mới",
123
+ "save": "Lưu",
124
+ "cancel": "Hủy",
125
+ "delete": "Xóa",
126
+ "search": "Tìm kiếm"
127
+ },
128
+ "customer": {
129
+ "name": "Tên khách hàng",
130
+ "phone": "Số điện thoại"
131
+ },
132
+ "message": {
133
+ "notFound": "Không tìm thấy dữ liệu",
134
+ "saveSuccess": "Lưu thành công",
135
+ "confirmDelete": "Bạn có chắc chắn muốn xóa?"
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### Ngoại lệ
141
+ - Technical strings (CSS class names, HTML attributes)
142
+ - Enum labels → nên qua i18n nhưng có thể hardcode trong các dict objects
143
+
144
+ ---
145
+
146
+ ## 4. ACCESSIBILITY / A11Y (RF04)
147
+
148
+ ### Quy tắc
149
+ - Mọi `<img>` PHẢI có `alt` attribute
150
+ - Mọi form field PHẢI có `<label>` hoặc `aria-label`
151
+ - Mọi interactive element PHẢI có `tabindex` hợp lý
152
+ - Color contrast ratio ≥ 4.5:1 cho text
153
+
154
+ ### Code examples
155
+ ```html
156
+ <!-- ❌ SAI — Thiếu a11y -->
157
+ <img src="logo.png">
158
+ <input type="text" placeholder="Search">
159
+ <div (click)="doSomething()">Click me</div>
160
+
161
+ <!-- ✅ ĐÚNG — a11y đầy đủ -->
162
+ <img src="logo.png" alt="Logo EVNICT">
163
+ <label for="search">{{ 'label.search' | translate }}</label>
164
+ <input type="text" id="search" [placeholder]="'placeholder.search' | translate" aria-label="Search">
165
+ <button (click)="doSomething()" tabindex="0">
166
+ {{ 'button.action' | translate }}
167
+ </button>
168
+ ```
169
+
170
+ ### Scan commands
171
+ ```bash
172
+ grep -rn "<img " --include="*.html" src/ | grep -v "alt="
173
+ grep -rn "<input " --include="*.html" src/ | grep -v "aria-label\|id="
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 5. NO DIRECT DOM MANIPULATION (RF05)
179
+
180
+ ### Quy tắc
181
+ - KHÔNG dùng `document.getElementById()`, `document.querySelector()`
182
+ - KHÔNG dùng `jQuery` hoặc truy cập DOM trực tiếp
183
+ - Dùng Angular bindings, `@ViewChild`, hoặc `Renderer2`
184
+ - Exception: third-party library integration (VD: chart.js) → dùng `@ViewChild`
185
+
186
+ ### Code examples
187
+ ```typescript
188
+ // ❌ SAI — Direct DOM manipulation
189
+ ngAfterViewInit() {
190
+ document.getElementById('myInput').focus();
191
+ document.querySelector('.container').classList.add('active');
192
+ const el = document.getElementsByClassName('item');
193
+ }
194
+
195
+ // ✅ ĐÚNG — Angular way
196
+ @ViewChild('myInput') myInput: ElementRef;
197
+
198
+ ngAfterViewInit() {
199
+ this.myInput.nativeElement.focus();
200
+ }
201
+
202
+ // ✅ ĐÚNG — Renderer2
203
+ constructor(private renderer: Renderer2) {}
204
+
205
+ setActive(el: ElementRef) {
206
+ this.renderer.addClass(el.nativeElement, 'active');
207
+ }
208
+
209
+ // ✅ ĐÚNG — Template bindings
210
+ // <div [class.active]="isActive"></div>
211
+ // <input #myInput (keyup)="onKeyUp()">
212
+ ```
213
+
214
+ ### Scan commands
215
+ ```bash
216
+ grep -rn "document\.getElementById\|document\.querySelector\|document\.getElement" --include="*.ts" src/
217
+ grep -rn "jQuery\|\\$(" --include="*.ts" src/
218
+ ```
219
+
220
+ ---
221
+
222
+ ## 6. RESPONSIVE DESIGN (RF06)
223
+
224
+ ### Quy tắc
225
+ - Tất cả pages PHẢI responsive cho: Desktop (≥1200px), Tablet (768-1199px), Mobile (≤767px)
226
+ - Dùng PrimeNG Grid system (p-grid, p-col) hoặc CSS Grid/Flexbox
227
+ - Test responsive trước khi commit
228
+ - Text KHÔNG bị cắt, table PHẢI scrollable trên mobile
229
+
230
+ ### Code examples
231
+ ```html
232
+ <!-- ✅ ĐÚNG — PrimeNG responsive grid -->
233
+ <div class="grid">
234
+ <div class="col-12 md:col-6 lg:col-4">
235
+ <!-- Card 1 -->
236
+ </div>
237
+ <div class="col-12 md:col-6 lg:col-4">
238
+ <!-- Card 2 -->
239
+ </div>
240
+ <div class="col-12 md:col-12 lg:col-4">
241
+ <!-- Card 3 -->
242
+ </div>
243
+ </div>
244
+
245
+ <!-- ✅ Table responsive -->
246
+ <div class="table-responsive">
247
+ <p-table [value]="data" [scrollable]="true" scrollHeight="400px"
248
+ [responsive]="true" responsiveLayout="scroll">
249
+ <!-- columns -->
250
+ </p-table>
251
+ </div>
252
+ ```
253
+
254
+ ```scss
255
+ // ✅ SCSS responsive
256
+ .page-container {
257
+ padding: 1rem;
258
+
259
+ @media (max-width: 768px) {
260
+ padding: 0.5rem;
261
+
262
+ .action-buttons {
263
+ flex-direction: column;
264
+ gap: 0.5rem;
265
+ }
266
+ }
267
+ }
268
+ ```
269
+
270
+ ---
271
+
272
+ ## 7. ANGULAR CONVENTIONS
273
+
274
+ ### File naming
275
+ | Loại | Pattern | Ví dụ |
276
+ |------|---------|-------|
277
+ | Component | `{name}.component.ts` | `customer-list.component.ts` |
278
+ | Service | `{name}.service.ts` | `customer.service.ts` |
279
+ | Module | `{name}.module.ts` | `customer.module.ts` |
280
+ | Pipe | `{name}.pipe.ts` | `date-format.pipe.ts` |
281
+ | Directive | `{name}.directive.ts` | `auto-focus.directive.ts` |
282
+ | Guard | `{name}.guard.ts` | `auth.guard.ts` |
283
+ | Interceptor | `{name}.interceptor.ts` | `auth.interceptor.ts` |
284
+ | Model/Interface | `{name}.model.ts` | `customer.model.ts` |
285
+
286
+ ### Component structure
287
+ ```typescript
288
+ // ✅ ĐÚNG — Component tiêu chuẩn
289
+ @Component({
290
+ selector: 'app-customer-list',
291
+ templateUrl: './customer-list.component.html',
292
+ styleUrls: ['./customer-list.component.scss']
293
+ })
294
+ export class CustomerListComponent implements OnInit, OnDestroy {
295
+ // 1. Decorators
296
+ @ViewChild('dt') table: Table;
297
+
298
+ // 2. Public properties (used in template)
299
+ customers: CustomerDTO[] = [];
300
+ loading = false;
301
+ totalRecords = 0;
302
+
303
+ // 3. Private properties
304
+ private destroy$ = new Subject<void>();
305
+
306
+ // 4. Constructor (DI)
307
+ constructor(
308
+ private customerService: CustomerService,
309
+ private messageService: MessageService
310
+ ) {}
311
+
312
+ // 5. Lifecycle hooks
313
+ ngOnInit(): void {
314
+ this.loadData();
315
+ }
316
+
317
+ ngOnDestroy(): void {
318
+ this.destroy$.next();
319
+ this.destroy$.complete();
320
+ }
321
+
322
+ // 6. Public methods (used in template)
323
+ loadData(): void { ... }
324
+ onCreate(): void { ... }
325
+
326
+ // 7. Private methods
327
+ private handleError(err: any): void { ... }
328
+ }
329
+ ```
330
+
331
+ ### Service pattern
332
+ ```typescript
333
+ // ✅ ĐÚNG — Service tiêu chuẩn
334
+ @Injectable({ providedIn: 'root' })
335
+ export class CustomerService {
336
+ private baseUrl = `${environment.apiUrl}/api/customers`;
337
+
338
+ constructor(private http: HttpClient) {}
339
+
340
+ search(keyword: string, page: number, size: number): Observable<ResponseData> {
341
+ const params = new HttpParams()
342
+ .set('keyword', keyword)
343
+ .set('page', page.toString())
344
+ .set('size', size.toString());
345
+ return this.http.get<ResponseData>(this.baseUrl, { params });
346
+ }
347
+
348
+ getById(id: number): Observable<ResponseData> {
349
+ return this.http.get<ResponseData>(`${this.baseUrl}/${id}`);
350
+ }
351
+
352
+ create(dto: CustomerDTO): Observable<ResponseData> {
353
+ return this.http.post<ResponseData>(this.baseUrl, dto);
354
+ }
355
+
356
+ update(id: number, dto: CustomerDTO): Observable<ResponseData> {
357
+ return this.http.put<ResponseData>(`${this.baseUrl}/${id}`, dto);
358
+ }
359
+
360
+ delete(id: number): Observable<ResponseData> {
361
+ return this.http.delete<ResponseData>(`${this.baseUrl}/${id}`);
362
+ }
363
+ }
364
+ ```
365
+
366
+ ### RxJS — Memory leak prevention
367
+ ```typescript
368
+ // ❌ SAI — Không unsubscribe → memory leak
369
+ ngOnInit() {
370
+ this.service.getData().subscribe(data => this.data = data);
371
+ }
372
+
373
+ // ✅ ĐÚNG — takeUntil pattern
374
+ private destroy$ = new Subject<void>();
375
+
376
+ ngOnInit() {
377
+ this.service.getData()
378
+ .pipe(takeUntil(this.destroy$))
379
+ .subscribe(data => this.data = data);
380
+ }
381
+
382
+ ngOnDestroy() {
383
+ this.destroy$.next();
384
+ this.destroy$.complete();
385
+ }
386
+
387
+ // ✅ ĐÚNG — async pipe (tự unsubscribe)
388
+ // component.ts
389
+ data$ = this.service.getData();
390
+ // template
391
+ <div *ngIf="data$ | async as data">{{ data.name }}</div>
392
+ ```
393
+
394
+ ### Scan commands
395
+ ```bash
396
+ # Tìm subscribe không unsubscribe
397
+ grep -rn "\.subscribe(" --include="*.ts" src/ | grep -v "takeUntil\|async\|take(1)\|first()"
398
+ # Tìm inline styles
399
+ grep -rn "style=\"" --include="*.html" src/
400
+ # Tìm document access
401
+ grep -rn "document\." --include="*.ts" src/
402
+ ```
@@ -0,0 +1,228 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+ # Project Conventions — EVNICT Standard
5
+ **Activation Mode: Always On**
6
+ **Source: QĐ-TTPM Phụ lục IV — Hướng dẫn thiết lập ngữ cảnh**
7
+
8
+ > **⚠️ FILE NÀY CẦN ĐƯỢC KHỞI TẠO BỞI AI AGENT**
9
+ > Chạy `/evnict-kit:init-rules` → Agent đọc codebase → tự động điền nội dung.
10
+ > Các section bên dưới chứa placeholder — Agent sẽ thay thế bằng conventions thực tế của dự án.
11
+
12
+ ---
13
+
14
+ ## RP01 — NAMING CONVENTION
15
+
16
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định naming conventions.
17
+
18
+ ### Khi khởi tạo, Agent sẽ điền:
19
+ - Package/namespace naming pattern
20
+ - Class naming pattern (Controller, Service, Repository, DTO, Entity)
21
+ - Method naming pattern (CRUD, search, business operations)
22
+ - Variable naming pattern (fields, locals, constants)
23
+ - File naming pattern
24
+ - Database table/column naming pattern
25
+ - API path naming pattern
26
+
27
+ ### Format mẫu (Agent sẽ điền theo dự án thực tế):
28
+ ```
29
+ Package: com.evn.{project}.{module}
30
+ Class: {Module}{Type}.java (VD: CustomerService.java)
31
+ Method: camelCase, prefix: find/get/create/update/delete
32
+ Variable: camelCase, descriptive
33
+ Constant: UPPER_SNAKE_CASE
34
+ Table: UPPER_SNAKE_CASE (VD: CUSTOMER, DON_VI)
35
+ Column: UPPER_SNAKE_CASE (VD: CREATED_DATE, DON_VI_ID)
36
+ API: /api/{module}/{action} (VD: /api/customers/search)
37
+ ```
38
+
39
+ ---
40
+
41
+ ## RP02 — ARCHITECTURE PATTERN
42
+
43
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định kiến trúc.
44
+
45
+ ### Khi khởi tạo, Agent sẽ điền:
46
+ - Overall architecture (MVC, Clean Architecture, Hexagonal...)
47
+ - Layer structure (Controller → Service → Repository)
48
+ - Module organization (by feature, by layer, hybrid)
49
+ - Dependency direction rules
50
+ - Cross-cutting concerns (logging, auth, exception handling)
51
+
52
+ ### Format mẫu:
53
+ ```
54
+ Architecture: Layered MVC
55
+ Layers:
56
+ 1. Controller — HTTP handling, input validation
57
+ 2. Service — Business logic, transaction management
58
+ 3. Repository — Data access (JOOQ/JPA)
59
+ 4. DTO/Entity — Data transfer / persistence
60
+
61
+ Module Structure:
62
+ src/main/java/com/evn/{project}/
63
+ ├── config/ ← Application configuration
64
+ ├── common/ ← Shared utilities, base classes
65
+ ├── security/ ← Auth, JWT, filters
66
+ └── {module}/ ← Feature modules
67
+ ├── controller/
68
+ ├── service/
69
+ ├── repository/
70
+ └── dto/
71
+ ```
72
+
73
+ ---
74
+
75
+ ## RP03 — CODING CONVENTION
76
+
77
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định coding style.
78
+
79
+ ### Khi khởi tạo, Agent sẽ điền:
80
+ - Indentation (tabs vs spaces, size)
81
+ - Import ordering
82
+ - Method ordering within class
83
+ - Comment style
84
+ - Exception handling pattern
85
+ - Logging convention
86
+ - Null handling (Optional, null checks, annotations)
87
+
88
+ ### Format mẫu:
89
+ ```
90
+ Indentation: 4 spaces (Java), 2 spaces (TypeScript/HTML/SCSS)
91
+ Max line length: 120 characters
92
+ Import order: java.*, javax.*, org.*, com.*, static
93
+ Method order: public → protected → private
94
+ Logging: SLF4J with Lombok @Slf4j
95
+ Null: @Nullable/@NonNull annotations, Optional for return types
96
+ ```
97
+
98
+ ---
99
+
100
+ ## RP04 — API CONVENTION
101
+
102
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định API patterns.
103
+
104
+ ### Khi khởi tạo, Agent sẽ điền:
105
+ - Base URL pattern
106
+ - HTTP method usage (GET/POST/PUT/DELETE)
107
+ - Request/Response format (ResponseData wrapper)
108
+ - Pagination pattern
109
+ - Error response format
110
+ - Authentication header format
111
+ - API versioning (if any)
112
+
113
+ ### Format mẫu:
114
+ ```
115
+ Base URL: /api/{module}
116
+ Response: ResponseData { status, message, data }
117
+ Pagination: ?page=0&size=20&sort=name
118
+ Auth Header: Authorization: Bearer {token}
119
+ Error: ResponseData { status: 1, message: "...", data: null }
120
+
121
+ Endpoints:
122
+ GET /api/{module} → List (paginated)
123
+ GET /api/{module}/{id} → Get by ID
124
+ POST /api/{module} → Create
125
+ PUT /api/{module}/{id} → Update
126
+ DELETE /api/{module}/{id} → Delete
127
+ POST /api/{module}/search → Complex search
128
+ ```
129
+
130
+ ---
131
+
132
+ ## RP05 — DATABASE CONVENTION
133
+
134
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định DB patterns.
135
+
136
+ ### Khi khởi tạo, Agent sẽ điền:
137
+ - Database type & version
138
+ - Schema structure (single/multi schema)
139
+ - Table naming convention
140
+ - Column naming convention
141
+ - Primary key pattern (sequence, UUID, identity)
142
+ - Foreign key naming
143
+ - Index naming
144
+ - Audit columns (created_by, created_date, etc.)
145
+ - Soft delete pattern (if used)
146
+
147
+ ### Format mẫu:
148
+ ```
149
+ Database: Oracle 19c
150
+ Schemas: EVNTMS (system), {PROJECT} (business)
151
+ Table: UPPER_SNAKE (VD: CUSTOMER, HD_DIEN)
152
+ Column: UPPER_SNAKE (VD: TEN_KH, MA_DON_VI)
153
+ PK: ID (NUMBER, sequence {TABLE}_SEQ)
154
+ FK: {TABLE}_{REF_TABLE}_FK
155
+ Index: IX_{TABLE}_{COLUMNS}
156
+ Audit: CREATED_BY, CREATED_DATE, UPDATED_BY, UPDATED_DATE
157
+ Soft delete: IS_DELETED (NUMBER(1)) hoặc STATUS = 'DELETED'
158
+ ```
159
+
160
+ ---
161
+
162
+ ## RP06 — COMPONENT CONVENTION (Frontend)
163
+
164
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định component patterns.
165
+
166
+ ### Khi khởi tạo, Agent sẽ điền:
167
+ - Component file structure
168
+ - Shared vs feature-specific components
169
+ - Naming convention (selector prefix, file names)
170
+ - State management pattern
171
+ - UI library usage (PrimeNG components)
172
+ - Form handling pattern (Reactive Forms vs Template-driven)
173
+ - Routing pattern
174
+
175
+ ### Format mẫu:
176
+ ```
177
+ Selector prefix: app-
178
+ File structure: {name}.component.ts/html/scss
179
+ Shared path: src/app/shared/components/
180
+ Feature path: src/app/features/{module}/components/
181
+ State: Service + BehaviorSubject (no NgRx)
182
+ UI Library: PrimeNG 16+
183
+ Forms: Reactive Forms (FormBuilder)
184
+ Routing: Lazy-loaded feature modules
185
+ ```
186
+
187
+ ---
188
+
189
+ ## RP07 — INTEGRATION MAP
190
+
191
+ > ⚠️ **CHƯA ĐƯỢC KHỞI TẠO** — Agent cần scan codebase để xác định integrations.
192
+
193
+ ### Khi khởi tạo, Agent sẽ điền:
194
+ - External services integrated (SSO, MinIO, CMIS, etc.)
195
+ - Internal service dependencies
196
+ - Message queues / event systems
197
+ - Caching strategy
198
+ - File storage
199
+ - Email/notification services
200
+
201
+ ### Format mẫu:
202
+ ```
203
+ Authentication: EVN SSO → JWT (RS256)
204
+ File Storage: MinIO (S3-compatible)
205
+ Document: CMIS (Content Management)
206
+ Cache: Redis (session) / Caffeine (local)
207
+ Email: SMTP server
208
+ Notification: WebSocket (SockJS + STOMP)
209
+ CI/CD: Azure DevOps Pipelines
210
+ Container: Docker + Kubernetes
211
+ ```
212
+
213
+ ---
214
+
215
+ ## HƯỚNG DẪN KHỞI TẠO
216
+
217
+ Khi Agent nhận `/evnict-kit:init-rules`:
218
+
219
+ 1. **Scan codebase** — `tree -L 3`, đọc các file cốt lõi (pom.xml, package.json, config files)
220
+ 2. **Phân tích patterns** — Tìm patterns từ code hiện có
221
+ 3. **Điền từng section** — Thay thế "⚠️ CHƯA ĐƯỢC KHỞI TẠO" bằng nội dung thực tế
222
+ 4. **Thêm code examples** — Lấy từ code thực tế của dự án (KHÔNG code mẫu generic)
223
+ 5. **Validate** — Đảm bảo conventions phù hợp với code hiện có
224
+
225
+ **SAU KHI khởi tạo:**
226
+ - Xóa tất cả placeholder "⚠️ CHƯA ĐƯỢC KHỞI TẠO"
227
+ - Đổi mỗi section header thành `✅ ĐÃ KHỞI TẠO — {date}`
228
+ - Commit: `chore: initialize project conventions RP01-RP07`