task-d.7.6
This commit is contained in:
71
docs/implementation/task-d76-dashboard-setup-wizard-ui.md
Normal file
71
docs/implementation/task-d76-dashboard-setup-wizard-ui.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Task D.7.6 Dashboard Setup Wizard UI
|
||||||
|
|
||||||
|
Date: 2026-07-03
|
||||||
|
Status: implemented
|
||||||
|
|
||||||
|
## Scope Delivered
|
||||||
|
|
||||||
|
Added dashboard-native setup wizard route:
|
||||||
|
|
||||||
|
- `GET /dashboard/administration/setup`
|
||||||
|
- Server-side page access restricted to `super_admin`
|
||||||
|
- Admin navigation item for `Setup Wizard`
|
||||||
|
|
||||||
|
Added setup UI orchestration:
|
||||||
|
|
||||||
|
- `src/features/setup/components/setup-wizard.tsx`
|
||||||
|
- `src/app/dashboard/administration/setup/page.tsx`
|
||||||
|
|
||||||
|
Extended setup API client surface:
|
||||||
|
|
||||||
|
- `src/features/setup/api/types.ts`
|
||||||
|
- `src/features/setup/api/service.ts`
|
||||||
|
- `src/features/setup/api/queries.ts`
|
||||||
|
- `src/features/setup/api/use-csv-commit.ts`
|
||||||
|
- `src/features/setup/api/use-setup-verification.ts`
|
||||||
|
|
||||||
|
## Behavior
|
||||||
|
|
||||||
|
- Step 1 calls setup readiness and displays overall status, PASS / WARNING / FAIL counts, grouped checks, suggested fixes, loading, error, and permission states.
|
||||||
|
- Step 2 calls template metadata and displays registered setup templates from the existing setup template API.
|
||||||
|
- Step 3 accepts one or more CSV files and does not upload them until the user clicks preview.
|
||||||
|
- Step 4 calls CSV preview, stores `previewHash` in client state only, displays per-file summaries, row/error/warning counts, and grouped safe error messages.
|
||||||
|
- Step 5 calls CSV commit with the latest `previewHash`.
|
||||||
|
- Commit is disabled when preview has `FAIL`.
|
||||||
|
- Commit requires warning acknowledgement when preview has `WARNING`.
|
||||||
|
- File changes after preview clear commit eligibility and require re-preview, using file name + size + lastModified fingerprint.
|
||||||
|
- Step 6 calls setup verification and displays grouped checks plus summary counts.
|
||||||
|
- Step 7 summarizes readiness, preview, commit, and verification results for the current browser session.
|
||||||
|
|
||||||
|
## Security And API Notes
|
||||||
|
|
||||||
|
- Setup page uses `auth()` and `PageContainer` access fallback for non-super-admin users.
|
||||||
|
- Existing setup APIs remain the enforcement boundary and still require `super_admin`.
|
||||||
|
- Upload requests use `FormData` directly so browser-managed multipart boundaries are preserved.
|
||||||
|
- UI reads safe API error messages and does not render raw stack traces.
|
||||||
|
- CSV files are uploaded only to the preview and commit endpoints.
|
||||||
|
- The wizard does not log CSV data.
|
||||||
|
|
||||||
|
## Out Of Scope Preserved
|
||||||
|
|
||||||
|
- No setup state persistence.
|
||||||
|
- No seed manifest persistence.
|
||||||
|
- No destructive reset or reseed behavior.
|
||||||
|
- No seed execution.
|
||||||
|
- No database migrations.
|
||||||
|
- No new CRM behavior.
|
||||||
|
- No file download or ZIP template generation.
|
||||||
|
|
||||||
|
Persistent setup runs and resume behavior remain deferred to D.7.8.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `npm run typecheck -- --pretty false` passed.
|
||||||
|
- `npx oxlint src/features/setup/api/types.ts src/features/setup/api/service.ts src/features/setup/api/queries.ts src/features/setup/api/use-csv-commit.ts src/features/setup/api/use-setup-verification.ts src/features/setup/components/setup-wizard.tsx src/app/dashboard/administration/setup/page.tsx src/config/nav-config.ts` passed.
|
||||||
|
- Existing dev server was already running at `http://localhost:3000`.
|
||||||
|
- `curl.exe -I -L --max-time 20 http://localhost:3000/dashboard/administration/setup` returned `200 OK`.
|
||||||
|
|
||||||
|
## Residual Notes
|
||||||
|
|
||||||
|
- `plans/task-d.7.6.md` was already untracked during implementation and was not modified as part of this delivery.
|
||||||
|
- The wizard is intentionally session-only until the D.7.8 setup-state persistence slice.
|
||||||
486
plans/task-d.7.6.md
Normal file
486
plans/task-d.7.6.md
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
# Task D.7.6 – Dashboard Setup Wizard UI
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Build a dashboard-native Setup Wizard UI for ALLA OS Administration.
|
||||||
|
|
||||||
|
The wizard must connect the previously implemented setup APIs into one guided workflow:
|
||||||
|
|
||||||
|
- D.7.2 Readiness and Verification APIs
|
||||||
|
- D.7.3 CSV Template Pack and Template Metadata API
|
||||||
|
- D.7.4 CSV Preview Validation Engine
|
||||||
|
- D.7.5 CSV Commit Import Engine
|
||||||
|
|
||||||
|
This task focuses on UI and orchestration only.
|
||||||
|
|
||||||
|
Do not implement seed execution, destructive reset, setup state persistence, seed manifest persistence, or new migrations in this task.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Review Before Implementation
|
||||||
|
|
||||||
|
Review:
|
||||||
|
|
||||||
|
- AGENTS.md
|
||||||
|
- plans/task-d.7.md
|
||||||
|
- plans/task-d.7.1.md
|
||||||
|
- plans/task-d.7.2.md
|
||||||
|
- plans/task-d.7.3.md
|
||||||
|
- plans/task-d.7.4.md
|
||||||
|
- plans/task-d.7.5.md
|
||||||
|
- docs/setup/seed-matrix.md
|
||||||
|
- docs/setup/setup-wizard-blueprint.md
|
||||||
|
- docs/setup/setup-state-machine.md
|
||||||
|
- docs/setup/verification-matrix.md
|
||||||
|
- docs/setup/csv-template-spec.md
|
||||||
|
- docs/setup/import-mapping.md
|
||||||
|
- setup/templates/README.md
|
||||||
|
- setup/templates/templates.json
|
||||||
|
- src/features/setup/api/types.ts
|
||||||
|
- src/features/setup/api/service.ts
|
||||||
|
- src/features/setup/api/queries.ts
|
||||||
|
- src/app/api/setup/readiness/route.ts
|
||||||
|
- src/app/api/setup/verify/route.ts
|
||||||
|
- src/app/api/setup/templates/route.ts
|
||||||
|
- src/app/api/setup/import/preview/route.ts
|
||||||
|
- src/app/api/setup/import/commit/route.ts
|
||||||
|
- existing dashboard pages and PageContainer usage
|
||||||
|
- src/config/nav-config.ts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Scope
|
||||||
|
|
||||||
|
Create dashboard page:
|
||||||
|
|
||||||
|
src/app/dashboard/administration/setup/page.tsx
|
||||||
|
|
||||||
|
Create UI components under:
|
||||||
|
|
||||||
|
src/features/setup/components/
|
||||||
|
|
||||||
|
Recommended components:
|
||||||
|
|
||||||
|
- setup-wizard.tsx
|
||||||
|
- setup-wizard-stepper.tsx
|
||||||
|
- setup-status-badge.tsx
|
||||||
|
- setup-check-list.tsx
|
||||||
|
- setup-summary-cards.tsx
|
||||||
|
- setup-template-list.tsx
|
||||||
|
- csv-upload-dropzone.tsx
|
||||||
|
- csv-preview-table.tsx
|
||||||
|
- csv-import-report.tsx
|
||||||
|
- setup-verification-summary.tsx
|
||||||
|
- setup-finish-panel.tsx
|
||||||
|
|
||||||
|
Optional hooks:
|
||||||
|
|
||||||
|
src/features/setup/api/use-setup-readiness.ts
|
||||||
|
src/features/setup/api/use-setup-templates.ts
|
||||||
|
src/features/setup/api/use-csv-preview.ts
|
||||||
|
src/features/setup/api/use-csv-commit.ts
|
||||||
|
src/features/setup/api/use-setup-verification.ts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Route and Navigation
|
||||||
|
|
||||||
|
Add menu item under Administration:
|
||||||
|
|
||||||
|
Administration
|
||||||
|
|
||||||
|
Setup Wizard
|
||||||
|
|
||||||
|
Target route:
|
||||||
|
|
||||||
|
/dashboard/administration/setup
|
||||||
|
|
||||||
|
The route must be protected by existing dashboard/auth rules.
|
||||||
|
|
||||||
|
If setup APIs require `super_admin`, the UI should show a friendly permission message when unauthorized.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wizard Steps
|
||||||
|
|
||||||
|
Implement these UI steps.
|
||||||
|
|
||||||
|
### Step 1 – System Readiness
|
||||||
|
|
||||||
|
Call:
|
||||||
|
|
||||||
|
GET /api/setup/readiness
|
||||||
|
|
||||||
|
Show:
|
||||||
|
|
||||||
|
- Overall status
|
||||||
|
- PASS / WARNING / FAIL counts
|
||||||
|
- Check list grouped by area
|
||||||
|
- Suggested fixes
|
||||||
|
- Re-run button
|
||||||
|
|
||||||
|
Blocking behavior:
|
||||||
|
|
||||||
|
- FAIL should block moving forward unless step is marked dry-run / review-only.
|
||||||
|
- WARNING can continue with acknowledgement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2 – Template Pack
|
||||||
|
|
||||||
|
Call:
|
||||||
|
|
||||||
|
GET /api/setup/templates
|
||||||
|
|
||||||
|
Show:
|
||||||
|
|
||||||
|
- available CSV templates
|
||||||
|
- import order
|
||||||
|
- seed type
|
||||||
|
- required columns
|
||||||
|
- sample file name
|
||||||
|
- unsupported/deferred templates from README or metadata if available
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- link to local setup/templates path in documentation text only
|
||||||
|
- do not implement file download unless already available
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 3 – CSV Upload
|
||||||
|
|
||||||
|
Allow upload of multiple CSV files.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- accept only `.csv`
|
||||||
|
- show selected files
|
||||||
|
- allow remove/replace
|
||||||
|
- show detected file count
|
||||||
|
- show missing recommended templates as info only
|
||||||
|
- do not upload automatically until Preview button is clicked
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 4 – CSV Preview
|
||||||
|
|
||||||
|
Call:
|
||||||
|
|
||||||
|
POST /api/setup/import/preview
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
multipart/form-data files
|
||||||
|
|
||||||
|
Show:
|
||||||
|
|
||||||
|
- previewHash
|
||||||
|
- overall status
|
||||||
|
- per-file status
|
||||||
|
- row count
|
||||||
|
- create/update/error/warning counts
|
||||||
|
- row-level errors
|
||||||
|
- row-level warnings
|
||||||
|
- dependency warnings
|
||||||
|
- duplicate warnings
|
||||||
|
|
||||||
|
Blocking behavior:
|
||||||
|
|
||||||
|
- FAIL blocks commit.
|
||||||
|
- WARNING requires acknowledgement before commit.
|
||||||
|
- Store previewHash in client state only for this task.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 5 – CSV Commit
|
||||||
|
|
||||||
|
Call:
|
||||||
|
|
||||||
|
POST /api/setup/import/commit
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
same files + previewHash
|
||||||
|
|
||||||
|
Support:
|
||||||
|
|
||||||
|
- dryRun toggle
|
||||||
|
- commit button
|
||||||
|
- show import report
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- Commit button disabled when preview has blocking errors.
|
||||||
|
- If files changed after preview, force re-preview.
|
||||||
|
- If commit returns previewHash mismatch, show clear message and require re-preview.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 6 – Verification
|
||||||
|
|
||||||
|
Call:
|
||||||
|
|
||||||
|
POST /api/setup/verify
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
optional organizationId / active org context
|
||||||
|
|
||||||
|
Show:
|
||||||
|
|
||||||
|
- overall status
|
||||||
|
- PASS / WARNING / FAIL counts
|
||||||
|
- grouped checks
|
||||||
|
- suggested fixes
|
||||||
|
- re-run button
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 7 – Finish
|
||||||
|
|
||||||
|
Show:
|
||||||
|
|
||||||
|
- readiness summary
|
||||||
|
- template summary
|
||||||
|
- preview summary
|
||||||
|
- commit summary
|
||||||
|
- verification summary
|
||||||
|
- next recommended task
|
||||||
|
|
||||||
|
Because setup state persistence is out of scope, do not permanently lock or complete setup.
|
||||||
|
|
||||||
|
Show clear message:
|
||||||
|
|
||||||
|
This wizard session is not persisted yet. Persistent setup runs will be implemented in D.7.8.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI Requirements
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
- shadcn/ui
|
||||||
|
- PageContainer
|
||||||
|
- Card
|
||||||
|
- Button
|
||||||
|
- Badge
|
||||||
|
- Alert
|
||||||
|
- Table
|
||||||
|
- Tabs or Accordion where helpful
|
||||||
|
- Progress / Stepper
|
||||||
|
- ScrollArea for long reports
|
||||||
|
- responsive layout
|
||||||
|
- dark mode compatible styles
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
- hardcoded colors outside design tokens
|
||||||
|
- raw JSON dumps as main UI
|
||||||
|
- giant ungrouped error lists
|
||||||
|
- hidden errors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UX Requirements
|
||||||
|
|
||||||
|
The wizard should feel like an enterprise setup console.
|
||||||
|
|
||||||
|
Must include:
|
||||||
|
|
||||||
|
- clear progress
|
||||||
|
- clear blocking vs non-blocking issues
|
||||||
|
- grouped diagnostics
|
||||||
|
- concise summary cards
|
||||||
|
- actionable suggested fixes
|
||||||
|
- retry/re-run buttons
|
||||||
|
- empty states
|
||||||
|
- loading states
|
||||||
|
- error states
|
||||||
|
- permission denied state
|
||||||
|
|
||||||
|
Recommended status language:
|
||||||
|
|
||||||
|
PASS
|
||||||
|
|
||||||
|
WARNING
|
||||||
|
|
||||||
|
FAIL
|
||||||
|
|
||||||
|
Do not translate status enum values in API handling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## State Management
|
||||||
|
|
||||||
|
D.7.6 uses client-side state only.
|
||||||
|
|
||||||
|
Track:
|
||||||
|
|
||||||
|
- current step
|
||||||
|
- readiness report
|
||||||
|
- template metadata
|
||||||
|
- selected files
|
||||||
|
- preview report
|
||||||
|
- previewHash
|
||||||
|
- commit report
|
||||||
|
- verification report
|
||||||
|
- warning acknowledgement
|
||||||
|
|
||||||
|
Do not implement DB persistence.
|
||||||
|
|
||||||
|
If browser refreshes, state can reset.
|
||||||
|
|
||||||
|
Add note that persistent resume will arrive in D.7.8.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Integration Rules
|
||||||
|
|
||||||
|
- Reuse existing setup API types.
|
||||||
|
- Do not duplicate response shapes manually if types exist.
|
||||||
|
- Handle non-200 responses safely.
|
||||||
|
- Show safe error message from API contract.
|
||||||
|
- Do not display raw stack traces.
|
||||||
|
- Do not log sensitive CSV data.
|
||||||
|
- Do not upload files except to preview/commit endpoints.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSV File Change Rules
|
||||||
|
|
||||||
|
After successful preview:
|
||||||
|
|
||||||
|
- if selected files are removed, added, renamed, or content changed
|
||||||
|
- clear previewHash
|
||||||
|
- clear commit report
|
||||||
|
- require preview again
|
||||||
|
|
||||||
|
Implementation can use file name + size + lastModified fingerprint for this task.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
- Persistent setup state
|
||||||
|
- setup_runs / setup_run_steps migrations
|
||||||
|
- seed_manifests persistence
|
||||||
|
- seed execution
|
||||||
|
- scoped reset/reseed UI
|
||||||
|
- CSV template ZIP download
|
||||||
|
- production setup lock
|
||||||
|
- installation profile engine
|
||||||
|
- plugin runtime
|
||||||
|
- real file attachment import
|
||||||
|
- email settings persistence
|
||||||
|
- new CRM behavior
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deliverables
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
src/app/dashboard/administration/setup/page.tsx
|
||||||
|
|
||||||
|
src/features/setup/components/setup-wizard.tsx
|
||||||
|
src/features/setup/components/setup-wizard-stepper.tsx
|
||||||
|
src/features/setup/components/setup-status-badge.tsx
|
||||||
|
src/features/setup/components/setup-check-list.tsx
|
||||||
|
src/features/setup/components/setup-summary-cards.tsx
|
||||||
|
src/features/setup/components/setup-template-list.tsx
|
||||||
|
src/features/setup/components/csv-upload-dropzone.tsx
|
||||||
|
src/features/setup/components/csv-preview-table.tsx
|
||||||
|
src/features/setup/components/csv-import-report.tsx
|
||||||
|
src/features/setup/components/setup-verification-summary.tsx
|
||||||
|
src/features/setup/components/setup-finish-panel.tsx
|
||||||
|
|
||||||
|
Navigation update:
|
||||||
|
|
||||||
|
src/config/nav-config.ts
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
src/features/setup/api/use-setup-readiness.ts
|
||||||
|
src/features/setup/api/use-setup-templates.ts
|
||||||
|
src/features/setup/api/use-csv-preview.ts
|
||||||
|
src/features/setup/api/use-csv-commit.ts
|
||||||
|
src/features/setup/api/use-setup-verification.ts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
✓ Dashboard route exists at /dashboard/administration/setup.
|
||||||
|
|
||||||
|
✓ Navigation exposes Setup Wizard under Administration.
|
||||||
|
|
||||||
|
✓ Stepper wizard renders with all required steps.
|
||||||
|
|
||||||
|
✓ Readiness step calls GET /api/setup/readiness.
|
||||||
|
|
||||||
|
✓ Template step calls GET /api/setup/templates.
|
||||||
|
|
||||||
|
✓ CSV upload accepts multiple CSV files.
|
||||||
|
|
||||||
|
✓ Preview step calls POST /api/setup/import/preview.
|
||||||
|
|
||||||
|
✓ Preview report displays file and row-level validation results.
|
||||||
|
|
||||||
|
✓ Commit step calls POST /api/setup/import/commit with previewHash.
|
||||||
|
|
||||||
|
✓ Commit is disabled when preview has FAIL.
|
||||||
|
|
||||||
|
✓ File changes after preview clear previewHash and require re-preview.
|
||||||
|
|
||||||
|
✓ Verification step calls POST /api/setup/verify.
|
||||||
|
|
||||||
|
✓ Finish step summarizes all prior outputs.
|
||||||
|
|
||||||
|
✓ UI handles loading, empty, error, unauthorized, warning, and success states.
|
||||||
|
|
||||||
|
✓ Uses shadcn/ui and existing dashboard layout conventions.
|
||||||
|
|
||||||
|
✓ No setup data persistence or reset logic is introduced.
|
||||||
|
|
||||||
|
✓ Typecheck passes or unrelated failures are documented.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Suggested Verification
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
npm run typecheck
|
||||||
|
|
||||||
|
Run scoped lint:
|
||||||
|
|
||||||
|
npx oxlint src/features/setup src/app/dashboard/administration/setup src/config/nav-config.ts
|
||||||
|
|
||||||
|
Manual test:
|
||||||
|
|
||||||
|
1. Open /dashboard/administration/setup as super_admin.
|
||||||
|
2. Run readiness.
|
||||||
|
3. View template pack.
|
||||||
|
4. Upload valid CSV batch.
|
||||||
|
5. Run preview.
|
||||||
|
6. Confirm previewHash appears.
|
||||||
|
7. Run dryRun commit.
|
||||||
|
8. Run commit.
|
||||||
|
9. Re-run verification.
|
||||||
|
10. Confirm finish summary.
|
||||||
|
11. Modify selected file after preview.
|
||||||
|
12. Confirm previewHash clears.
|
||||||
|
13. Login as non-super_admin and confirm friendly unauthorized behavior.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Follow-up
|
||||||
|
|
||||||
|
After D.7.6:
|
||||||
|
|
||||||
|
D.7.8 – Seed Manifest and Setup State Persistence
|
||||||
|
|
||||||
|
D.7.7 – Scoped Reset and Reseed Engine
|
||||||
|
|
||||||
|
D.7.9 – Installation Profile and Plugin Runtime Enhancement
|
||||||
27
src/app/dashboard/administration/setup/page.tsx
Normal file
27
src/app/dashboard/administration/setup/page.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { auth } from '@/auth';
|
||||||
|
import PageContainer from '@/components/layout/page-container';
|
||||||
|
import { SetupWizard } from '@/features/setup/components/setup-wizard';
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: 'Dashboard: Administration Setup'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function AdministrationSetupPage() {
|
||||||
|
const session = await auth();
|
||||||
|
const canAccessSetup = session?.user?.systemRole === 'super_admin';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer
|
||||||
|
pageTitle='Administration Setup Wizard'
|
||||||
|
pageDescription='Run readiness checks, review setup templates, preview CSV imports, commit imports, and verify the configured system.'
|
||||||
|
access={canAccessSetup}
|
||||||
|
accessFallback={
|
||||||
|
<div className='rounded-lg border border-dashed p-8 text-center text-muted-foreground'>
|
||||||
|
Setup administration requires a super admin account.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SetupWizard />
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -178,6 +178,14 @@ import { NavGroup } from "@/types";
|
|||||||
items: [],
|
items: [],
|
||||||
access: { systemRole: "super_admin" },
|
access: { systemRole: "super_admin" },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Setup Wizard",
|
||||||
|
url: "/dashboard/administration/setup",
|
||||||
|
icon: "settings",
|
||||||
|
isActive: false,
|
||||||
|
items: [],
|
||||||
|
access: { systemRole: "super_admin" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Teams",
|
title: "Teams",
|
||||||
url: "/dashboard/workspaces/team",
|
url: "/dashboard/workspaces/team",
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { queryOptions } from '@tanstack/react-query';
|
import { queryOptions } from '@tanstack/react-query';
|
||||||
import { getSetupReadiness, verifySetup } from './service';
|
import { getSetupReadiness, getSetupTemplates, verifySetup } from './service';
|
||||||
import type { SetupVerificationPayload } from './types';
|
import type { SetupVerificationPayload } from './types';
|
||||||
|
|
||||||
export const setupKeys = {
|
export const setupKeys = {
|
||||||
all: ['setup'] as const,
|
all: ['setup'] as const,
|
||||||
readiness: () => [...setupKeys.all, 'readiness'] as const,
|
readiness: () => [...setupKeys.all, 'readiness'] as const,
|
||||||
|
templates: () => [...setupKeys.all, 'templates'] as const,
|
||||||
verification: (payload: SetupVerificationPayload = {}) =>
|
verification: (payload: SetupVerificationPayload = {}) =>
|
||||||
[...setupKeys.all, 'verification', payload] as const
|
[...setupKeys.all, 'verification', payload] as const
|
||||||
};
|
};
|
||||||
@@ -15,6 +16,12 @@ export const setupReadinessQueryOptions = () =>
|
|||||||
queryFn: () => getSetupReadiness()
|
queryFn: () => getSetupReadiness()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setupTemplatesQueryOptions = () =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: setupKeys.templates(),
|
||||||
|
queryFn: () => getSetupTemplates()
|
||||||
|
});
|
||||||
|
|
||||||
export const setupVerificationQueryOptions = (payload: SetupVerificationPayload = {}) =>
|
export const setupVerificationQueryOptions = (payload: SetupVerificationPayload = {}) =>
|
||||||
queryOptions({
|
queryOptions({
|
||||||
queryKey: setupKeys.verification(payload),
|
queryKey: setupKeys.verification(payload),
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
import { apiClient } from '@/lib/api-client';
|
import { ApiClientError, apiClient } from '@/lib/api-client';
|
||||||
import type {
|
import type {
|
||||||
|
CsvPreviewResult,
|
||||||
|
ImportReport,
|
||||||
SetupReadinessReport,
|
SetupReadinessReport,
|
||||||
|
SetupTemplatesResponse,
|
||||||
SetupVerificationPayload,
|
SetupVerificationPayload,
|
||||||
SetupVerificationReport
|
SetupVerificationReport
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
|
interface ApiErrorPayload {
|
||||||
|
message?: string;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getSetupReadiness(): Promise<SetupReadinessReport> {
|
export async function getSetupReadiness(): Promise<SetupReadinessReport> {
|
||||||
return apiClient<SetupReadinessReport>('/setup/readiness');
|
return apiClient<SetupReadinessReport>('/setup/readiness');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getSetupTemplates(): Promise<SetupTemplatesResponse> {
|
||||||
|
return apiClient<SetupTemplatesResponse>('/setup/templates');
|
||||||
|
}
|
||||||
|
|
||||||
export async function verifySetup(
|
export async function verifySetup(
|
||||||
payload: SetupVerificationPayload = {}
|
payload: SetupVerificationPayload = {}
|
||||||
): Promise<SetupVerificationReport> {
|
): Promise<SetupVerificationReport> {
|
||||||
@@ -17,3 +29,50 @@ export async function verifySetup(
|
|||||||
body: JSON.stringify(payload)
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function readUploadResponse<T>(response: Response): Promise<T> {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json() as Promise<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = (await response.json().catch(() => null)) as ApiErrorPayload | null;
|
||||||
|
const message = payload?.message ?? payload?.error ?? `API error: ${response.status}`;
|
||||||
|
|
||||||
|
throw new ApiClientError(message, {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
payload
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCsvFormData(files: File[]): FormData {
|
||||||
|
const formData = new FormData();
|
||||||
|
files.forEach((file) => formData.append('files', file, file.name));
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function previewSetupCsvFiles(files: File[]): Promise<CsvPreviewResult> {
|
||||||
|
return readUploadResponse<CsvPreviewResult>(
|
||||||
|
await fetch('/api/setup/import/preview', {
|
||||||
|
method: 'POST',
|
||||||
|
body: buildCsvFormData(files)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function commitSetupCsvFiles(input: {
|
||||||
|
files: File[];
|
||||||
|
previewHash: string;
|
||||||
|
dryRun?: boolean;
|
||||||
|
}): Promise<ImportReport> {
|
||||||
|
const formData = buildCsvFormData(input.files);
|
||||||
|
formData.set('previewHash', input.previewHash);
|
||||||
|
formData.set('dryRun', String(Boolean(input.dryRun)));
|
||||||
|
|
||||||
|
return readUploadResponse<ImportReport>(
|
||||||
|
await fetch('/api/setup/import/commit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,3 +37,36 @@ export interface SetupVerificationPayload {
|
|||||||
export interface SetupVerificationReport extends SetupReadinessReport {
|
export interface SetupVerificationReport extends SetupReadinessReport {
|
||||||
organizationId: string | null;
|
organizationId: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SetupTemplateMetadataItem {
|
||||||
|
file: string;
|
||||||
|
seedType: string;
|
||||||
|
importOrder: number;
|
||||||
|
supported: boolean;
|
||||||
|
requiredColumns: string[];
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SetupTemplatesResponse {
|
||||||
|
success: boolean;
|
||||||
|
time: string;
|
||||||
|
version: string;
|
||||||
|
generatedFrom: string;
|
||||||
|
templates: SetupTemplateMetadataItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {
|
||||||
|
CsvPreviewError,
|
||||||
|
CsvPreviewFileResult,
|
||||||
|
CsvPreviewRow,
|
||||||
|
CsvPreviewResult,
|
||||||
|
CsvPreviewStatus,
|
||||||
|
CsvPreviewWarning
|
||||||
|
} from '@/features/setup/server/csv/types';
|
||||||
|
|
||||||
|
export type {
|
||||||
|
ImportFileReport,
|
||||||
|
ImportReport,
|
||||||
|
ImportRowReport,
|
||||||
|
ImportStatus
|
||||||
|
} from '@/features/setup/server/csv/import-report';
|
||||||
|
|||||||
17
src/features/setup/api/use-csv-commit.ts
Normal file
17
src/features/setup/api/use-csv-commit.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useMutation } from '@tanstack/react-query';
|
||||||
|
import { commitSetupCsvFiles, previewSetupCsvFiles } from './service';
|
||||||
|
|
||||||
|
export function useCsvPreview() {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (files: File[]) => previewSetupCsvFiles(files)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCsvCommit() {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (input: { files: File[]; previewHash: string; dryRun?: boolean }) =>
|
||||||
|
commitSetupCsvFiles(input)
|
||||||
|
});
|
||||||
|
}
|
||||||
11
src/features/setup/api/use-setup-verification.ts
Normal file
11
src/features/setup/api/use-setup-verification.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useMutation } from '@tanstack/react-query';
|
||||||
|
import { verifySetup } from './service';
|
||||||
|
import type { SetupVerificationPayload } from './types';
|
||||||
|
|
||||||
|
export function useSetupVerification() {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (payload: SetupVerificationPayload = {}) => verifySetup(payload)
|
||||||
|
});
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user