Page Design: Khám phá Dữ liệu (Discovery)
Follows MASTER.md — CRUD List + Dialog patterns.
Applies to: SCR-DISC-10, SCR-DISC-11, SCR-DISC-20
Route: /[locale]/discovery
Users: Manager
Layout
+-----------------------------------------------------------+
| "Khám phá Dữ liệu" |
| "Thu thập metadata cấu trúc từ CSDL các Sở/Ban/Ngành" |
| [+ Nhập metadata] |
+-----------------------------------------------------------+
| [Filter: Đơn vị ▼] [Filter: Trạng thái ▼] [Search...] |
+-----------------------------------------------------------+
| Table |
| ┌──────────┬────────┬──────┬──────────┬────────┬────────┐ |
| │ Tên file │ Đơn vị │ Loại │ Số fields│Trạng thái│ Ngày │ |
| ├──────────┼────────┼──────┼──────────┼────────┼────────┤ |
| │ schema.ddl│ Sở TC │ DDL │ 42 │✅ Done │ 24/03 │ |
| │ data.csv │ BHXH │ CSV │ 18 │⏳ Parse│ 23/03 │ |
| └──────────┴────────┴──────┴──────────┴────────┴────────┘ |
+-----------------------------------------------------------+
| Pagination: 20 items/page |
+-----------------------------------------------------------+
Components
- Page header: Title + subtitle + primary "Nhập metadata" button (opens SCR-DISC-11)
- Workflow Stepper (same as SCR-MAP-20): Shows Discovery as step 1 of BPF-01 flow
- Filter bar: Unit select + Status select + search input
- Table: MASTER.md table pattern
- File type badge:
DDL (violet), CSV (blue), Manual (slate)
- Status badge:
PENDING (yellow), PROCESSING (blue animate-pulse), COMPLETED (green), FAILED (red)
- Click row → navigate to SCR-DISC-20
- NEW — Matching action per row (GAP-05): For COMPLETED sources, show "▶ Chạy Matching" button in action column → triggers matching for that batch, navigates to SCR-MAP-20 with progress
- Empty state: "Chưa có nguồn metadata nào. Bắt đầu bằng cách upload file hoặc khai báo thủ công."
Row Action Column (UX IMPROVEMENT)
/* Action column per row — DropdownMenu or inline buttons */
flex items-center gap-2
/* COMPLETED sources → matching trigger */
Button(variant="outline", size="sm")
Play.h-3.w-3.mr-1 "Chạy Matching"
/* Already matched sources */
Badge.text-[10px].bg-success/10.text-success "Đã matching"
/* FAILED sources */
Button(variant="outline", size="sm").text-destructive
RotateCcw.h-3.w-3.mr-1 "Thử lại"
Data & Business Rules
| Rule |
Detail |
| Default sort |
created_at DESC |
| Pagination |
20 items/page |
| PROCESSING status |
Show spinner in badge, auto-refresh every 10s |
| FAILED status |
Show error icon, click to see error detail + "Thử lại" button |
| Matching trigger |
Only for COMPLETED sources. Navigate to SCR-MAP-20 with batch pre-selected |
Layout
+------------------------------------------+
| "Nhập metadata từ đơn vị" |
+------------------------------------------+
| Phương thức nhập: |
| [Tab: Upload file] [Tab: Khai báo thủ công]|
| ───────────────────────────────────── |
| TAB 1: Upload file |
| Đơn vị: [Select đơn vị] |
| Loại file: (●) CSV (○) SQL DDL |
| File: [Drop zone / Browse] |
| ───────────────────────────────────── |
| TAB 2: Khai báo thủ công |
| Đơn vị: [Select đơn vị] |
| Tên bảng: [Input] |
| Fields: [Dynamic field list — add/remove] |
+------------------------------------------+
| [Hủy] [Nhập metadata] |
+------------------------------------------+
Components
/* Dialog — max-w-2xl (larger for file upload + manual entry) */
/* Tabs — MASTER.md tab pattern */
Tabs
TabsTrigger "Upload file"
TabsTrigger "Khai báo thủ công"
/* Upload tab */
/* Unit select — required */
Select placeholder="Chọn đơn vị..."
/* File type — radio group inline */
RadioGroup.flex.gap-4
/* Drop zone */
border-2.border-dashed.border-border.rounded-2xl.p-8.text-center
.hover:border-primary.hover:bg-primary/5.transition-all.cursor-pointer
Upload.h-8.w-8.text-muted-foreground.mx-auto
p.text-sm.font-semibold.mt-2 "Kéo thả file hoặc click để chọn"
p.text-xs.text-muted-foreground "CSV, DDL (tối đa 10MB)"
/* File selected state */
bg-muted/50.rounded-2xl.p-4.flex.items-center.gap-3
FileText.h-5.w-5.text-primary
span.font-semibold /* filename */
span.text-xs.text-muted-foreground /* file size */
Button(variant="ghost", size="icon") X /* remove */
/* Manual tab */
/* Unit select — same */
/* Table name input */
/* Dynamic fields list */
space-y-2
/* Each field row */
flex items-center gap-3
Input.flex-1 placeholder="Tên field"
Select.w-40 /* Data type: Text/Number/Date... */
Button(variant="ghost", size="icon") Trash2 /* remove */
/* Add field button */
Button(variant="outline", size="sm")
Plus.h-4.w-4.mr-2 "Thêm field"
Business Rules
- Upload: background job for large files. Toast "File đã được tải lên, đang xử lý..."
- Manual: validate min 1 field required
- After submit: redirect to SCR-DISC-10, new source appears with PROCESSING status
Layout
+-----------------------------------------------------------+
| Breadcrumb: Khám phá DL > [file name] |
+-----------------------------------------------------------+
| H1: [file name] Badges: [DDL] [COMPLETED] [Sở TC] |
+-----------------------------------------------------------+
| Summary: 42 fields trích xuất | 3 bảng phát hiện |
+-----------------------------------------------------------+
| Table: Extracted Fields |
| ┌──────────┬──────────┬──────────┬──────────┬────────────┐ |
| │ Tên field│ Kiểu DL │ Tên bảng │ Matching │ Thao tác │ |
| ├──────────┼──────────┼──────────┼──────────┼────────────┤ |
| │ ho_ten │ VARCHAR │ nhan_vien│ ✅ Matched│ [Sửa] │ |
| │ ngay_sinh│ DATE │ nhan_vien│ ⏳ Pending│ │ |
| └──────────┴──────────┴──────────┴──────────┴────────────┘ |
+-----------------------------------------------------------+
Components
- Breadcrumb + header: MASTER.md patterns
- Summary cards: 2 stat cards (total fields, total tables) — inline, smaller
- Fields table: MASTER.md table
- field_name in
font-mono font-bold
- data_type in
font-mono text-xs
- Matching status badge: Matched (green) / Pending (yellow) / Unmatched (slate)
- "Sửa" link → inline edit or popup for field name correction
- Parse error display (if FAILED status): Error banner with details
Behaviors
| State |
Trigger |
Display |
| Loading |
Page init |
Skeleton |
| PROCESSING |
File still parsing |
Spinner + "Đang xử lý..." + auto-refresh |
| COMPLETED |
Parse done |
Full table of fields |
| FAILED |
Parse error |
Error banner with detail + "Thử lại" button |
Accessibility
- Upload drop zone:
aria-label="Khu vực tải file", keyboard accessible (Enter/Space)
- Dynamic field list:
aria-label="Danh sách fields khai báo thủ công"
- Add/remove field: announce via
aria-live="polite"
- Table: sortable headers, row hover
MASTER.md Overrides
| What |
MASTER.md |
This Page |
Reason |
| SCR-DISC-11 dialog width |
max-w-lg |
max-w-2xl |
File upload + manual entry tabs need space |