@explorer02/cfm-survey-sdk 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/index.d.mts +24 -26
  2. package/dist/index.d.ts +24 -26
  3. package/dist/index.js +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/package.json +2 -2
  6. package/postinstall.js +21 -26
  7. package/templates/AGENT.md +24 -10
  8. package/templates/docs/00-integration/constraints.md +54 -0
  9. package/templates/docs/00-integration/setup.md +80 -0
  10. package/templates/docs/00-integration/useSurveySDK.md +107 -0
  11. package/templates/docs/01-components/01-survey-page.md +91 -0
  12. package/templates/docs/01-components/02-question.md +105 -0
  13. package/templates/docs/01-components/08-file-upload-scale.md +56 -0
  14. package/templates/docs/{03-client-components → 01-components}/README.md +1 -1
  15. package/templates/docs/02-question-types/01-rating.md +0 -8
  16. package/templates/docs/02-reference/question-types/01-rating.md +52 -0
  17. package/templates/docs/02-reference/question-types/README.md +71 -0
  18. package/templates/docs/02-reference/routing-table.md +37 -0
  19. package/templates/docs/MANIFEST.json +129 -0
  20. package/templates/docs/index.md +100 -140
  21. package/templates/docs/templates/implementation_plan.md +78 -0
  22. package/templates/docs/01-sdk-core/01-fetch-survey.md +0 -68
  23. package/templates/docs/01-sdk-core/02-survey-mapper.md +0 -85
  24. package/templates/docs/01-sdk-core/03-question-mappers.md +0 -114
  25. package/templates/docs/01-sdk-core/04-pagination.md +0 -72
  26. package/templates/docs/01-sdk-core/05-validation.md +0 -66
  27. package/templates/docs/01-sdk-core/06-submit-survey.md +0 -90
  28. package/templates/docs/01-sdk-core/07-language-handling.md +0 -111
  29. package/templates/docs/01-sdk-core/08-icons-and-emojis.md +0 -56
  30. package/templates/docs/01-sdk-core/README.md +0 -53
  31. package/templates/docs/02-question-types/02-radio.md +0 -26
  32. package/templates/docs/02-question-types/03-text.md +0 -26
  33. package/templates/docs/02-question-types/12-text-and-media.md +0 -35
  34. package/templates/docs/02-question-types/README.md +0 -74
  35. package/templates/docs/03-client-components/01-survey-page.md +0 -113
  36. package/templates/docs/03-client-components/02-question.md +0 -74
  37. package/templates/docs/03-client-components/08-file-upload-scale.md +0 -37
  38. package/templates/docs/04-critical-rules/01-import-rules.md +0 -51
  39. package/templates/docs/04-critical-rules/02-action-dispatching.md +0 -56
  40. package/templates/docs/04-critical-rules/03-scroll-navigation.md +0 -37
  41. package/templates/docs/04-critical-rules/04-logo-branding.md +0 -42
  42. package/templates/docs/04-critical-rules/05-troubleshooting.md +0 -46
  43. package/templates/docs/04-critical-rules/README.md +0 -29
  44. /package/templates/docs/{03-client-components → 01-components}/03-rating-scale.md +0 -0
  45. /package/templates/docs/{03-client-components → 01-components}/04-csat-scale.md +0 -0
  46. /package/templates/docs/{03-client-components → 01-components}/05-csat-matrix-scale.md +0 -0
  47. /package/templates/docs/{03-client-components → 01-components}/06-likert-matrix-scale.md +0 -0
  48. /package/templates/docs/{03-client-components → 01-components}/07-slider-matrix-scale.md +0 -0
  49. /package/templates/docs/{03-client-components → 01-components}/09-custom-slider-track.md +0 -0
  50. /package/templates/docs/{03-client-components → 01-components}/10-header-footer.md +0 -0
  51. /package/templates/docs/{03-client-components → 01-components}/11-progress-bar.md +0 -0
  52. /package/templates/docs/{03-client-components → 01-components}/12-language-selector.md +0 -0
  53. /package/templates/docs/{03-client-components → 01-components}/13-matrix-dropdown.md +0 -0
  54. /package/templates/docs/{02-question-types → 02-reference/question-types}/04-csat.md +0 -0
  55. /package/templates/docs/{02-question-types → 02-reference/question-types}/05-rating-scale.md +0 -0
  56. /package/templates/docs/{02-question-types → 02-reference/question-types}/06-slider.md +0 -0
  57. /package/templates/docs/{02-question-types → 02-reference/question-types}/07-matrix-cfm.md +0 -0
  58. /package/templates/docs/{02-question-types → 02-reference/question-types}/08-matrix-csat.md +0 -0
  59. /package/templates/docs/{02-question-types → 02-reference/question-types}/09-matrix-rating.md +0 -0
  60. /package/templates/docs/{02-question-types → 02-reference/question-types}/10-slider-matrix.md +0 -0
  61. /package/templates/docs/{02-question-types → 02-reference/question-types}/11-file-upload.md +0 -0
@@ -1,149 +1,109 @@
1
1
  # CFM SURVEY SDK — AGENT DOCUMENTATION INDEX
2
2
 
3
- **@explorer02/cfm-survey-sdk**
3
+ **@explorer02/cfm-survey-sdk** (npm) · **@repo/sdk** (monorepo)
4
4
 
5
- This file is the MASTER GUIDE for AI coding agents (Cursor, Copilot, etc.).
6
- It is a structured roadmap that tells the agent exactly which documentation files to read and in what order.
5
+ Master guide for AI coding agents. Machine-readable index: `MANIFEST.json`.
7
6
 
8
- ## ── HOW THIS DOCUMENTATION SYSTEM WORKS ──────────────────────────────────────
9
-
10
- The `docs/` folder mirrors the SDK's internal architecture:
7
+ ## Documentation Layout
11
8
 
12
9
  ```
13
10
  docs/
14
- ├── index.md ← YOU ARE HERE — read this first
15
- ├── 01-sdk-core/ SDK internals: fetch, map, paginate, validate, submit
16
- ├── 02-question-types/ ← One doc per question type (12 types)
17
- ├── 03-client-components/ One doc per UI component (13 components)
18
- └── 04-critical-rules/ Non-negotiable constraints, imports, troubleshooting
11
+ ├── index.md ← YOU ARE HERE
12
+ ├── MANIFEST.json Phase + question-type routing (for tooling)
13
+ ├── 00-integration/ ← Setup, hook contract, constraints
14
+ ├── 01-components/ UI blueprints (read ALL before coding)
15
+ ├── 02-reference/ Routing table + question-type data (on demand)
16
+ └── templates/
17
+ └── implementation_plan.md
19
18
  ```
20
19
 
21
- ## ── CLIENT INTERACTION FLOW (3 INPUTS ONLY) ──────────────────────────────────
22
-
23
- The entire build process requires EXACTLY 3 inputs from the client:
24
-
25
- **INPUT 1: Client's initial prompt**
26
- → "Build a survey like this image using @explorer02/cfm-survey-sdk"
27
- May include UI mockup screenshots, brand colors, or text description
28
- Agent begins project scaffolding and component architecture
29
-
30
- **INPUT 2: Instance ID (agent asks for it)**
31
- Agent asks: "Please provide your survey instance ID (JWT token)"
32
- → Client pastes the instanceId string
33
- → Agent wires it into SurveyPage.tsx and fetches the survey
34
-
35
- **INPUT 3: Deployment confirmation (agent asks at the end)**
36
- → Agent asks: "Your survey is built and tested. Ready to deploy to Vercel?"
37
- Client confirms → Agent runs `npx vercel --prod --yes`
38
-
39
- ## ── EXECUTION PIPELINE ───────────────────────────────────────────────────────
40
-
41
- Follow these phases IN ORDER. Each phase references specific doc files.
42
-
43
- ### PHASE 1: PROJECT SCAFFOLDING
44
- Read: `04-critical-rules/01-import-rules.md`
45
-
46
- Actions:
47
- 1. Create Next.js project:
48
- `npx -y create-next-app@latest ./ --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`
49
- 2. Install SDK:
50
- `npm install @explorer02/cfm-survey-sdk @tanstack/react-query`
51
- 3. Configure `next.config.js`:
52
- `transpilePackages: ["@explorer02/cfm-survey-sdk"]`
53
-
54
- ### PHASE 2: ASK FOR INSTANCE ID (INPUT 2)
55
- Read: `01-sdk-core/01-fetch-survey.md`
56
-
57
- Ask the client in chat:
58
- "Please provide your survey instance ID (the JWT token string) so I can connect your survey."
59
-
60
- Wait for the client to paste the instanceId. Store it you will wire it into SurveyPage.tsx in Phase 4.
61
-
62
- ### PHASE 3: UNDERSTAND THE SDK PIPELINE
63
- Read these docs IN ORDER to understand how the SDK works:
64
-
65
- 1. `01-sdk-core/01-fetch-survey.md` — How survey data is fetched
66
- 2. `01-sdk-core/02-survey-mapper.md` — How raw API → Survey object
67
- 3. `01-sdk-core/03-question-mappers.md` How questions are typed/mapped
68
- 4. `01-sdk-core/07-language-handling.md`Translations & placeholders
69
- 5. `01-sdk-core/04-pagination.md` Page navigation state
70
- 6. `01-sdk-core/05-validation.md` — Required field validation
71
- 7. `01-sdk-core/06-submit-survey.md` — Response submission format
72
- 8. `01-sdk-core/08-icons-and-emojis.md` — CSAT emoji/star icon system
73
-
74
- Then understand what question types exist:
75
- 9. `02-question-types/README.md` — Overview of all 12 types
76
-
77
- *You do NOT need to read every question type doc upfront. Read them ON DEMAND when you encounter each type during component building.*
78
-
79
- ### PHASE 4: UI ARCHITECTURE PLANNING (CRITICAL)
80
- Before writing any React code, you MUST enter Planning Mode and generate an `implementation_plan.md`.
81
-
82
- Read the component architectural blueprints IN ORDER:
83
- 1. `03-client-components/README.md` — File structure overview
84
- 2. `03-client-components/01-survey-page.md` — MAIN orchestrator
85
- 3. `03-client-components/02-question.md` Question dispatcher
86
- 4. `03-client-components/10-header-footer.md` — CSS-built logo/branding/themes
87
- 5. `03-client-components/11-progress-bar.md` — Progress indicator
88
- 6. `03-client-components/12-language-selector.md` — Language dropdown
89
-
90
- Then, for EACH question type present in the fetched survey, read its matching UI Blueprint:
91
- - **Rating**: `03-client-components/03-rating-scale.md`
92
- - **CSAT**: `03-client-components/04-csat-scale.md`
93
- - **CSAT Matrix**: `03-client-components/05-csat-matrix-scale.md`
94
- - **Likert Matrix**: `03-client-components/06-likert-matrix-scale.md`
95
- - **Slider Matrix**: `03-client-components/07-slider-matrix-scale.md`
96
- - **File Upload**: `03-client-components/08-file-upload-scale.md`
97
- - **Sliders**: `03-client-components/09-custom-slider-track.md`
98
-
99
- Your `implementation_plan.md` MUST be structured professionally and precisely cover:
100
- 1. **Data Fetching & State**: How you will integrate `useSurveySDK(instanceId)` and handle loading/errors.
101
- 2. **Pagination & Navigation**: How you will iterate through pages, manage `handleNext`, `handleBack`, `handleAction`, and progress tracking.
102
- 3. **Question Dispatching**: How `Question.tsx` will route types and handle rich text rendering safely.
103
- 4. **Question Architectures & Configs**: How you will implement complex UI exactly as prescribed (e.g., matrix transposition, slider invisible overlays, CSAT bounding boxes, file size constraints).
104
- 5. **Theme & Logo Engineering**: How you will map the mockups to CSS-only logos and Tailwind themes.
105
- 6. **Submission**: How you will trigger `submitSurvey` and route to the Thank You screen.
106
-
107
- **ACTION**: Generate the `implementation_plan.md`. Once the plan is written, **DO NOT WAIT FOR APPROVAL**. Automatically trigger Phase 5 and begin writing the React components immediately!
108
-
109
- Then for EACH question type present in the fetched survey, read the matching question-type doc AND component doc:
110
-
111
- | `question.type` | Question Doc | Component Doc |
112
- |---|---|---|
113
- | `'rating'` | `02-question-types/01-rating` | `03-components/03-rating` |
114
- | `'radio'` | `02-question-types/02-radio` | (inline in Question) |
115
- | `'text'` | `02-question-types/03-text` | (inline in Question) |
116
- | `'csat'` | `02-question-types/04-csat` | `03-components/04-csat` |
117
- | `'rating_scale'` | `02-question-types/05-rating-s` | `03-components/03-rating` |
118
- | `'slider'` | `02-question-types/06-slider` | `03-components/09-slider` |
119
- | `'matrix'` CFM | `02-question-types/07-matrix-c` | `03-components/06-likert` |
120
- | `'matrix'` CSAT | `02-question-types/08-matrix-c` | `03-components/05-csat-m` |
121
- | `'matrix'` RATING| `02-question-types/09-matrix-r` | `03-components/05-csat-m` |
122
- | `'slider_matrix'`| `02-question-types/10-slider-m` | `03-components/07-slider` |
123
- | `'file_upload'` | `02-question-types/11-file-up` | `03-components/08-file` |
124
- | `'text_and_media'`| `02-question-types/12-text-med` | (inline in Question) |
125
-
126
- Also read these shared component docs:
127
- - `03-client-components/09-custom-slider-track.md` (used by CSAT matrix, slider matrix when sliderType='graphics')
128
- - `03-client-components/13-matrix-dropdown.md` (used by matrix dropdown fmt)
129
-
130
- ### PHASE 5: APPLY CRITICAL RULES
131
- Read ALL files in `04-critical-rules/`:
132
- 1. `01-import-rules.md` — Package imports, 'use client', Suspense
133
- 2. `02-action-dispatching.md` — onAction pattern, placeholder constants
134
- 3. `03-scroll-navigation.md` — id={question.id} requirement
135
- 4. `04-logo-branding.md` — CSS-only logo, no external image needed
136
- 5. `05-troubleshooting.md` — Common build errors and fixes
137
-
138
- Verify your implementation against every rule before proceeding.
139
-
140
- ### PHASE 6: BUILD VERIFICATION
141
- 1. Run: `npm run build`
142
- 2. If errors → fix automatically → re-run until clean
143
- 3. Run: `npm run dev`
144
- 4. Verify: survey loads, navigation works, validation fires, submit works
145
-
146
- ### PHASE 7: DEPLOYMENT (INPUT 3)
147
- Ask the client: "Your survey is built and verified. Ready to deploy to Vercel?"
148
- If yes → run: `npx vercel --prod --yes`
149
- Report the final deployment URL to the client.
20
+ **Import rule:** Use whatever package name appears in the project's `package.json` (`@explorer02/cfm-survey-sdk` or `@repo/sdk`).
21
+
22
+ ---
23
+
24
+ ## Client Inputs (3 only)
25
+
26
+ 1. **Initial prompt** mockup, brand colors, layout preferences
27
+ 2. **Instance ID** JWT token (agent asks in chat)
28
+ 3. **Deploy confirmation** — yes/no for production deploy
29
+
30
+ **Branding comes from INPUT 1 only.** No setup wizard. No `survey-config.json`.
31
+
32
+ ---
33
+
34
+ ## Execution Pipeline
35
+
36
+ ### PHASE 0: ORIENT
37
+
38
+ - Read this file and `AGENT.md`
39
+ - Detect framework: read `package.json` — Next.js / Vite / CRA (see `00-integration/setup.md`)
40
+ - Extract branding and layout from client prompt
41
+ - For existing apps: read project structure; do not blindly scaffold
42
+
43
+ ### PHASE 1: SCAFFOLD
44
+
45
+ Read: `00-integration/setup.md` (matching framework section)
46
+
47
+ Install SDK + `@tanstack/react-query` + `react-icons`. Apply framework-specific config.
48
+
49
+ ### PHASE 2: INSTANCE ID (INPUT 2)
50
+
51
+ Read: `00-integration/useSurveySDK.md`
52
+
53
+ Ask: *"Please provide your survey instance ID (JWT token)."*
54
+
55
+ ### PHASE 3: SDK CONTRACT
56
+
57
+ Read: `00-integration/useSurveySDK.md`
58
+
59
+ Understand `useSurveySDK`, `onAction`, states. Do **not** read internal mapper/source paths.
60
+
61
+ Optional: read `02-reference/routing-table.md` for type overview.
62
+
63
+ ### PHASE 4: PLAN + INGEST (CRITICAL)
64
+
65
+ 1. Read **every** file in `01-components/` (all 14 blueprints)
66
+ 2. Copy `docs/templates/implementation_plan.md` `./implementation_plan.md`
67
+ 3. Fill every section do **not** invent a different structure
68
+ 4. **Auto-proceed to Phase 5** do not wait for approval
69
+
70
+ For each question type in the fetched survey, also read matching docs from `02-reference/question-types/` (see `MANIFEST.json` or `02-reference/routing-table.md`).
71
+
72
+ ### PHASE 5: BUILD
73
+
74
+ Read: `00-integration/constraints.md`
75
+
76
+ Implement components per blueprints. Use exported types:
77
+
78
+ ```typescript
79
+ import { useSurveySDK, ACTIONS, type SurveyAction } from '@explorer02/cfm-survey-sdk';
80
+ ```
81
+
82
+ ### PHASE 6: VERIFY
83
+
84
+ Read: `00-integration/constraints.md` (troubleshooting)
85
+
86
+ Checklist:
87
+
88
+ - [ ] `Question.tsx` switch covers all 12 `question.type` values
89
+ - [ ] Every question wrapper has `id={question.id}`
90
+ - [ ] No imports from `@explorer02/cfm-survey-sdk/src/...`
91
+ - [ ] `SurveyPage` handles loading / error / empty / submitted / active
92
+ - [ ] `npm run build` exits 0
93
+
94
+ ### PHASE 7: DEPLOY (INPUT 3)
95
+
96
+ Ask: *"Your survey is built and verified. Ready to deploy?"*
97
+
98
+ If yes: `npx cfm-sdk deploy` (preferred) or `npx vercel --prod --yes`
99
+
100
+ ---
101
+
102
+ ## Progressive Reading Guide
103
+
104
+ | When | Read |
105
+ |------|------|
106
+ | 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
+ | On demand | `02-reference/question-types/<type>.md` for types in survey |
109
+ | Tooling | `MANIFEST.json`, `templates/implementation_plan.md` |
@@ -0,0 +1,78 @@
1
+ # Survey UI Implementation Plan
2
+
3
+ > Copy this file to `./implementation_plan.md` in the project root. Fill every section before writing React code.
4
+
5
+ ## 0. Project Context
6
+
7
+ - **Framework:** [ ] Next.js App Router [ ] Vite [ ] CRA [ ] Existing app
8
+ - **Package import name:** (from `package.json` — `@explorer02/cfm-survey-sdk` or `@repo/sdk`)
9
+ - **instanceId:** (JWT — wired in SurveyPage)
10
+ - **Branding source:** (client prompt / mockup description — no wizard)
11
+
12
+ ## 1. Data Fetching & State
13
+
14
+ - [ ] `useSurveySDK` options: instanceId, language, placeholders, debug
15
+ - [ ] `SurveyPage` 5-state machine: loading / error / empty / submitted / active
16
+ - [ ] `surveyQueryResults.isLoading`, `.error`, `.data` handling
17
+ - [ ] `submitSurveyResults.isLoading`, `.error`, `.data` handling
18
+
19
+ ## 2. Pagination, Actions & Flow
20
+
21
+ - [ ] `onAction` NEXT / PREVIOUS / SUBMIT wiring
22
+ - [ ] `ProgressBar` bound to `state.progressPercentage`
23
+ - [ ] Back/Next button visibility per layout config
24
+ - [ ] Last-page NEXT → auto SUBMIT behavior
25
+
26
+ ## 3. Question Dispatching (`Question.tsx`)
27
+
28
+ Exhaustive switch — check each:
29
+
30
+ - [ ] `rating` → `RatingScale`
31
+ - [ ] `csat` → `CsatScale`
32
+ - [ ] `radio` → inline MCQ
33
+ - [ ] `text` → inline textarea/input
34
+ - [ ] `rating_scale` → `RatingScale` (star/emoji)
35
+ - [ ] `slider` → `CustomSliderTrack`
36
+ - [ ] `matrix` + `CFM_MATRIX` → `LikertMatrixScale`
37
+ - [ ] `matrix` + `CSAT_MATRIX` / `RATING_MATRIX` → `CsatMatrixScale`
38
+ - [ ] `rating_matrix` → `CsatMatrixScale`
39
+ - [ ] `slider_matrix` → `SliderMatrixScale`
40
+ - [ ] `file_upload` → `FileUploadScale`
41
+ - [ ] `text_and_media` → inline media (no scale)
42
+ - [ ] `dangerouslySetInnerHTML` for `question.text` / `description`
43
+ - [ ] `validationError` banner per question
44
+ - [ ] `id={question.id}` on every question wrapper
45
+
46
+ ## 4. Component Architecture Checklist
47
+
48
+ | Component | In survey? | Blueprint doc | Key constraints verified |
49
+ |-----------|------------|---------------|--------------------------|
50
+ | RatingScale | | `01-components/03-rating-scale.md` | |
51
+ | CsatScale | | `01-components/04-csat-scale.md` | |
52
+ | CsatMatrixScale | | `01-components/05-csat-matrix-scale.md` | |
53
+ | LikertMatrixScale | | `01-components/06-likert-matrix-scale.md` | |
54
+ | SliderMatrixScale | | `01-components/07-slider-matrix-scale.md` | |
55
+ | FileUploadScale | | `01-components/08-file-upload-scale.md` | |
56
+ | CustomSliderTrack | | `01-components/09-custom-slider-track.md` | |
57
+ | Header / Footer | | `01-components/10-header-footer.md` | |
58
+ | ProgressBar | | `01-components/11-progress-bar.md` | |
59
+ | LanguageSelector | | `01-components/12-language-selector.md` | |
60
+ | MatrixDropdown | | `01-components/13-matrix-dropdown.md` | |
61
+
62
+ ## 5. Theme, Brand & Logo
63
+
64
+ - [ ] CSS-only logo (no `<img>`, no `public/` uploads)
65
+ - [ ] Primary / hover colors from client prompt
66
+ - [ ] Header / Footer / ProgressBar / LanguageSelector per layout
67
+
68
+ ## 6. Submit & Thank You
69
+
70
+ - [ ] `onAction({ type: 'SUBMIT' })` on final page
71
+ - [ ] Thank-you screen when `submitSurveyResults.data` is set
72
+ - [ ] Custom thank-you message from client prompt if provided
73
+
74
+ ## 7. Pre-Build Verification
75
+
76
+ - [ ] No imports from `.../src/` internal paths
77
+ - [ ] All mutations via `onAction` — no direct state mutation
78
+ - [ ] `npm run build` passes
@@ -1,68 +0,0 @@
1
- # Fetch Survey — `useFetchSurvey`
2
-
3
- > **Source**: `packages/sdk/src/fetchSurvey/useFetchSurvey.ts`
4
- > **Called by**: `useSurveySDK()` internally — the client never calls this directly.
5
-
6
- ## What It Does
7
-
8
- 1. Builds the API URL from the client's `instanceId` (JWT token)
9
- 2. Makes a `GET` request to the Sprinklr CFM API endpoint
10
- 3. Caches the raw response using `@tanstack/react-query` (singleton QueryClient — no provider needed)
11
- 4. Re-maps the cached response whenever the target language changes (client-side, no re-fetch)
12
-
13
- ## API Endpoint
14
-
15
- ```
16
- https://custom-p0.feedbook.me/api/feedback/survey/cfm?instanceId={JWT_TOKEN}
17
- ```
18
-
19
- The URL is constructed by `buildSurveyUrl()` in `fetchSurvey/utils/url.ts`.
20
-
21
- ## Instance ID
22
-
23
- The `instanceId` is a **JWT token** string that encodes:
24
- - `surveyId` — Which survey to load
25
- - `distributionEntityId` — Which distribution channel
26
- - `surveyLanguage` — Default language (e.g. `'de'`)
27
- - `partnerId` — Tenant identifier
28
-
29
- **⚠️ CRITICAL**: The instanceId comes from the **client's chat prompt**. The agent must ask the client for it before building the survey. Without it, `useFetchSurvey` returns `null` and the survey cannot load.
30
-
31
- ## Return Shape
32
-
33
- ```typescript
34
- {
35
- survey: Survey | null, // Fully mapped survey object (see 02-survey-mapper.md)
36
- session: SurveySession | null, // { instanceId, language } — passed to submit hook
37
- fetching: boolean, // True while network request is in flight
38
- fetchError: Error | null, // Network/API error
39
- }
40
- ```
41
-
42
- ## Caching Behaviour
43
-
44
- - Keyed by `['survey', url]` — fetched **once** per instanceId
45
- - Language changes do NOT re-fetch — they re-map the cached raw response via `useMemo`
46
- - Uses `cache: 'force-cache'` on the fetch request for browser-level HTTP caching
47
-
48
- ## QueryClient
49
-
50
- The SDK creates its own internal singleton `QueryClient` in `src/queryClient.ts`.
51
- The client app does **NOT** need to wrap anything in `<QueryClientProvider>`.
52
-
53
- ## Logging & Telemetry
54
-
55
- The fetch lifecycle emits structured logs (when `debug: true`):
56
- - `logFetchStart(url)` — before the request
57
- - `logFetchPerfSuccess(durationMs, status, url, payloadSize)` — on success
58
- - `logFetchPerfFailure(durationMs, status, url)` — on failure
59
- - `trackFetchLatency(...)` — performance telemetry
60
-
61
- ## Error Handling
62
-
63
- | Scenario | Behaviour |
64
- |----------|-----------|
65
- | Network offline | `fetchError` populated, `survey` is `null` |
66
- | HTTP 4xx/5xx | `fetchError` populated with status message |
67
- | Invalid instanceId | API returns empty/malformed → `survey` maps to `null` |
68
- | Successful but empty | `survey` is `null`, no error |
@@ -1,85 +0,0 @@
1
- # Survey Mapper — `mapSurvey`
2
-
3
- > **Source**: `packages/sdk/src/fetchSurvey/utils/mappers/surveyMapper.ts`
4
- > **Called by**: `useFetchSurvey()` inside `useMemo` — re-runs when language changes.
5
-
6
- ## What It Does
7
-
8
- Transforms the raw API response (`ApiResponse`) into a clean, typed `Survey` object:
9
-
10
- ```
11
- ApiResponse (raw network JSON)
12
-
13
- ├── extractQuestions() → Flat list of ApiQuestion[]
14
- ├── resolveSurveyLanguage() → Determine active language code
15
- ├── extractSurveyLanguages()→ Build SurveyLanguage[] for language switcher
16
- └── mapSurveyPages() → Pages → Questions → per-type mappers
17
-
18
- └── mapQuestion() per question (see 03-question-mappers.md)
19
- ```
20
-
21
- ## Output: `Survey` Type
22
-
23
- ```typescript
24
- type Survey = {
25
- id: string; // Survey identifier
26
- language: string; // Active language code (e.g. 'en', 'de')
27
- languages: SurveyLanguage[]; // All available languages for the switcher
28
- pages: SurveyPageData[]; // Ordered list of pages
29
- };
30
-
31
- type SurveyPageData = {
32
- id: string; // Page identifier
33
- title?: string; // Optional page heading
34
- questions: SurveyQuestion[]; // Questions on this page
35
- };
36
-
37
- type SurveyLanguage = {
38
- code: string; // BCP-47 code (e.g. 'de')
39
- name: string; // Display name (e.g. 'Deutsch')
40
- };
41
- ```
42
-
43
- ## Key Functions
44
-
45
- ### `extractQuestions(api)`
46
- Traverses `api.cfmSurveyDTO.surveyPages[].questionHolders[].question` to produce a flat array of raw API questions.
47
-
48
- ### `resolveSurveyLanguage(api, language?)`
49
- Priority: `language` parameter → `api.surveyLanguage` → `api.cfmSurveyDTO.baseLanguage` → `'en'`
50
-
51
- ### `extractSession(api)`
52
- Returns `{ instanceId, language }` or `null` if no valid instanceId exists. This session object is passed to the submit hook.
53
-
54
- ### `mapSurveyPages(api, language, placeholders)`
55
- Iterates over `api.cfmSurveyDTO.surveyPages`, calling `mapQuestion()` for each question within each page's `questionHolders`. Returns `SurveyPageData[]`.
56
-
57
- ## API Response Structure (Simplified)
58
-
59
- ```typescript
60
- type ApiResponse = {
61
- instanceId: string;
62
- surveyLanguage: string;
63
- cfmSurveyDTO: {
64
- id: string;
65
- baseLanguage: string;
66
- surveyPages: Array<{
67
- id: string;
68
- pageTitle?: string;
69
- questionHolders: Array<{
70
- question: ApiQuestion;
71
- }>;
72
- }>;
73
- };
74
- };
75
- ```
76
-
77
- ## Language Re-mapping
78
-
79
- When the user switches language via the `LanguageSelector`:
80
- 1. `selectedLanguage` state changes in `SurveyPage.tsx`
81
- 2. This flows into `useSurveySDK({ options: { language: selectedLanguage } })`
82
- 3. `useFetchSurvey` does **NOT re-fetch** — the raw `ApiResponse` is cached
83
- 4. `useMemo` re-runs `mapSurvey(apiResponse, newLanguage, placeholders)`
84
- 5. Each question's text, options, and labels are resolved from `translations[language]`
85
- 6. The entire UI re-renders with translated content
@@ -1,114 +0,0 @@
1
- # Question Mappers — `mapQuestion`
2
-
3
- > **Source**: `packages/sdk/src/fetchSurvey/utils/mappers/questionMappers/index.ts`
4
- > **Called by**: `mapSurveyPages()` for each question in each page.
5
-
6
- ## What It Does
7
-
8
- Takes a raw `ApiQuestion` and produces a fully typed `SurveyQuestion` variant. This is the core routing logic that determines what question type the client component will render.
9
-
10
- ## Dispatch Pipeline
11
-
12
- ```
13
- ApiQuestion
14
-
15
- ├── resolveBase(raw, configs, language, placeholders)
16
- │ → { id, text, description, required, requiredErrorMessage, containerMedia* }
17
-
18
- ├── normalizeType(raw.answerType)
19
- │ → 'rating' | 'text' | 'matrix' | 'rating_matrix' | 'slider_matrix'
20
- │ | 'text_and_media' | 'file_upload' | 'radio' (default)
21
-
22
- └── switch(type) → per-type mapper
23
- ├── 'rating' → mapRatingQuestion() [handles NPS, CSAT, Slider, RatingScale]
24
- ├── 'text' → mapTextQuestion()
25
- ├── 'matrix' → mapMatrixQuestion() [handles CFM, CSAT, RATING matrix]
26
- ├── 'rating_matrix' → mapMatrixQuestion() [same handler, different subType]
27
- ├── 'slider_matrix' → mapSliderMatrixQuestion()
28
- ├── 'text_and_media' → mapTextAndMediaQuestion()
29
- ├── 'file_upload' → mapFileUploadQuestion()
30
- └── default → mapRadioQuestion() [MCQ and any unrecognised type]
31
- ```
32
-
33
- ## `normalizeType(answerType)` — Type Resolution
34
-
35
- | API `answerType` | Normalized Type | Notes |
36
- |-----------------|----------------|-------|
37
- | `'SCALE'` | `'rating'` | Further sub-typed inside ratingMapper |
38
- | `'RATING'` | `'rating'` | Legacy alias |
39
- | `'RATING_MATRIX'` | `'rating_matrix'` | Grid with NPS-style columns |
40
- | `'TEXTFIELD'` | `'text'` | Short or long text input |
41
- | `'MCQ'` | `'radio'` | Multiple choice (single select) |
42
- | `'CFM_MATRIX'` | `'matrix'` | Likert-style grid |
43
- | `'CSAT_MATRIX'` | `'matrix'` | Satisfaction grid with emoji/star |
44
- | `'SLIDER_MATRIX'` | `'slider_matrix'` | Grid of range sliders |
45
- | `'TEXT_AND_MEDIA'` | `'text_and_media'` | Display-only media card |
46
- | `'FILE_UPLOAD'` | `'file_upload'` | File attachment question |
47
- | Any other | `'radio'` | Safe fallback |
48
-
49
- ## `resolveBase()` — Shared Fields
50
-
51
- Every question variant inherits these base fields:
52
-
53
- ```typescript
54
- type QuestionBase = {
55
- id: string; // ⚠️ MUST be used as DOM element id
56
- text: string; // May contain HTML — use dangerouslySetInnerHTML
57
- description?: string; // Supplementary instruction text (HTML)
58
- required?: boolean; // Whether answer is mandatory
59
- requiredErrorMessage?: string; // Custom validation error text
60
- questionNumber?: number; // 1-indexed ordinal position
61
- containerMediaUrl?: string; // Image/video shown alongside question
62
- containerMediaMimeType?: string; // MIME type for container media
63
- containerMediaAlignment?: string;// Layout position of container media
64
- containerMediaSize?: number; // Width percentage of container media
65
- };
66
- ```
67
-
68
- ### Text Resolution Priority
69
- ```
70
- language translation (richText) → language translation (plainText)
71
- → default richText → default plainText → ''
72
- ```
73
-
74
- ### Placeholder Replacement
75
- The `resolveBase` function replaces `{{TOKEN}}` patterns in question text and description:
76
- ```typescript
77
- text.replace(/\{\{(\w+)\}\}/g, (match, key) =>
78
- placeholders[key] !== undefined ? placeholders[key] : match
79
- );
80
- ```
81
-
82
- ## Rating Mapper Sub-Dispatch
83
-
84
- The `mapRatingQuestion()` handler further sub-types based on `questionConfigs`:
85
-
86
- ```
87
- SCALE answerType
88
-
89
- ├── SCALE_TYPE=CSAT (or ≤5 options) → type: 'csat'
90
- ├── SCALE_TYPE=STAR/EMOJI/FIVE_POINT → type: 'rating_scale'
91
- ├── INPUT_TYPE=SLIDER → type: 'slider'
92
- └── default (NPS/TEN_POINT) → type: 'rating'
93
- ```
94
-
95
- This means the client component's `Question.tsx` needs to handle **all these refined types**, not just the raw `'rating'` type.
96
-
97
- ## Final Output: `SurveyQuestion` Union
98
-
99
- ```typescript
100
- type SurveyQuestion =
101
- | RatingQuestion // type: 'rating'
102
- | RadioQuestion // type: 'radio'
103
- | TextQuestion // type: 'text'
104
- | MatrixQuestion // type: 'matrix'
105
- | RatingMatrixQuestion // type: 'rating_matrix'
106
- | SliderMatrixQuestion // type: 'slider_matrix'
107
- | TextAndMediaQuestion // type: 'text_and_media'
108
- | CsatQuestion // type: 'csat'
109
- | SliderQuestion // type: 'slider'
110
- | RatingScaleQuestion // type: 'rating_scale'
111
- | FileUploadQuestion; // type: 'file_upload'
112
- ```
113
-
114
- Each type is documented in detail in `02-question-types/`.