@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.
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +9 -2
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +12 -4
- package/dist/exporters/feature-parser.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +10 -0
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +13 -12
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-delivery.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +14 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +371 -324
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +268 -90
- package/dist/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +23 -49
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +203 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +179 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +233 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +226 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +177 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +69 -240
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +13 -12
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -21
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +371 -324
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +262 -102
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +23 -49
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +203 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +179 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +233 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +226 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +177 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +69 -240
- package/package.json +9 -1
- package/src/cli/index.ts +4 -1
- package/src/exporters/feature-parser.ts +12 -4
- package/src/orchestrator/ai-rules-updater.ts +10 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +13 -12
- package/src/orchestrator/templates/ai-instructions/claude-config.md +1 -1
- package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +1 -1
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +14 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +371 -324
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +268 -90
- package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +23 -49
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +203 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +179 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +233 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +226 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +177 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +69 -240
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +13 -12
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +1 -1
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +1 -1
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -21
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +371 -324
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +262 -102
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +23 -49
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +203 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +179 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +233 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +226 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +177 -0
- 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
|
package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md
ADDED
|
@@ -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)
|