@explorer02/cfm-survey-sdk 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/postinstall.js +5 -0
- package/templates/AGENT.md +4 -2
- package/templates/docs/00-integration/component-checklist.md +61 -0
- package/templates/docs/00-integration/constraints.md +17 -0
- package/templates/docs/01-components/01-survey-page.md +2 -0
- package/templates/docs/01-components/02-question.md +43 -56
- package/templates/docs/01-components/03-rating-scale.md +2 -0
- package/templates/docs/01-components/04-csat-scale.md +3 -1
- package/templates/docs/01-components/05-csat-matrix-scale.md +2 -0
- package/templates/docs/01-components/06-likert-matrix-scale.md +2 -0
- package/templates/docs/01-components/07-slider-matrix-scale.md +2 -0
- package/templates/docs/01-components/08-file-upload-scale.md +2 -0
- package/templates/docs/01-components/09-custom-slider-track.md +2 -0
- package/templates/docs/01-components/10-header-footer.md +3 -1
- package/templates/docs/01-components/11-progress-bar.md +2 -0
- package/templates/docs/01-components/12-language-selector.md +2 -0
- package/templates/docs/01-components/13-matrix-dropdown.md +2 -0
- package/templates/docs/01-components/README.md +4 -2
- package/templates/docs/02-reference/config-field-index.md +158 -0
- package/templates/docs/02-reference/routing-table.md +16 -16
- package/templates/docs/03-ui-specs/00-question-shell.md +102 -0
- package/templates/docs/03-ui-specs/01-rating.md +80 -0
- package/templates/docs/03-ui-specs/02-radio.md +57 -0
- package/templates/docs/03-ui-specs/03-text.md +51 -0
- package/templates/docs/03-ui-specs/04-csat.md +57 -0
- package/templates/docs/03-ui-specs/05-rating-scale.md +49 -0
- package/templates/docs/03-ui-specs/06-slider.md +42 -0
- package/templates/docs/03-ui-specs/07-matrix-cfm.md +66 -0
- package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +65 -0
- package/templates/docs/03-ui-specs/09-slider-matrix.md +61 -0
- package/templates/docs/03-ui-specs/10-file-upload.md +54 -0
- package/templates/docs/03-ui-specs/11-text-and-media.md +49 -0
- package/templates/docs/03-ui-specs/12-survey-chrome.md +60 -0
- package/templates/docs/03-ui-specs/README.md +80 -0
- package/templates/docs/03-ui-specs/shared/custom-slider-track.md +52 -0
- package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +38 -0
- package/templates/docs/MANIFEST.json +27 -1
- package/templates/docs/index.md +28 -13
- package/templates/docs/templates/Question.tsx +243 -0
- package/templates/docs/templates/implementation_plan.md +40 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# UI Spec: File Upload (`type: 'file_upload'`)
|
|
2
|
+
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/FileUploadScale.tsx`
|
|
4
|
+
> **SDK type:** `FileUploadQuestion` — `fetchSurvey/types/fileUpload.ts`
|
|
5
|
+
> **Component blueprint:** `01-components/08-file-upload-scale.md`
|
|
6
|
+
|
|
7
|
+
## Config Inventory
|
|
8
|
+
|
|
9
|
+
| Field | Implemented | UI impact |
|
|
10
|
+
|-------|-------------|-----------|
|
|
11
|
+
| `uploadMessage` | ✅ | HTML in dropzone (bold 16px) |
|
|
12
|
+
| `supportedFileFormats` | ✅ | Validation + accept attribute |
|
|
13
|
+
| `maxFileCount` | ✅ | Total file limit |
|
|
14
|
+
| `fileSizeLimit` | ✅ | MB limit |
|
|
15
|
+
| `fileSizeLimitType` | ✅ | `PER_FILE` or `IN_TOTAL` |
|
|
16
|
+
|
|
17
|
+
## Layout Anatomy
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
[uploadMessage HTML in dashed dropzone]
|
|
21
|
+
File limit: N; File size limit: XMB/file|in total; Supports: ...
|
|
22
|
+
[local error banner — red if validation fails]
|
|
23
|
+
[file list cards: icon, name, size, remove ×]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Interactive States
|
|
27
|
+
|
|
28
|
+
| State | Border | Background |
|
|
29
|
+
|-------|--------|------------|
|
|
30
|
+
| Default | `#d1d5db` dashed | `#f9fafb` |
|
|
31
|
+
| Hover | `#e20074` | `#fdf2f8` |
|
|
32
|
+
| Drag active | `#e20074` | `#fdf2f8` |
|
|
33
|
+
|
|
34
|
+
## Local Validation (before SDK)
|
|
35
|
+
|
|
36
|
+
1. Max file count exceeded
|
|
37
|
+
2. Unsupported extension
|
|
38
|
+
3. PER_FILE size exceeded
|
|
39
|
+
4. IN_TOTAL cumulative size exceeded
|
|
40
|
+
|
|
41
|
+
Error banner: `#fee2e2` bg, `#b91c1c` text.
|
|
42
|
+
|
|
43
|
+
## Answer Mutation
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
onSelect(File[] | undefined) // undefined when all removed
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Agent Checklist
|
|
50
|
+
|
|
51
|
+
- [ ] Hidden `<input type="file">` triggered by dropzone click
|
|
52
|
+
- [ ] Drag enter/over/leave/drop handlers
|
|
53
|
+
- [ ] Dynamic constraints line in dropzone
|
|
54
|
+
- [ ] File list with remove button (hover red)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# UI Spec: Text and Media (`type: 'text_and_media'`)
|
|
2
|
+
|
|
3
|
+
> **Reference:** `apps/client/src/components/Question.tsx` (inline)
|
|
4
|
+
> **SDK type:** `TextAndMediaQuestion` — `fetchSurvey/types/textAndMedia.ts`
|
|
5
|
+
> **Component blueprint:** `01-components/02-question.md`
|
|
6
|
+
|
|
7
|
+
## Config Inventory
|
|
8
|
+
|
|
9
|
+
| Field | Implemented | UI impact |
|
|
10
|
+
|-------|-------------|-----------|
|
|
11
|
+
| `mediaUrl` | ✅ | Required to render media block |
|
|
12
|
+
| `mediaMimeType` | ✅ | `video/` or `VIDEO` → `<video>`; else `<img>` |
|
|
13
|
+
| `mediaTitle` | ✅ | Caption below media, centered gray text |
|
|
14
|
+
| `mediaAlignment` | ✅ | Flex justify: CENTER / RIGHT / default left |
|
|
15
|
+
| `mediaSize` | ✅ | Width `%` on media container; default 100% |
|
|
16
|
+
|
|
17
|
+
No answer input — display-only question.
|
|
18
|
+
|
|
19
|
+
## Layout Anatomy
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
[question title + description — standard shell]
|
|
23
|
+
|
|
24
|
+
┌─ flex container (justify per mediaAlignment) ──────────────┐
|
|
25
|
+
│ ┌─ media block (width: mediaSize%) ──────────────────┐ │
|
|
26
|
+
│ │ <video controls> or <img> │ │
|
|
27
|
+
│ │ [optional mediaTitle caption] │ │
|
|
28
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
29
|
+
└────────────────────────────────────────────────────────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Alignment Mapping
|
|
33
|
+
|
|
34
|
+
| `mediaAlignment` | CSS |
|
|
35
|
+
|------------------|-----|
|
|
36
|
+
| `TOP_CENTER`, `BOTTOM_CENTER` | `justify-center` |
|
|
37
|
+
| `TOP_RIGHT`, `BOTTOM_RIGHT` | `justify-end` |
|
|
38
|
+
| default | `justify-start` |
|
|
39
|
+
|
|
40
|
+
## Answer Mutation
|
|
41
|
+
|
|
42
|
+
None — no `onSelect` payload for this type.
|
|
43
|
+
|
|
44
|
+
## Agent Checklist
|
|
45
|
+
|
|
46
|
+
- [ ] Render only when `mediaUrl` is present
|
|
47
|
+
- [ ] Video vs image from mime type
|
|
48
|
+
- [ ] `max-w-full rounded-md shadow-sm` on media element
|
|
49
|
+
- [ ] Optional centered caption for `mediaTitle`
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# UI Spec: Survey Chrome
|
|
2
|
+
|
|
3
|
+
> **Reference:** `SurveyPage.tsx`, `Header.tsx`, `Footer.tsx`, `ProgressBar.tsx`, `LanguageSelector.tsx`
|
|
4
|
+
> **Component blueprints:** `01-components/01-survey-page.md`, `10-header-footer.md`, `11-progress-bar.md`, `12-language-selector.md`
|
|
5
|
+
|
|
6
|
+
## SurveyPage — 5-State Machine
|
|
7
|
+
|
|
8
|
+
| State | Condition | UI |
|
|
9
|
+
|-------|-----------|-----|
|
|
10
|
+
| Loading | `surveyQueryResults.isLoading` | Centered "Loading..." |
|
|
11
|
+
| Error | `surveyQueryResults.error` | Red error message |
|
|
12
|
+
| Empty | `!survey` | "No survey data" |
|
|
13
|
+
| Submitted | `submitSurveyResults.data` | Thank you message |
|
|
14
|
+
| Active | else | Questions + nav |
|
|
15
|
+
|
|
16
|
+
## Active Layout
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Header
|
|
20
|
+
main (max-w-4xl)
|
|
21
|
+
ProgressBar(progressPercentage)
|
|
22
|
+
LanguageSelector (hidden if ≤1 language)
|
|
23
|
+
Questions (space-y-12)
|
|
24
|
+
Submit error (if any)
|
|
25
|
+
Nav: Back (if page > 0) + Next/Submit
|
|
26
|
+
Footer
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Navigation Labels
|
|
30
|
+
|
|
31
|
+
German when `survey.language.startsWith('de')`:
|
|
32
|
+
|
|
33
|
+
| Action | EN | DE |
|
|
34
|
+
|--------|----|----|
|
|
35
|
+
| Back | Zurück | Back |
|
|
36
|
+
| Next | Weiter | Next |
|
|
37
|
+
| Submit | Absenden | Submit |
|
|
38
|
+
| Submitting | Wird gesendet... | Submitting... |
|
|
39
|
+
|
|
40
|
+
## Button Tokens
|
|
41
|
+
|
|
42
|
+
- Back: `border-[#e20074] text-[#e20074] hover:bg-[#fdf2f8]`
|
|
43
|
+
- Primary: `bg-[#e20074] text-white hover:opacity-90`
|
|
44
|
+
|
|
45
|
+
## ProgressBar
|
|
46
|
+
|
|
47
|
+
Pink fill bar, `300ms` width transition on `progressPercentage`.
|
|
48
|
+
|
|
49
|
+
## LanguageSelector
|
|
50
|
+
|
|
51
|
+
- Hidden when `languages.length <= 1`
|
|
52
|
+
- Focus ring: `#2563eb`
|
|
53
|
+
|
|
54
|
+
## Agent Checklist
|
|
55
|
+
|
|
56
|
+
- [ ] All 5 states implemented
|
|
57
|
+
- [ ] `onAction({ type: 'CHANGE' })` wired per question
|
|
58
|
+
- [ ] PREVIOUS / NEXT actions on nav buttons
|
|
59
|
+
- [ ] ProgressBar receives `state.progressPercentage`
|
|
60
|
+
- [ ] Header/Footer on every state branch
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# UI Specifications — Reference Implementation Guide
|
|
2
|
+
|
|
3
|
+
> **For npm installs:** implement from these specs + [`templates/Question.tsx`](../templates/Question.tsx). The monorepo path `apps/client/src/components/` is **not** available in client projects.
|
|
4
|
+
> **For monorepo devs:** cross-check against [`apps/client/src/components/`](../../../../../../apps/client/src/components/).
|
|
5
|
+
> Read the spec for **each question type present** in the fetched survey before writing React code.
|
|
6
|
+
|
|
7
|
+
## How to Read a UI Spec
|
|
8
|
+
|
|
9
|
+
Each file in this folder follows the same structure:
|
|
10
|
+
|
|
11
|
+
1. **Config inventory** — every SDK field, whether the reference client implements it
|
|
12
|
+
2. **Layout anatomy** — structured ASCII diagram
|
|
13
|
+
3. **Config decision tree** — matches `if/else` branches in reference code
|
|
14
|
+
4. **Interactive states** — default, hover, selected, disabled, focus
|
|
15
|
+
5. **Tooltips & labels** — positioning formulas
|
|
16
|
+
6. **Color tokens** — exact hex values from reference client
|
|
17
|
+
7. **Answer mutation** — `onSelect` / `onAction CHANGE` shape
|
|
18
|
+
8. **Agent checklist**
|
|
19
|
+
|
|
20
|
+
## Design Tokens (Reference Client)
|
|
21
|
+
|
|
22
|
+
| Token | Value | Usage |
|
|
23
|
+
|-------|-------|-------|
|
|
24
|
+
| Primary | `#e20074` | Borders, rings, dots, slider fill, selected text |
|
|
25
|
+
| Selected bg | `#fdf2f8` | Card options, CSAT buttons, matrix cells |
|
|
26
|
+
| NPS track highlight | `#fbe8f3` | Selected radio cell in NPS track row |
|
|
27
|
+
| NPS track bar | `#f2f2f2` | Gray bar behind NPS radios |
|
|
28
|
+
| Validation border | `#333333` | Error banner |
|
|
29
|
+
| Validation bg | `#d9d9d9` | Error banner |
|
|
30
|
+
| Row band | `#f3f4f6` | Slider matrix row background |
|
|
31
|
+
| Zebra row | `rgba(249,250,251,0.8)` | Matrix alternating rows |
|
|
32
|
+
| Tooltip bg | `#1f2937` | Hover tooltips on emoji/slider |
|
|
33
|
+
| Likert carousel dot (active) | `#2563eb` | LikertMatrix carousel only |
|
|
34
|
+
| CSAT carousel dot (active) | `#e20074` | CsatMatrix carousel |
|
|
35
|
+
|
|
36
|
+
## Reference Component Index
|
|
37
|
+
|
|
38
|
+
| Spec file | Reference component | `question.type` |
|
|
39
|
+
|-----------|---------------------|-----------------|
|
|
40
|
+
| [00-question-shell.md](00-question-shell.md) | `Question.tsx` | All (wrapper) |
|
|
41
|
+
| [01-rating.md](01-rating.md) | `RatingScale.tsx` | `rating` |
|
|
42
|
+
| [02-radio.md](02-radio.md) | `Question.tsx` inline | `radio` |
|
|
43
|
+
| [03-text.md](03-text.md) | `Question.tsx` inline | `text` |
|
|
44
|
+
| [04-csat.md](04-csat.md) | `CsatScale.tsx` | `csat` |
|
|
45
|
+
| [05-rating-scale.md](05-rating-scale.md) | *(gap — reuse CsatScale patterns)* | `rating_scale` |
|
|
46
|
+
| [06-slider.md](06-slider.md) | *(gap — reuse CustomSliderTrack)* | `slider` |
|
|
47
|
+
| [07-matrix-cfm.md](07-matrix-cfm.md) | `LikertMatrixScale.tsx` | `matrix` + CFM |
|
|
48
|
+
| [08-matrix-csat-rating.md](08-matrix-csat-rating.md) | `CsatMatrixScale.tsx` | CSAT/RATING matrix |
|
|
49
|
+
| [09-slider-matrix.md](09-slider-matrix.md) | `SliderMatrixScale.tsx` | `slider_matrix` |
|
|
50
|
+
| [10-file-upload.md](10-file-upload.md) | `FileUploadScale.tsx` | `file_upload` |
|
|
51
|
+
| [11-text-and-media.md](11-text-and-media.md) | `Question.tsx` inline | `text_and_media` |
|
|
52
|
+
| [12-survey-chrome.md](12-survey-chrome.md) | `SurveyPage.tsx` + chrome | Shell |
|
|
53
|
+
| [shared/custom-slider-track.md](shared/custom-slider-track.md) | `CustomSliderTrack.tsx` | Primitive |
|
|
54
|
+
| [shared/matrix-dropdown.md](shared/matrix-dropdown.md) | `MatrixDropdown.tsx` | Primitive |
|
|
55
|
+
|
|
56
|
+
## NPS Traffic-Light Colors
|
|
57
|
+
|
|
58
|
+
Use `option.color` from SDK — never invent colors:
|
|
59
|
+
|
|
60
|
+
| Value | Hex |
|
|
61
|
+
|-------|-----|
|
|
62
|
+
| 0 | `#e2001a` |
|
|
63
|
+
| 1 | `#e4251b` |
|
|
64
|
+
| 2 | `#ec610a` |
|
|
65
|
+
| 3 | `#f18b00` |
|
|
66
|
+
| 4 | `#f7b200` |
|
|
67
|
+
| 5 | `#fcd900` |
|
|
68
|
+
| 6 | `#fcd900` |
|
|
69
|
+
| 7 | `#9fca00` |
|
|
70
|
+
| 8 | `#6bb300` |
|
|
71
|
+
| 9 | `#339a00` |
|
|
72
|
+
| 10 | `#008000` |
|
|
73
|
+
|
|
74
|
+
## When to Read
|
|
75
|
+
|
|
76
|
+
After Phase 3 in [`index.md`](../index.md), for each question in `state.currentQuestions`:
|
|
77
|
+
|
|
78
|
+
1. Read [`02-reference/question-types/`](../02-reference/question-types/) for data shape
|
|
79
|
+
2. Read matching spec from this folder (see [`MANIFEST.json`](../MANIFEST.json) `uiSpecs`)
|
|
80
|
+
3. Cross-check [`config-field-index.md`](../02-reference/config-field-index.md)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# UI Spec: Custom Slider Track (shared primitive)
|
|
2
|
+
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/CustomSliderTrack.tsx`
|
|
4
|
+
> **Used by:** `SliderMatrixScale.tsx`, `CsatMatrixScale` (graphics), standalone `slider` (gap)
|
|
5
|
+
|
|
6
|
+
## Layer Architecture
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
1. Gray inactive track (#e5e7eb, 4px height)
|
|
10
|
+
2. Magenta fill bar (width = percentage%, #e20074 or #9ca3af if disabled)
|
|
11
|
+
3. Tick marks (1px × 8px at ticks positions)
|
|
12
|
+
4. Invisible <input type="range"> overlay (opacity 0, full hit area)
|
|
13
|
+
5. Visual thumb: circle OR emoji (sliderType === 'graphics')
|
|
14
|
+
6. Tooltip bubble on hover/drag (#1f2937 bg, rounded value)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
| Prop | Role |
|
|
20
|
+
|------|------|
|
|
21
|
+
| `min`, `max`, `htmlStep` | Range input bounds |
|
|
22
|
+
| `value` | Current position |
|
|
23
|
+
| `disabled` | Gray theme, opacity 0.5, no interaction |
|
|
24
|
+
| `displayValues` | Reserved — tooltip always shows on hover/drag in client |
|
|
25
|
+
| `hasSelectedValue` | Reserved |
|
|
26
|
+
| `sliderType: 'graphics'` | Emoji thumb via `getEmojiForIndex` |
|
|
27
|
+
| `ticks` | Discrete tick count + emoji index scale |
|
|
28
|
+
| `reverseScaleOrder` | Flip emoji index calculation |
|
|
29
|
+
|
|
30
|
+
## Interactive States
|
|
31
|
+
|
|
32
|
+
| State | Thumb | Tooltip |
|
|
33
|
+
|-------|-------|---------|
|
|
34
|
+
| Default | White circle, 2.5px magenta border | Hidden |
|
|
35
|
+
| Hover/drag | Pink glow ring `rgba(226,0,116,0.2)` | Dark bubble with `Math.round(value)` |
|
|
36
|
+
| Disabled | Gray border, opacity 0.5 | Hidden |
|
|
37
|
+
| Graphics | Emoji at percentage position | Same tooltip |
|
|
38
|
+
|
|
39
|
+
## Emoji Index Formula
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
const idx = Math.round(((value - min) / (max - min)) * ((ticks || 10) - 1));
|
|
43
|
+
const displayIdx = reverseScaleOrder ? (ticks || 10) - 1 - idx : idx;
|
|
44
|
+
getEmojiForIndex(displayIdx, ticks || 10)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Agent Checklist
|
|
48
|
+
|
|
49
|
+
- [ ] 4-layer overlay with invisible range input
|
|
50
|
+
- [ ] Tooltip on hover AND drag
|
|
51
|
+
- [ ] Graphics mode emoji thumb
|
|
52
|
+
- [ ] Transition disabled while dragging
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# UI Spec: Matrix Dropdown (shared primitive)
|
|
2
|
+
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/MatrixDropdown.tsx`
|
|
4
|
+
> **Used by:** `LikertMatrixScale`, `CsatMatrixScale` vertical list
|
|
5
|
+
|
|
6
|
+
## Modes
|
|
7
|
+
|
|
8
|
+
| `multiple` | Trigger | Selection |
|
|
9
|
+
|------------|---------|-----------|
|
|
10
|
+
| `false` | Single line + chevron | One value; checkmark on selected option |
|
|
11
|
+
| `true` | Tag chips with × | Toggle array; N/A mutex |
|
|
12
|
+
|
|
13
|
+
## Interactive States
|
|
14
|
+
|
|
15
|
+
| State | Trigger border | Shadow |
|
|
16
|
+
|-------|----------------|--------|
|
|
17
|
+
| Closed | `#d1d5db` | subtle |
|
|
18
|
+
| Open | `#e20074` | `0 0 0 3px rgba(226,0,116,0.1)` |
|
|
19
|
+
| Option hover | bg `#fdf2f8` | — |
|
|
20
|
+
| Option selected | bg `#fdf2f8`, text `#e20074` | — |
|
|
21
|
+
| N/A mutex (multi) | Other options opacity 0.5, disabled | — |
|
|
22
|
+
|
|
23
|
+
## N/A Mutex (multi-select)
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
if (val === null) {
|
|
27
|
+
if (multiValues.includes(null)) onChange([]);
|
|
28
|
+
else onChange([null]);
|
|
29
|
+
}
|
|
30
|
+
// When null selected, non-null options disabled
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Agent Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] Click-outside closes panel
|
|
36
|
+
- [ ] HTML labels via dangerouslySetInnerHTML
|
|
37
|
+
- [ ] Single: close on select
|
|
38
|
+
- [ ] Multi: tag chips removable with ×
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
"id": 4,
|
|
34
34
|
"name": "planAndIngest",
|
|
35
35
|
"read": [
|
|
36
|
+
"00-integration/component-checklist.md",
|
|
37
|
+
"03-ui-specs/README.md",
|
|
36
38
|
"01-components/README.md",
|
|
37
39
|
"01-components/01-survey-page.md",
|
|
38
40
|
"01-components/02-question.md",
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"01-components/13-matrix-dropdown.md"
|
|
50
52
|
],
|
|
51
53
|
"template": "templates/implementation_plan.md",
|
|
54
|
+
"questionDispatcher": "templates/Question.tsx",
|
|
52
55
|
"output": "implementation_plan.md"
|
|
53
56
|
},
|
|
54
57
|
{
|
|
@@ -63,6 +66,8 @@
|
|
|
63
66
|
"read": ["00-integration/constraints.md"],
|
|
64
67
|
"checklist": [
|
|
65
68
|
"questionDispatcherCoversAll12Types",
|
|
69
|
+
"matrixRoutesBySubType",
|
|
70
|
+
"noStubPlaceholderText",
|
|
66
71
|
"everyQuestionWrapperHasId",
|
|
67
72
|
"noInternalSdkImports",
|
|
68
73
|
"surveyPageFiveStates",
|
|
@@ -125,5 +130,26 @@
|
|
|
125
130
|
"component": "01-components/02-question.md",
|
|
126
131
|
"reference": "02-reference/question-types/README.md#text_and_media"
|
|
127
132
|
}
|
|
128
|
-
}
|
|
133
|
+
},
|
|
134
|
+
"uiSpecs": {
|
|
135
|
+
"questionShell": "03-ui-specs/00-question-shell.md",
|
|
136
|
+
"rating": "03-ui-specs/01-rating.md",
|
|
137
|
+
"radio": "03-ui-specs/02-radio.md",
|
|
138
|
+
"text": "03-ui-specs/03-text.md",
|
|
139
|
+
"csat": "03-ui-specs/04-csat.md",
|
|
140
|
+
"rating_scale": "03-ui-specs/05-rating-scale.md",
|
|
141
|
+
"slider": "03-ui-specs/06-slider.md",
|
|
142
|
+
"matrix_CFM_MATRIX": "03-ui-specs/07-matrix-cfm.md",
|
|
143
|
+
"matrix_CSAT_MATRIX": "03-ui-specs/08-matrix-csat-rating.md",
|
|
144
|
+
"matrix_RATING_MATRIX": "03-ui-specs/08-matrix-csat-rating.md",
|
|
145
|
+
"slider_matrix": "03-ui-specs/09-slider-matrix.md",
|
|
146
|
+
"file_upload": "03-ui-specs/10-file-upload.md",
|
|
147
|
+
"text_and_media": "03-ui-specs/11-text-and-media.md",
|
|
148
|
+
"surveyChrome": "03-ui-specs/12-survey-chrome.md"
|
|
149
|
+
},
|
|
150
|
+
"sharedUiSpecs": {
|
|
151
|
+
"customSliderTrack": "03-ui-specs/shared/custom-slider-track.md",
|
|
152
|
+
"matrixDropdown": "03-ui-specs/shared/matrix-dropdown.md"
|
|
153
|
+
},
|
|
154
|
+
"configFieldIndex": "02-reference/config-field-index.md"
|
|
129
155
|
}
|
package/templates/docs/index.md
CHANGED
|
@@ -11,10 +11,12 @@ docs/
|
|
|
11
11
|
├── index.md ← YOU ARE HERE
|
|
12
12
|
├── MANIFEST.json ← Phase + question-type routing (for tooling)
|
|
13
13
|
├── 00-integration/ ← Setup, hook contract, constraints
|
|
14
|
-
├── 01-components/ ←
|
|
15
|
-
├── 02-reference/ ← Routing table +
|
|
14
|
+
├── 01-components/ ← Wiring blueprints (read ALL before coding)
|
|
15
|
+
├── 02-reference/ ← Routing table + config-field-index (on demand)
|
|
16
|
+
├── 03-ui-specs/ ← Authoritative UI specs (reference-client driven)
|
|
16
17
|
└── templates/
|
|
17
|
-
|
|
18
|
+
├── implementation_plan.md
|
|
19
|
+
└── Question.tsx ← Canonical dispatcher (copy before building)
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
**Import rule:** Use whatever package name appears in the project's `package.json` (`@explorer02/cfm-survey-sdk` or `@repo/sdk`).
|
|
@@ -63,17 +65,26 @@ Optional: read `02-reference/routing-table.md` for type overview.
|
|
|
63
65
|
### PHASE 4: PLAN + INGEST (CRITICAL)
|
|
64
66
|
|
|
65
67
|
1. Read **every** file in `01-components/` (all 14 blueprints)
|
|
66
|
-
2.
|
|
67
|
-
3.
|
|
68
|
-
4. **
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
2. Read `00-integration/component-checklist.md` and `03-ui-specs/README.md`
|
|
69
|
+
3. **Inventory** every `(type, subType)` in `survey.pages` after instanceId fetch
|
|
70
|
+
4. For **each type in the survey**, read matching `03-ui-specs/` (use `MANIFEST.json` `uiSpecs`) and `02-reference/question-types/` — **blocking** for `matrix`, `slider_matrix`, `file_upload`
|
|
71
|
+
5. Copy `docs/templates/implementation_plan.md` → `./implementation_plan.md` and fill every section
|
|
72
|
+
6. Copy `docs/templates/Question.tsx` as the dispatcher starting point
|
|
73
|
+
7. **Auto-proceed to Phase 5** — do not wait for approval
|
|
71
74
|
|
|
72
75
|
### PHASE 5: BUILD
|
|
73
76
|
|
|
74
|
-
Read: `00-integration/constraints.md`
|
|
77
|
+
Read: `00-integration/constraints.md`, `00-integration/component-checklist.md`
|
|
78
|
+
|
|
79
|
+
Create all required scale component files **before** wiring `Question.tsx`. For each question in the survey:
|
|
80
|
+
|
|
81
|
+
1. Read `02-reference/question-types/{type}.md` for data shape
|
|
82
|
+
2. Read `03-ui-specs/{NN}-{type}.md` (use `MANIFEST.json` `uiSpecs`; split matrix by `subType`)
|
|
83
|
+
3. If `matrixFormat`, `buttonType`, or `sliderType` is present → read `03-ui-specs/shared/` specs
|
|
84
|
+
4. Cross-check `02-reference/config-field-index.md` for every non-default field
|
|
85
|
+
5. Implement per ui-spec — monorepo devs may consult `apps/client/src/components/`; npm installs use ui-specs only
|
|
75
86
|
|
|
76
|
-
Implement components per blueprints. Use exported types:
|
|
87
|
+
Implement components per blueprints + UI specs. Use exported types:
|
|
77
88
|
|
|
78
89
|
```typescript
|
|
79
90
|
import { useSurveySDK, ACTIONS, type SurveyAction } from '@explorer02/cfm-survey-sdk';
|
|
@@ -85,7 +96,10 @@ Read: `00-integration/constraints.md` (troubleshooting)
|
|
|
85
96
|
|
|
86
97
|
Checklist:
|
|
87
98
|
|
|
88
|
-
- [ ] `Question.tsx`
|
|
99
|
+
- [ ] `Question.tsx` copied from `docs/templates/Question.tsx` — covers all 12 `question.type` values
|
|
100
|
+
- [ ] Matrix routes by `subType` (`CFM_MATRIX` vs `CSAT_MATRIX` / `RATING_MATRIX`)
|
|
101
|
+
- [ ] All scale components from `component-checklist.md` exist for types in survey
|
|
102
|
+
- [ ] **Zero stub text:** `grep -r "not yet implemented" src/ components/ app/` returns no matches
|
|
89
103
|
- [ ] Every question wrapper has `id={question.id}`
|
|
90
104
|
- [ ] No imports from `@explorer02/cfm-survey-sdk/src/...`
|
|
91
105
|
- [ ] `SurveyPage` handles loading / error / empty / submitted / active
|
|
@@ -104,6 +118,7 @@ If yes: `npx cfm-sdk deploy` (preferred) or `npx vercel --prod --yes`
|
|
|
104
118
|
| When | Read |
|
|
105
119
|
|------|------|
|
|
106
120
|
| Always first | `index.md`, `00-integration/setup.md`, `00-integration/useSurveySDK.md`, `00-integration/constraints.md` |
|
|
107
|
-
| Before any React code | All `01-components/*.md` |
|
|
108
|
-
|
|
|
121
|
+
| Before any React code | All `01-components/*.md`, `00-integration/component-checklist.md`, `templates/Question.tsx` |
|
|
122
|
+
| After instanceId fetch | `03-ui-specs/` per type in survey (blocking for matrix / slider_matrix / file_upload) |
|
|
123
|
+
| Config audit | `02-reference/config-field-index.md` |
|
|
109
124
|
| Tooling | `MANIFEST.json`, `templates/implementation_plan.md` |
|