@sun-asterisk/sungen 2.6.15 → 2.7.0-beta.0

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 (65) hide show
  1. package/dist/cli/index.js +3 -1
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/exporters/feature-parser.d.ts +9 -2
  4. package/dist/exporters/feature-parser.d.ts.map +1 -1
  5. package/dist/exporters/feature-parser.js +12 -4
  6. package/dist/exporters/feature-parser.js.map +1 -1
  7. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  8. package/dist/orchestrator/ai-rules-updater.js +10 -0
  9. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  10. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +13 -12
  11. package/dist/orchestrator/templates/ai-instructions/claude-config.md +1 -1
  12. package/dist/orchestrator/templates/ai-instructions/claude-skill-delivery.md +1 -1
  13. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +14 -0
  14. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +371 -324
  15. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +268 -90
  16. package/dist/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +23 -49
  17. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +203 -0
  18. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +179 -0
  19. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +233 -0
  20. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +226 -0
  21. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +177 -0
  22. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +69 -240
  23. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +13 -12
  24. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +1 -1
  25. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +1 -1
  26. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -21
  27. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +371 -324
  28. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +262 -102
  29. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +23 -49
  30. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +203 -0
  31. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +179 -0
  32. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +233 -0
  33. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +226 -0
  34. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +177 -0
  35. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +69 -240
  36. package/package.json +9 -1
  37. package/src/cli/index.ts +4 -1
  38. package/src/exporters/feature-parser.ts +12 -4
  39. package/src/orchestrator/ai-rules-updater.ts +10 -0
  40. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +13 -12
  41. package/src/orchestrator/templates/ai-instructions/claude-config.md +1 -1
  42. package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +1 -1
  43. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +14 -0
  44. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +371 -324
  45. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +268 -90
  46. package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +23 -49
  47. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +203 -0
  48. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +179 -0
  49. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +233 -0
  50. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +226 -0
  51. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +177 -0
  52. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +69 -240
  53. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +13 -12
  54. package/src/orchestrator/templates/ai-instructions/copilot-config.md +1 -1
  55. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +1 -1
  56. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -21
  57. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +371 -324
  58. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +262 -102
  59. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +23 -49
  60. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +203 -0
  61. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +179 -0
  62. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +233 -0
  63. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +226 -0
  64. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +177 -0
  65. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +69 -240
@@ -0,0 +1,203 @@
1
+ # GROUP A: DATA ENTRY
2
+
3
+ > The user feeds data into the system — field by field, file by file, or in bulk.
4
+
5
+ Patterns: 1. Form & Inputs · 2. File Upload · 3. Import / Export
6
+ See `SKILL.md` for the 4 Viewpoints, Shared Checks, and Security Tag Rules.
7
+
8
+ ---
9
+
10
+ ## 1. Form & Inputs
11
+
12
+ > **Base pattern.** The field-level validation here is inherited by Create (4), Update (5), Login (15), Register (16), Password (17). Generate this as a standalone section only for a plain form with no more-specific role (settings, profile, contact) — see *Pattern selection* in `SKILL.md`.
13
+
14
+ **Apply when**: the screen has at least 1 input field and 1 submit button that sends data to the server, and no more-specific pattern (4/5/15/16/17) applies.
15
+
16
+ **Shared checks applied**: XSS/Injection
17
+
18
+ ---
19
+
20
+ ### Tier 1 — @high
21
+
22
+ **[VP-LOGIC] Business behavior**
23
+
24
+ - All required fields empty → Submit button is disabled, no request is sent on click
25
+ - All required fields filled validly → Submit button becomes enabled and clickable
26
+ - Submit the form with valid data → success feedback appears (toast/message/redirect), data is saved to the system
27
+ - Submit the form → server returns an error (5xx, business error) → error message appears, all entered data is preserved on the form
28
+ - User clicks submit twice in a row before the response arrives → only 1 request is sent, no duplicate record is created
29
+ - Field A value changes → Field B updates its options accordingly immediately (field dependency; override if the spec uses field visibility: Field B is shown/hidden instead of changing options)
30
+
31
+ **[VP-VAL] Input validation**
32
+
33
+ - Submit while a required field is empty (applies if Submit is not disabled — Pattern B) → error message appears right at that field, not only a generic toast
34
+ - Enter beyond max length → field accepts no more characters (HTML maxlength default; override if the spec uses server-side: input accepted but rejected on submit with an error stating the limit)
35
+ - Enter the wrong format (email, phone, date…) → error message appears at the field, field is highlighted (text comes from {{format_error}} in test-data.yaml)
36
+ - User fixes the field after an error → the error clears immediately once the value becomes valid (real-time clear)
37
+ - Input containing only whitespace → treated as empty, submit shows the required error (override if the spec requires auto-trim and accept)
38
+
39
+ **[VP-SEC]** → Apply Shared Check: XSS/Injection
40
+
41
+ ---
42
+
43
+ ### Tier 2 — @normal + @low
44
+
45
+ **[VP-UI] Interface states**
46
+
47
+ - [@normal] Required fields have a visual indicator (asterisk, color, "Required" label)
48
+ - [@normal] Disabled fields: visually dimmed, cursor not-allowed, accept no input
49
+ - [@normal] Focused field: border/outline highlight is clear, distinguishable from an unfocused field
50
+ - [@low] Tab order: the Tab key moves focus in a logical order, top to bottom, left to right
51
+ - [@low] Placeholder text: shows the correct hint text per spec, disappears once the user starts typing
52
+ - [@low] Character counter (if the spec has one): shows the remaining character count, changes color near or at the limit
53
+
54
+ **[VP-VAL] Boundary values**
55
+
56
+ 4 TCs per range (min-1, min, max, max+1). Default tag = @normal (Tier 2).
57
+ **Override to @high (Tier 1)** when the field is on a critical business rule or the spec uses inclusive operators (`<=`, `>=`).
58
+
59
+ - [@normal] Exactly the min value → accepted, no error
60
+ - [@normal] Exactly the max value → accepted, no error
61
+ - [@normal] Min - 1 unit → rejected, appropriate error
62
+ - [@normal] Max + 1 unit → rejected, appropriate error
63
+
64
+ ---
65
+
66
+ ### ⚡ Cross-pattern interactions
67
+
68
+ - **+ Modal/Dialog**: Form inside a modal → on submit success the modal closes, background data updates immediately without a full-page reload
69
+ - **+ Create/Add**: Apply this entire checklist. Add: the form opens as a blank slate, no data cached from a previous submit or a previous open
70
+ - **+ Update/Edit**: Apply this entire checklist. Add: the form pre-fills the correct current data from the DB
71
+ - **+ Notification**: Submit success → toast shows {{success_message}} from test-data.yaml, auto-dismisses after a few seconds
72
+
73
+ ---
74
+
75
+ ## 2. File Upload
76
+
77
+ **Apply when**: the screen has a component letting the user upload a file (image, PDF, video, document…). It can be standalone or a field within a larger form.
78
+
79
+ **Shared checks applied**: XSS/Injection (via file name)
80
+
81
+ ---
82
+
83
+ ### Tier 1 — @high
84
+
85
+ **[VP-LOGIC] Upload behavior**
86
+
87
+ - Upload a file of the right type and size → upload succeeds, file name/thumbnail/preview appears in the UI
88
+ - Upload in progress → progress indicator appears, the form's submit button is disabled until the upload completes
89
+ - Upload fails (network error, server timeout) → error message states the reason clearly, the user can retry
90
+ - User removes an uploaded file → the file is removed from the form and deleted from the server immediately (override if the spec uses lazy delete: only deleted on form submit)
91
+ - Multiple files (if the spec allows) → each file has its own upload progress and status
92
+
93
+ **[VP-VAL] File constraints**
94
+
95
+ - Upload a file with a disallowed extension (not in the whitelist) → rejected immediately, error lists the allowed types
96
+ - Upload a file exceeding the size limit → rejected, error states the limit and the actual size of the selected file
97
+ - Submit the form without uploading a file (field required) → "file required" error appears, the form does not submit
98
+ - Upload an empty file (0 bytes) → rejected with an appropriate error
99
+
100
+ **[VP-SEC]**
101
+
102
+ - Upload a file with a valid extension but whose real MIME type is executable (file-type spoofing) → server validates the real MIME type and rejects it
103
+ - File name containing a path-traversal string (`../../etc/passwd`, `../config`) → file name is sanitized, not executed, no path is exposed
104
+ - Upload without authentication → 401/403, the file is not stored on the server
105
+
106
+ ---
107
+
108
+ ### Tier 2 — @normal + @low
109
+
110
+ **[VP-UI] Interface states**
111
+
112
+ - [@normal] Drop zone or "Choose file" button is clearly visible and easy to recognize
113
+ - [@normal] The list of accepted file types and the size limit appear in the UI (helper text or tooltip)
114
+ - [@normal] During upload: progress bar or percentage is shown, a cancel button is available
115
+ - [@normal] Upload success: thumbnail (image) or file icon + file name + size are clearly shown
116
+ - [@normal] Multiple upload with a limit: a "2/5 files" counter shows, the upload button hides/disables when the limit is reached
117
+ - [@low] Drag & drop: dragging a file over the zone → drop zone highlights, upload starts automatically on drop
118
+
119
+ **[VP-VAL] Edge cases**
120
+
121
+ - [@normal] Upload a file with the same name as an existing one → rejected, error "File already exists" (override if the spec defines overwrite or auto-rename to file(1))
122
+ - [@normal] File name with special characters or Unicode (accented Vietnamese) → upload succeeds, the name is displayed correctly
123
+
124
+ ---
125
+
126
+ ### ⚡ Cross-pattern interactions
127
+
128
+ - **+ Form & Inputs**: Upload is a field in the form → the form cannot submit if the upload is incomplete or failed
129
+ - **+ Create/Add**: The created record includes the correct file reference, the file is accessible after reopening the record
130
+ - **+ Update/Edit**: The current file is shown → the user can replace it (new upload overwrites the old) or remove it separately
131
+ - **+ Modal/Dialog**: Upload inside a modal → the modal does not close while uploading, progress is not lost
132
+ - **+ Notification**: Upload success/fail → toast shows the correct message and the correct type (success/error)
133
+
134
+ ---
135
+
136
+ ## 3. Import / Export
137
+
138
+ **Apply when**: the screen has a function to bulk-import data from a file (CSV, Excel) or export the current data to a file.
139
+
140
+ **Shared checks applied**: Loading State
141
+
142
+ ---
143
+
144
+ ### Tier 1 — @high
145
+
146
+ **[VP-LOGIC] Import behavior**
147
+
148
+ *No preview:*
149
+ - Upload a valid file (correct format, all required columns, valid data) → import succeeds, the number of imported records is clearly shown
150
+ - After import → new data appears in the list/table immediately without a reload (override if the spec requires a manual reload)
151
+ - Large file (many records, async processing) → UI shows "processing", the user gets a notification when done
152
+
153
+ *With preview:*
154
+ - Upload a file → a preview table appears with the parsed data, the user sees it before confirming
155
+ - Preview shows inline errors for each invalid row: highlights the row, states the column and the reason
156
+ - User confirms after viewing the preview → valid records are imported, invalid rows are skipped with a row-level error summary (override if the spec requires rejecting all when any row is invalid)
157
+ - User cancels at the preview step → no record is created, the system returns to the state before the upload
158
+
159
+ *Export:*
160
+ - User clicks Export → the file download starts automatically, format CSV (override if the spec uses XLSX or another format)
161
+ - Export with an active filter → the file contains only the filtered data, not the entire dataset
162
+ - Export success → the file downloads without navigating the user away from the current page
163
+
164
+ **[VP-VAL] File & data validation**
165
+
166
+ - Import a file in the wrong format (not CSV/Excel, wrong delimiter) → rejected, error states the required format with an example
167
+ - Import a file missing required columns → rejected, error lists the missing column names
168
+ - Import a file with a wrong column header name → rejected, error lists the required column names (override if the spec allows partial import ignoring unknown columns)
169
+ - Import records with a key that already exists → skip that row, count it under "Y skipped" in the result summary (override if the spec requires overwrite or rejecting the whole file)
170
+ - Import a file with invalid data in cells (wrong type, over max length) → row-level errors state the row number, column, and reason
171
+
172
+ **[VP-SEC]**
173
+
174
+ - Import an Excel file containing formula injection (`=HYPERLINK(...)`, `=CMD(...)` in a cell) → the cell value is sanitized to plain text, not executed
175
+ - Export another user's/tenant's data via IDOR (changing a param in the URL/request) → blocked, 403 Forbidden
176
+
177
+ ---
178
+
179
+ ### Tier 2 — @normal + @low
180
+
181
+ **[VP-UI] Interface states**
182
+
183
+ - [@normal] Import: accepted file types, size limit, and a "download template" link appear clearly before the user picks a file
184
+ - [@normal] Import processing: progress/spinner shows, the Import button is disabled to prevent a double submit
185
+ - [@normal] Import result summary: "X records imported, Y skipped, Z failed" is clearly shown, with a downloadable error report if the spec requires
186
+ - [@normal] Export: the Export button switches to a loading state while generating the file
187
+ - [@low] Template download: the template file has the correct column headers and at least 1 row of example data
188
+
189
+ **[VP-VAL] Edge cases**
190
+
191
+ - [@normal] Import an empty file (header row only, no data) → warning "No data to import", no crash, no record created
192
+ - [@normal] Export when data is empty → the file still downloads, with the header row only and no data rows (override if the spec wants to block the download and show a "No data to export" toast)
193
+ - [@normal] Export a large file (10k+ records) → the file generates within the allowed timeout, no 504 error
194
+ - [@normal] Export encoding is correct: opening the CSV in Excel shows no broken Vietnamese font (UTF-8 BOM)
195
+
196
+ ---
197
+
198
+ ### ⚡ Cross-pattern interactions
199
+
200
+ - **+ Data Table**: After import → the table auto-refreshes to show new records; Export takes exactly the data currently shown in the table
201
+ - **+ Filter**: Export with an active filter → the exported file count matches the number of records shown in the UI
202
+ - **+ Pagination**: After import → the total count in the pagination updates correctly
203
+ - **+ Notification**: Import/Export complete (especially async) → toast or notification shows the result summary
@@ -0,0 +1,179 @@
1
+ # GROUP B: DATA OPERATIONS
2
+
3
+ > The user creates, edits, or deletes a specific record in the system.
4
+
5
+ Patterns: 4. Create / Add · 5. Update / Edit · 6. Delete
6
+ See `SKILL.md` for the 4 Viewpoints, Shared Checks, and Security Tag Rules.
7
+
8
+ ---
9
+
10
+ ## 4. Create / Add
11
+
12
+ **Apply when**: the screen has a function to create a new record (an "Add", "Create", "New" button, or a link to a create form).
13
+
14
+ **Inherits**: Form & Inputs — field-level validation (required, format, maxlength, whitespace, real-time error clear). Generate those once here; this pattern adds the create-specific rules below.
15
+
16
+ **Shared checks applied**: XSS/Injection
17
+
18
+ ---
19
+
20
+ ### Tier 1 — @high
21
+
22
+ **[VP-LOGIC] Create behavior**
23
+
24
+ - Open the create form → all fields are empty (blank slate), no data cached from a previous open or a previous submit
25
+ - Submit the form with valid data → the record is created successfully, success feedback appears (toast and/or redirect), no error on the form
26
+ - The new record appears in the correct position in the list per the current sort rule (usually newest first)
27
+ - Submit success → toast shows {{success_message}} from test-data.yaml, auto-dismisses after a few seconds
28
+ - Cancel / navigate away while the form is dirty → confirmation dialog "Discard changes?"; choosing Discard → no record is created in the DB
29
+ - User clicks Save twice in a row before the response → only 1 record is created, no duplicate
30
+
31
+ **[VP-VAL] Unique constraints**
32
+
33
+ - Enter a value duplicating an existing unique field (e.g. email, employee code) → rejected, inline error right at that field
34
+ - Required fields empty → the form cannot submit, no record is created in the DB (Submit disabled, or an inline error at each field on Submit click — depends on impl)
35
+ - Enter the wrong format → inline error at the field, field highlighted (text comes from {{format_error}} in test-data.yaml)
36
+
37
+ **[VP-SEC]**
38
+
39
+ - POST request to create a record without authentication → 401/403, no record is created in the DB
40
+ - POST request to create a record beyond the user's privilege (lower role) → 403 Forbidden from the server
41
+
42
+ ---
43
+
44
+ ### Tier 2 — @normal + @low
45
+
46
+ **[VP-UI] Interface states**
47
+
48
+ - [@normal] Form opens: required fields have a visual indicator (asterisk, color), optional fields do not
49
+ - [@normal] Navigate away while the form is unchanged (pristine) → no confirmation dialog appears
50
+ - [@low] Autofocus: the cursor moves to the first field automatically when the form opens
51
+ - [@low] "Save & Add Another" (if the spec has it): save succeeds → the form resets to blank, no redirect
52
+
53
+ **[VP-VAL] Dependency**
54
+
55
+ - [@normal] Select Field A (parent dropdown) → Field B (child dropdown) updates its options accordingly
56
+ - [@normal] Fields with default values: the value is shown when the form opens, the user can clear it and enter another value
57
+
58
+ ---
59
+
60
+ ### ⚡ Cross-pattern interactions
61
+
62
+ - **+ Form & Inputs**: Apply the entire VP-VAL checklist of Form & Inputs (boundary values, real-time error clear)
63
+ - **+ File Upload**: A form with a file upload field → cannot submit if the upload is not finished
64
+ - **+ Modal/Dialog**: Form inside a modal → on submit success the modal closes, the background list auto-refreshes
65
+ - **+ Data Table**: The new record appears in the table in the correct position, the total count increases by 1
66
+
67
+ ---
68
+
69
+ ## 5. Update / Edit
70
+
71
+ **Apply when**: the screen has a function to edit an existing record (an "Edit" button, a pencil icon, or inline edit).
72
+
73
+ **Inherits**: Form & Inputs — field-level validation (required, format, maxlength, whitespace, real-time error clear). Generate those once here; this pattern adds the edit-specific rules below.
74
+
75
+ **Shared checks applied**: XSS/Injection
76
+
77
+ ---
78
+
79
+ ### Tier 1 — @high
80
+
81
+ **[VP-LOGIC] Edit behavior**
82
+
83
+ - Open the edit form → all fields are pre-filled with the correct current data from the DB (text, selected dropdown, date, radio, checkbox)
84
+ - Change data and save → the record is updated in the DB, the UI reflects the new data immediately without a full-page reload
85
+ - Save success → toast shows {{success_message}} from test-data.yaml, auto-dismisses after a few seconds
86
+ - Cancel / navigate away while the form is dirty → confirmation dialog "Discard changes?"; choosing Discard → the DB is unchanged, data stays at the old value
87
+ - Save when the form has no changes (pristine) → no redundant DB UPDATE: either the Save button is disabled, or a request is sent but the server returns a no-op (verify via the Network tab: no write operation)
88
+
89
+ **[VP-VAL] Validation on edit**
90
+
91
+ - Change a unique field to a value already used by another record → rejected, inline error at the field
92
+ - Leave a unique field of the same record unchanged → save succeeds, no self-duplicate error
93
+ - Clear a required field → the Submit button becomes disabled again (override if the spec validates on submit: an inline error appears at the field on Submit click)
94
+ - Readonly / identity fields (ID, created date, username) → cannot be edited, accept no click/input
95
+
96
+ **[VP-SEC]**
97
+
98
+ - PUT/PATCH request without authentication → 401/403, the DB is unchanged
99
+ - Edit a record belonging to another user/tenant (IDOR) → 403 Forbidden, the DB is unchanged
100
+ - Edit a record that has been deleted (stale link) → 404 Not Found
101
+
102
+ ---
103
+
104
+ ### Tier 2 — @normal + @low
105
+
106
+ **[VP-UI] Interface states**
107
+
108
+ - [@normal] Readonly fields: visually dimmed, cursor not-allowed, accept no input
109
+ - [@normal] Unsaved-changes indicator: the title or tab shows a "•" or "(unsaved)" mark while the form is dirty
110
+ - [@normal] Concurrent edit: the server returns 409 Conflict on save → the error message clearly states "data was changed by someone else", the user does not lose entered data and is guided to reload to see the latest version
111
+ - [@low] "Last updated by [user] at [time]": the username and timestamp match exactly the last edit in the DB
112
+
113
+ **[VP-VAL] Dependency on edit**
114
+
115
+ - [@normal] Field dependency works as in Create: changing Field A → Field B updates its options, without resetting unrelated fields
116
+
117
+ ---
118
+
119
+ ### ⚡ Cross-pattern interactions
120
+
121
+ - **+ Form & Inputs**: Apply the entire VP-VAL checklist of Form & Inputs
122
+ - **+ File Upload**: The current file is shown → the user can replace it (new upload) or remove it, no need to re-upload if unchanged
123
+ - **+ Modal/Dialog**: Edit form inside a modal → on submit success the modal closes, the background data refreshes immediately
124
+ - **+ Data Table**: The row in the table reflects the new data immediately after a successful edit, without reloading the whole table
125
+
126
+ ---
127
+
128
+ ## 6. Delete
129
+
130
+ **Apply when**: the screen has a function to delete a record (a "Delete" button, a trash icon, or a context-menu action).
131
+
132
+ **Shared checks applied**: (no default shared check)
133
+
134
+ ---
135
+
136
+ ### Tier 1 — @high
137
+
138
+ **[VP-LOGIC] Delete behavior**
139
+
140
+ - Click Delete → a confirmation dialog must appear (no immediate delete), the confirm button uses a warning color (red/orange)
141
+ - Confirm the delete → the record disappears from the UI immediately, a toast shows the delete success message
142
+ - Cancel the confirmation → the dialog closes, the record stays in the UI and in the DB, no API is called
143
+ - Delete the last record on the current page (pagination) → automatically go to the previous page, no blank page is shown
144
+ - Delete a record referenced by another record (foreign key) → blocked, error message states the name of the module still using this record, the record is not deleted
145
+
146
+ **[VP-VAL] Delete type**
147
+
148
+ - Soft delete (default): the record is hidden from the main list, still in the DB with the flag `is_deleted = true`, the direct URL → 404 (override if the spec uses hard delete: the record is fully removed from the DB)
149
+
150
+ **[VP-SEC]**
151
+
152
+ - DELETE request without authentication → 401/403, the record is not deleted from the DB
153
+ - DELETE a record belonging to another user/tenant (IDOR via API) → 403 Forbidden, the record is not deleted
154
+ - Directly access the URL of a deleted record (soft or hard) → 404 Not Found
155
+
156
+ ---
157
+
158
+ ### Tier 2 — @normal + @low
159
+
160
+ **[VP-UI] Interface states**
161
+
162
+ - [@normal] Confirmation dialog: a clear title "Delete [record name]?", a body explaining the action cannot be undone
163
+ - [@normal] Deleting (loading): the confirm button shows a spinner and is disabled to prevent a double-click
164
+ - [@normal] Delete button: visually a warning (red color or a warning icon), not placed next to Save to avoid mis-clicks
165
+ - [@low] Bulk delete (if the spec has it): select multiple records → one confirmation for all, count stated clearly "Delete 3 records?"
166
+
167
+ **[VP-VAL] Dependency**
168
+
169
+ - [@normal] Cascade delete (if the spec has it): delete a parent → the confirmation dialog lists how many children will be deleted with it
170
+ - [@normal] Set Null (if the spec has it): delete a parent → child records still exist, the reference field becomes "Unassigned" or null
171
+
172
+ ---
173
+
174
+ ### ⚡ Cross-pattern interactions
175
+
176
+ - **+ Data Table**: The record disappears from the table immediately, the total count decreases by 1, the pagination adjusts itself
177
+ - **+ Modal/Dialog**: The delete confirmation is a modal → close the modal after deleting, the background table refreshes
178
+ - **+ List/Card View**: The card/row disappears immediately after a successful delete, no page reload needed
179
+ - **+ Notification**: The delete-success toast shows {{delete_success_message}} from test-data.yaml
@@ -0,0 +1,233 @@
1
+ # GROUP C: DATA EXPLORATION
2
+
3
+ > The user searches, filters, and browses existing data in the system.
4
+
5
+ Patterns: 7. Data Table · 8. Search · 9. Filter · 10. List / Card View
6
+ See `SKILL.md` for the 4 Viewpoints, Shared Checks, and Security Tag Rules.
7
+
8
+ ---
9
+
10
+ ## 7. Data Table
11
+
12
+ **Apply when**: the screen shows data as a table with rows and columns, usually with sort, pagination, and row-level actions.
13
+
14
+ **Shared checks applied**: Loading State, Empty State, XSS/Injection (data from the DB displayed safely)
15
+
16
+ ---
17
+
18
+ ### Tier 1 — @high
19
+
20
+ **[VP-LOGIC] Table behavior**
21
+
22
+ - Table finishes loading → the number of rows shown matches the configured page size (e.g. 10, 20, 50 rows/page)
23
+ - The total record count in the UI ("Total: X records") matches exactly the real record count in the DB
24
+ - Click a sortable column header → data re-sorts in the correct order (ASC first, DESC second), the sort icon changes accordingly
25
+ - Click a sortable column header once → sort ASC, ↑ icon shows; twice → sort DESC, ↓ icon shows; three times → back to unsorted, icon disappears
26
+ - Click an action button (Edit/Delete/View) on a row → the action applies to that exact row (correct record ID, not a different row)
27
+ - *Pagination:* Click page 2 → the table shows the correct next records, no overlap with page 1
28
+ - *Pagination:* Change the page size → the table reloads with the new row count, resets to page 1
29
+
30
+ **[VP-VAL] Data integrity**
31
+
32
+ - The value in each cell matches exactly the data in the DB (amount, date, status label, unit)
33
+ - Long text in a cell → truncated with `...`, does not break the layout or push the column out
34
+ - A column with a null/empty value → shows a placeholder (em dash or empty cell), not raw "undefined" or "null", the cell layout does not break
35
+
36
+ **[VP-SEC]**
37
+
38
+ - Data from the DB containing HTML/script tags → rendered as literal text, not executed (XSS)
39
+ - A user without permission to view a sensitive column (salary, national ID…) → the column is fully hidden from the DOM, not leaked via the API response (override if the spec wants to show `***` so the user knows the field exists)
40
+
41
+ ---
42
+
43
+ ### Tier 2 — @normal + @low
44
+
45
+ **[VP-UI] Interface states**
46
+
47
+ - [@normal] Sortable column header: has an arrow/indicator icon and a pointer cursor; a non-sortable column has no icon
48
+ - [@normal] Sticky header: scroll down vertically → the header row stays fixed, the column headers are always visible
49
+ - [@normal] Sticky action column (if the table scrolls horizontally): the Edit/Delete column is fixed on the right, not scrolled out of the viewport
50
+ - [@normal] Row hover: the background color changes slightly, clearly indicating which row is hovered
51
+ - [@normal] Pagination controls: Previous is disabled on page 1; Next is disabled on the last page; the current page is highlighted
52
+ - [@low] Column resize (if present): drag the header border to change the width, without affecting the data
53
+
54
+ **[VP-VAL] Edge cases**
55
+
56
+ - [@normal] Table with 1 row → pagination is fully hidden (override if the spec wants "Page 1 of 1"), no UI glitch
57
+ - [@normal] Sort on a datetime column → sorts correctly by the real timestamp, not alphabetically as a string
58
+ - [@normal] Sort on a numeric column → sorts correctly by numeric value (10 > 9), not as a string ("10" < "9")
59
+
60
+ ---
61
+
62
+ ### ⚡ Cross-pattern interactions
63
+
64
+ - **+ Search**: Search submit → the table filters immediately, pagination resets to page 1, the sort state is preserved
65
+ - **+ Filter**: Apply a filter → the table shows only matching rows, the total count updates, pagination resets to page 1
66
+ - **+ Update/Edit**: Save an edit successfully → the row in the table reflects the new data immediately, no full-page reload
67
+ - **+ Delete**: Delete a record → the row disappears immediately, the total count decreases by 1, pagination adjusts itself
68
+ - **+ Import/Export**: After import → the table auto-refreshes; Export takes exactly the data currently shown (current filter + sort)
69
+
70
+ ---
71
+
72
+ ## 8. Search
73
+
74
+ **Apply when**: the screen has a search box (search bar) letting the user filter data by keyword.
75
+
76
+ **Shared checks applied**: Empty State, XSS/Injection
77
+
78
+ ---
79
+
80
+ ### Tier 1 — @high
81
+
82
+ **[VP-LOGIC] Search behavior**
83
+
84
+ *Basic search:*
85
+ - Enter a valid keyword → results show the correct records containing the keyword (case-insensitive)
86
+ - Partial-match keyword → records containing the keyword anywhere all appear
87
+ - Enter a keyword matching no record → the Empty State message appears ("No results found"), the layout does not break
88
+ - Clear the keyword → the list reloads to the default state (all records), no need to press Search again
89
+
90
+ *Advanced search (if the spec has multiple search fields):*
91
+ - Fill multiple fields → results satisfy ALL filled conditions (AND logic)
92
+ - Leave some fields empty → filter only by the filled fields, empty fields are ignored
93
+
94
+ **[VP-VAL] Input handling**
95
+
96
+ - Input containing only whitespace → auto-trimmed, search with empty string → results as if not searched
97
+ - Enter special characters (single quote `'`, `%`, `_`) → treated as literal text, the query is not broken, results are valid
98
+ - Input beyond max length → field accepts no more characters (HTML maxlength default)
99
+
100
+ **[VP-SEC]** → Apply Shared Check: XSS/Injection (the search term shown in the results must be escaped correctly) + **SQL injection layer 2** (the search field reaches a LIKE query → test the API-level bypass `@high @manual`)
101
+
102
+ ---
103
+
104
+ ### Tier 2 — @normal + @low
105
+
106
+ **[VP-UI] Interface states**
107
+
108
+ - [@normal] A search icon or placeholder clearly hints what the field is for ("Search by name, email…")
109
+ - [@normal] Clear button (X): appears when there is text, click → the field empties and the list resets, no navigation away from the page
110
+ - [@normal] Search trigger: debounce ~300ms after stopping typing, or press Enter → the API call runs, a loading indicator shows in the table
111
+ - [@low] The keyword is highlighted in the results: the matching text portion is bold or a standout color
112
+
113
+ **[VP-VAL] Edge cases**
114
+
115
+ - [@normal] Keyword is pure digits (e.g. "12345") → searches correctly in numeric fields and text fields
116
+ - [@normal] Keyword is accented Vietnamese → results are correct, no encoding glitch
117
+
118
+ ---
119
+
120
+ ### ⚡ Cross-pattern interactions
121
+
122
+ - **+ Data Table**: Search submit → the table filters immediately, pagination resets to page 1
123
+ - **+ Filter**: Search + Filter both active → results satisfy BOTH conditions (AND)
124
+ - **+ Pagination**: Search returns many results → pagination shows correctly, the total count updates
125
+
126
+ ---
127
+
128
+ ## 9. Filter
129
+
130
+ **Apply when**: the screen has filters (dropdown, date range picker, checkbox group, radio group…) to narrow down the displayed dataset.
131
+
132
+ **Shared checks applied**: Empty State, URL Manipulation
133
+
134
+ ---
135
+
136
+ ### Tier 1 — @high
137
+
138
+ **[VP-LOGIC] Filter behavior**
139
+
140
+ - Select 1 filter value → the list/table shows only matching records, the total count updates correctly
141
+ - Select multiple values within the same filter group → show records matching ANY value in the group (OR logic within the group)
142
+ - Apply multiple filter groups at once → show records matching ALL groups (AND across groups)
143
+ - Reset / Clear All filters → the list returns to default, all filter controls return to their initial values
144
+ - A filter combination yielding 0 results → the Empty State appears, the layout does not break
145
+ - Dependent filter (if the screen has one): select Filter A → Filter B's options reset and reload per A's value immediately, no stale old options retained
146
+
147
+ **[VP-VAL] Input validation**
148
+
149
+ - Date range: start date > end date → the Apply button is disabled, the filter is not activated
150
+ - Numeric range: min > max → the Apply button is disabled, the filter is not activated
151
+ - Dropdown filter: options match exactly the real data in the DB (no orphan option)
152
+
153
+ **[VP-SEC]** → Apply Shared Check: URL Manipulation (tampered filter params → fallback to default, no crash)
154
+
155
+ ---
156
+
157
+ ### Tier 2 — @normal + @low
158
+
159
+ **[VP-UI] Interface states**
160
+
161
+ - [@normal] Active filters: shown as clear tags/chips, each tag has an X to remove that filter individually
162
+ - [@normal] Collapse/expand the filter panel: the selected state of the filters is preserved, not reset on collapse
163
+ - [@normal] Filter count badge: "Filters (3)" or an indicator shows the number of active filters
164
+ - [@low] Filter options in alphabetical order (override if the spec uses frequency sort or a custom order), not random on each open
165
+
166
+ **[VP-VAL] Edge cases**
167
+
168
+ - [@normal] A filter option removed from the DB (orphan option) → does not appear in the dropdown, no crash even if the URL still has the old param
169
+ - [@normal] Filter with a date range spanning a different timezone → results are correct per the server's timezone
170
+
171
+ ---
172
+
173
+ ### ⚡ Cross-pattern interactions
174
+
175
+ - **+ Search**: Filter + Search both active → AND logic, total records = the intersection of both conditions
176
+ - **+ Data Table**: Apply a filter → the table reloads, pagination resets to page 1, the sort state is preserved
177
+ - **+ Export**: Export with an active filter → the file contains only filtered records, not the entire dataset
178
+ - **+ Pagination**: A filter changing the total count → pagination recalculates, automatically goes to page 1
179
+
180
+ ---
181
+
182
+ ## 10. List / Card View
183
+
184
+ **Apply when**: the screen shows many records as a list (rows) or cards (grid), possibly with infinite scroll or a "Load More" button instead of traditional pagination.
185
+
186
+ **Shared checks applied**: Loading State, Empty State
187
+
188
+ ---
189
+
190
+ ### Tier 1 — @high
191
+
192
+ **[VP-LOGIC] Navigation & actions**
193
+
194
+ - Click a card/row → navigate to the correct detail page of that record (correct ID, not a different record)
195
+ - A quick action directly on the card (Like, Bookmark, Add to Cart, Status toggle) → changes the state immediately without navigating to another page
196
+ - *Infinite scroll:* Scroll to the bottom → the next records are appended to the list, the scroll position does not jump back to the top
197
+ - *Load More button:* Click "Load More" → the next records are appended, the total count updates
198
+ - Broken image (image URL is broken or returns 404) → a placeholder image is shown, the card layout does not break
199
+
200
+ **[VP-VAL] Data integrity**
201
+
202
+ - The values shown on the card (price, status, tag, rating) match exactly the data in the DB
203
+ - The total count ("Showing X of Y") matches the real total records after applying the current filter/search
204
+
205
+ **[VP-SEC]**
206
+
207
+ - Sensitive data (national ID, bank account number) of another user is not shown in the card → verify the DOM does not contain this data
208
+ - A quick action (Like, Follow) without auth → redirect to Login, the action is not performed
209
+
210
+ ---
211
+
212
+ ### Tier 2 — @normal + @low
213
+
214
+ **[VP-UI] Interface states**
215
+
216
+ - [@normal] Interactive cards: a clear hover effect (shadow, scale, or overlay) + pointer cursor; non-interactive (informational only) cards: no hover effect, default cursor
217
+ - [@normal] Grid/List layout toggle (if present): the switch changes the layout immediately, the data is unchanged, the preference is saved on page reload
218
+ - [@normal] Skeleton loading: while fetching → skeleton cards show the correct count and layout, no blank screen
219
+ - [@low] Lazy-loading images: images in the viewport load first, images outside load when scrolled to
220
+
221
+ **[VP-VAL] Edge cases**
222
+
223
+ - [@normal] A card with very long text (title, description) → text truncates with single-line ellipsis, does not break the card width (override if the spec uses a multi-line clamp: max 2-3 lines)
224
+ - [@normal] Load More / infinite scroll with total < page size → the "Load More" button is fully hidden (override if the spec wants it shown disabled with "No more records")
225
+
226
+ ---
227
+
228
+ ### ⚡ Cross-pattern interactions
229
+
230
+ - **+ Search**: Keyword submit → the list filters immediately, showing only cards matching the keyword
231
+ - **+ Filter**: Apply a filter → the list reloads, showing only cards matching the condition
232
+ - **+ Delete**: Delete a record → the card disappears from the list immediately, the total count decreases by 1
233
+ - **+ Update/Edit**: Edit successfully → the card reflects the new data immediately (name, status, image)