@crownpeak/dqm-react-component 1.0.1 → 1.2.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/CHANGELOG.md +41 -0
- package/README.md +125 -23
- package/dist/DQMSidebar.d.ts.map +1 -1
- package/dist/ErrorBoundary.d.ts.map +1 -1
- package/dist/__tests__/setup.d.ts +1 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/utils.d.ts +145 -0
- package/dist/__tests__/utils.d.ts.map +1 -0
- package/dist/auth-ui/assets/index-YKFZYENy.js +158 -0
- package/dist/auth-ui/index.html +1 -1
- package/dist/components/auth/DQMLogin.d.ts.map +1 -1
- package/dist/components/auth/index.d.ts +0 -1
- package/dist/components/auth/index.d.ts.map +1 -1
- package/dist/components/cards/AISummaryCard.d.ts +2 -0
- package/dist/components/cards/AISummaryCard.d.ts.map +1 -0
- package/dist/components/cards/index.d.ts +1 -0
- package/dist/components/cards/index.d.ts.map +1 -1
- package/dist/components/common/LanguageSwitch.d.ts +5 -0
- package/dist/components/common/LanguageSwitch.d.ts.map +1 -0
- package/dist/components/common/LanguageSwitchBase.d.ts +16 -0
- package/dist/components/common/LanguageSwitchBase.d.ts.map +1 -0
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/common/index.d.ts.map +1 -1
- package/dist/components/modals/AISettingsDialog.d.ts +61 -0
- package/dist/components/modals/AISettingsDialog.d.ts.map +1 -0
- package/dist/components/modals/HighlightModal.d.ts +45 -0
- package/dist/components/modals/HighlightModal.d.ts.map +1 -0
- package/dist/components/modals/LoginOverlay.d.ts +22 -0
- package/dist/components/modals/LoginOverlay.d.ts.map +1 -0
- package/dist/components/modals/index.d.ts +9 -0
- package/dist/components/modals/index.d.ts.map +1 -0
- package/dist/components/renderers/BrowserViewRenderer.d.ts.map +1 -1
- package/dist/components/renderers/ShadowDOMRenderer.d.ts.map +1 -1
- package/dist/components/sidebar/CloseButton.d.ts +6 -0
- package/dist/components/sidebar/CloseButton.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarContent.d.ts.map +1 -1
- package/dist/components/sidebar/SidebarFooter.d.ts.map +1 -1
- package/dist/components/sidebar/SidebarHeader.d.ts.map +1 -1
- package/dist/components/sidebar/SidebarSkeleton.d.ts.map +1 -1
- package/dist/components/sidebar/StyledDrawer.d.ts +6 -1
- package/dist/components/sidebar/StyledDrawer.d.ts.map +1 -1
- package/dist/components/sidebar/StyledFab.d.ts +4 -1
- package/dist/components/sidebar/StyledFab.d.ts.map +1 -1
- package/dist/components/sidebar/index.d.ts +1 -0
- package/dist/components/sidebar/index.d.ts.map +1 -1
- package/dist/context/ai/AIContext.d.ts +13 -0
- package/dist/context/ai/AIContext.d.ts.map +1 -0
- package/dist/context/ai/index.d.ts +12 -0
- package/dist/context/ai/index.d.ts.map +1 -0
- package/dist/context/ai/types.d.ts +161 -0
- package/dist/context/ai/types.d.ts.map +1 -0
- package/dist/context/ai/useAIEngine.d.ts +10 -0
- package/dist/context/ai/useAIEngine.d.ts.map +1 -0
- package/dist/context/ai/useAISummary.d.ts +10 -0
- package/dist/context/ai/useAISummary.d.ts.map +1 -0
- package/dist/context/ai/useAITranslation.d.ts +10 -0
- package/dist/context/ai/useAITranslation.d.ts.map +1 -0
- package/dist/context/ai/useTranslationCache.d.ts +9 -0
- package/dist/context/ai/useTranslationCache.d.ts.map +1 -0
- package/dist/dqm-widget.d.ts +107 -0
- package/dist/dqm-widget.esm.js +516 -0
- package/dist/dqm-widget.iife.js +183 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useAnalysis.d.ts +43 -0
- package/dist/hooks/useAnalysis.d.ts.map +1 -0
- package/dist/hooks/useAuthentication.d.ts +49 -0
- package/dist/hooks/useAuthentication.d.ts.map +1 -0
- package/dist/hooks/useHighlightActions.d.ts +37 -0
- package/dist/hooks/useHighlightActions.d.ts.map +1 -0
- package/dist/hooks/useHighlights.d.ts +72 -0
- package/dist/hooks/useHighlights.d.ts.map +1 -0
- package/dist/html-pages/DQMWidget.d.ts +36 -0
- package/dist/html-pages/DQMWidget.d.ts.map +1 -0
- package/dist/html-pages/index.d.ts +32 -0
- package/dist/html-pages/index.d.ts.map +1 -0
- package/dist/i18n/auth/de.d.ts +25 -0
- package/dist/i18n/auth/de.d.ts.map +1 -0
- package/dist/i18n/auth/en.d.ts +26 -0
- package/dist/i18n/auth/en.d.ts.map +1 -0
- package/dist/i18n/auth/es.d.ts +25 -0
- package/dist/i18n/auth/es.d.ts.map +1 -0
- package/dist/i18n/auth/index.d.ts +8 -0
- package/dist/i18n/auth/index.d.ts.map +1 -0
- package/dist/i18n/common/de.d.ts +18 -0
- package/dist/i18n/common/de.d.ts.map +1 -0
- package/dist/i18n/common/en.d.ts +19 -0
- package/dist/i18n/common/en.d.ts.map +1 -0
- package/dist/i18n/common/es.d.ts +18 -0
- package/dist/i18n/common/es.d.ts.map +1 -0
- package/dist/i18n/common/index.d.ts +8 -0
- package/dist/i18n/common/index.d.ts.map +1 -0
- package/dist/i18n/demo/de.d.ts +104 -0
- package/dist/i18n/demo/de.d.ts.map +1 -0
- package/dist/i18n/demo/en.d.ts +105 -0
- package/dist/i18n/demo/en.d.ts.map +1 -0
- package/dist/i18n/demo/es.d.ts +104 -0
- package/dist/i18n/demo/es.d.ts.map +1 -0
- package/dist/i18n/demo/index.d.ts +8 -0
- package/dist/i18n/demo/index.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +673 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/sidebar/de.d.ts +89 -0
- package/dist/i18n/sidebar/de.d.ts.map +1 -0
- package/dist/i18n/sidebar/en.d.ts +90 -0
- package/dist/i18n/sidebar/en.d.ts.map +1 -0
- package/dist/i18n/sidebar/es.d.ts +89 -0
- package/dist/i18n/sidebar/es.d.ts.map +1 -0
- package/dist/i18n/sidebar/index.d.ts +8 -0
- package/dist/i18n/sidebar/index.d.ts.map +1 -0
- package/dist/i18n.d.ts +8 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.cjs +61 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.html +498 -0
- package/dist/index.js +18006 -7241
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +25 -0
- package/dist/locale.d.ts.map +1 -0
- package/dist/mocks/browser.d.ts +23 -0
- package/dist/mocks/browser.d.ts.map +1 -0
- package/dist/mocks/handlers.d.ts +32 -0
- package/dist/mocks/handlers.d.ts.map +1 -0
- package/dist/mocks/index.d.ts +7 -0
- package/dist/mocks/index.d.ts.map +1 -0
- package/dist/mocks/server.d.ts +24 -0
- package/dist/mocks/server.d.ts.map +1 -0
- package/dist/server/routes/auth.js +0 -10
- package/dist/server/routes/auth.js.map +1 -1
- package/dist/store/api/dqmApi.d.ts +1793 -0
- package/dist/store/api/dqmApi.d.ts.map +1 -0
- package/dist/store/api/index.d.ts +6 -0
- package/dist/store/api/index.d.ts.map +1 -0
- package/dist/store/index.d.ts +57 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/localeSlice.d.ts +6 -0
- package/dist/store/localeSlice.d.ts.map +1 -0
- package/dist/store/slices/aiSlice.d.ts +134 -0
- package/dist/store/slices/aiSlice.d.ts.map +1 -0
- package/dist/store/slices/analysisSlice.d.ts +54 -0
- package/dist/store/slices/analysisSlice.d.ts.map +1 -0
- package/dist/store/slices/authSlice.d.ts +170 -0
- package/dist/store/slices/authSlice.d.ts.map +1 -0
- package/dist/store/slices/highlightSlice.d.ts +188 -0
- package/dist/store/slices/highlightSlice.d.ts.map +1 -0
- package/dist/store/slices/index.d.ts +12 -0
- package/dist/store/slices/index.d.ts.map +1 -0
- package/dist/types.d.ts +109 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/aiJsonClient.d.ts +23 -0
- package/dist/utils/aiJsonClient.d.ts.map +1 -0
- package/dist/utils/colors/GenerateCategoryColors.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +107 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/openaiJsonClient.d.ts +8 -0
- package/dist/utils/openaiJsonClient.d.ts.map +1 -0
- package/dist/utils/sanitizeHtmlDocument.d.ts +4 -0
- package/dist/utils/sanitizeHtmlDocument.d.ts.map +1 -0
- package/dist/utils/secureStorage.d.ts +95 -0
- package/dist/utils/secureStorage.d.ts.map +1 -0
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/translationCache.d.ts +45 -0
- package/dist/utils/translationCache.d.ts.map +1 -0
- package/dist/utils/translationUtils.d.ts +52 -0
- package/dist/utils/translationUtils.d.ts.map +1 -0
- package/dist/utils/useDomPresence.d.ts +210 -0
- package/dist/utils/useDomPresence.d.ts.map +1 -0
- package/package.json +59 -12
- package/AUTHENTICATION.md +0 -281
- package/BACKEND-API.md +0 -1829
- package/DEVELOPMENT.md +0 -339
- package/EXAMPLES.md +0 -194
- package/QUICKSTART.md +0 -200
- package/dist/auth-ui/assets/index-CczTRrba.js +0 -158
- package/dist/components/auth/OAuth2CallbackHandler.d.ts +0 -15
- package/dist/components/auth/OAuth2CallbackHandler.d.ts.map +0 -1
package/DEVELOPMENT.md
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
# Development Guide
|
|
2
|
-
|
|
3
|
-
## Running the Complete Stack
|
|
4
|
-
|
|
5
|
-
### Start Development (Frontend + Backend)
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm run dev
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
This runs both servers concurrently:
|
|
12
|
-
- **Frontend (Vite)**: http://localhost:5173
|
|
13
|
-
- **Backend (Express)**: http://localhost:3001
|
|
14
|
-
|
|
15
|
-
### Start Individual Servers
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Frontend only
|
|
19
|
-
npm run dev:client
|
|
20
|
-
|
|
21
|
-
# Backend only
|
|
22
|
-
npm run dev:server
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Project Structure
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
crownpeak-dqm-react-component/
|
|
29
|
-
├── src/ # React component source
|
|
30
|
-
│ ├── components/
|
|
31
|
-
│ │ ├── auth/ # Authentication components
|
|
32
|
-
│ │ ├── sidebar/ # Sidebar UI components
|
|
33
|
-
│ │ ├── cards/ # Analysis result cards
|
|
34
|
-
│ │ ├── renderers/ # HTML rendering
|
|
35
|
-
│ │ └── common/ # Shared components
|
|
36
|
-
│ ├── utils/ # Utilities
|
|
37
|
-
│ ├── types.ts # TypeScript types
|
|
38
|
-
│ ├── DQMSidebar.tsx # Main component
|
|
39
|
-
│ ├── index.ts # Library entry point
|
|
40
|
-
│ ├── App.tsx # Dev test harness
|
|
41
|
-
│ └── main.tsx # Dev app entry
|
|
42
|
-
│
|
|
43
|
-
├── server/ # Backend API
|
|
44
|
-
│ ├── routes/ # API endpoints
|
|
45
|
-
│ │ ├── auth.ts # Authentication
|
|
46
|
-
│ │ └── dqm.ts # DQM proxy
|
|
47
|
-
│ ├── services/ # Business logic
|
|
48
|
-
│ │ ├── sessionStore.ts # Session management
|
|
49
|
-
│ │ └── dqmClient.ts # DQM API client
|
|
50
|
-
│ ├── middleware/ # Express middleware
|
|
51
|
-
│ ├── config.ts # Configuration
|
|
52
|
-
│ ├── types.ts # TypeScript types
|
|
53
|
-
│ └── index.ts # Express app
|
|
54
|
-
│
|
|
55
|
-
├── dist/ # Build output
|
|
56
|
-
│ ├── index.js # Library ESM
|
|
57
|
-
│ ├── index.cjs # Library CommonJS
|
|
58
|
-
│ ├── index.d.ts # Type declarations
|
|
59
|
-
│ └── server/ # Compiled server code
|
|
60
|
-
│
|
|
61
|
-
├── vite.config.ts # Vite configuration
|
|
62
|
-
├── tsconfig.json # TypeScript base config
|
|
63
|
-
├── tsconfig.lib.json # Library build config
|
|
64
|
-
├── tsconfig.server.json # Server build config
|
|
65
|
-
└── package.json # Dependencies & scripts
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Authentication Modes
|
|
69
|
-
|
|
70
|
-
The component supports two modes:
|
|
71
|
-
|
|
72
|
-
### 1. Backend Mode (Recommended for Production)
|
|
73
|
-
|
|
74
|
-
```tsx
|
|
75
|
-
<DQMSidebar
|
|
76
|
-
config={{
|
|
77
|
-
authBackendUrl: 'http://localhost:3001',
|
|
78
|
-
useLocalStorage: true,
|
|
79
|
-
}}
|
|
80
|
-
/>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
- All API calls proxied through backend
|
|
84
|
-
- Session token stored in localStorage
|
|
85
|
-
- Real credentials never exposed to client
|
|
86
|
-
|
|
87
|
-
### 2. Direct Mode (Development/Staging)
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
<DQMSidebar
|
|
91
|
-
config={{
|
|
92
|
-
apiKey: 'YOUR_API_KEY',
|
|
93
|
-
websiteId: 'YOUR_WEBSITE_ID',
|
|
94
|
-
}}
|
|
95
|
-
/>
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
- Direct communication with Crownpeak DQM API
|
|
99
|
-
- Credentials in props or localStorage
|
|
100
|
-
- No backend required
|
|
101
|
-
|
|
102
|
-
## Testing Both Modes
|
|
103
|
-
|
|
104
|
-
### Test Backend Mode
|
|
105
|
-
|
|
106
|
-
1. Start both servers: `npm run dev`
|
|
107
|
-
2. Open http://localhost:5173
|
|
108
|
-
3. Click "Login" and enter credentials
|
|
109
|
-
4. Backend validates and issues session token
|
|
110
|
-
5. All API calls go through http://localhost:3001
|
|
111
|
-
|
|
112
|
-
### Test Direct Mode
|
|
113
|
-
|
|
114
|
-
1. Update `src/App.tsx`:
|
|
115
|
-
```tsx
|
|
116
|
-
<DQMSidebar
|
|
117
|
-
config={{
|
|
118
|
-
apiKey: 'YOUR_API_KEY',
|
|
119
|
-
websiteId: 'YOUR_WEBSITE_ID',
|
|
120
|
-
}}
|
|
121
|
-
/>
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
2. Start frontend only: `npm run dev:client`
|
|
125
|
-
3. No backend needed, direct API calls
|
|
126
|
-
|
|
127
|
-
## Building for Production
|
|
128
|
-
|
|
129
|
-
### Build Library
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
npm run build:lib
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Output: `dist/index.{js,cjs,d.ts}`
|
|
136
|
-
|
|
137
|
-
### Build Server
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
npm run build:server
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Output: `dist/server/`
|
|
144
|
-
|
|
145
|
-
### Test Library Build
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
npm pack
|
|
149
|
-
# Creates: crownpeak-dqm-react-component-1.0.0.tgz
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Environment Configuration
|
|
153
|
-
|
|
154
|
-
### Frontend (.env)
|
|
155
|
-
|
|
156
|
-
```env
|
|
157
|
-
VITE_BACKEND_URL=http://localhost:3001
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Backend (.env)
|
|
161
|
-
|
|
162
|
-
```env
|
|
163
|
-
PORT=3001
|
|
164
|
-
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
|
165
|
-
DQM_API_BASE_URL=https://api.crownpeak.net/dqm-cms/v1
|
|
166
|
-
JWT_SECRET=your-secret-key
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## API Testing with cURL
|
|
170
|
-
|
|
171
|
-
### Login
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
curl -X POST http://localhost:3001/auth/login \
|
|
175
|
-
-H "Content-Type: application/json" \
|
|
176
|
-
-d '{
|
|
177
|
-
"apiKey": "YOUR_API_KEY",
|
|
178
|
-
"websiteId": "YOUR_WEBSITE_ID"
|
|
179
|
-
}'
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Response:
|
|
183
|
-
```json
|
|
184
|
-
{
|
|
185
|
-
"sessionToken": "abc123...",
|
|
186
|
-
"websiteId": "YOUR_WEBSITE_ID"
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Start Analysis
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
curl -X POST http://localhost:3001/dqm/assets \
|
|
194
|
-
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
|
|
195
|
-
-H "Content-Type: application/json" \
|
|
196
|
-
-d '{
|
|
197
|
-
"html": "<html><body><h1>Test</h1></body></html>",
|
|
198
|
-
"url": "https://example.com"
|
|
199
|
-
}'
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Get Results
|
|
203
|
-
|
|
204
|
-
```bash
|
|
205
|
-
curl -X GET http://localhost:3001/dqm/assets/ASSET_ID \
|
|
206
|
-
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
## Debugging
|
|
210
|
-
|
|
211
|
-
### Enable Verbose Logging
|
|
212
|
-
|
|
213
|
-
Backend logs all requests automatically. Check terminal output:
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
[2025-10-31T10:00:00.000Z] POST /auth/login
|
|
217
|
-
[Auth] User logged in successfully (websiteId: test_id)
|
|
218
|
-
[SessionStore] Created session: abc12345... (expires in 1440 minutes)
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Check Session Status
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
curl -X GET http://localhost:3001/auth/session \
|
|
225
|
-
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### View Active Sessions (Dev Only)
|
|
229
|
-
|
|
230
|
-
Add to `server/routes/auth.ts`:
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
authRouter.get('/sessions/count', (req, res) => {
|
|
234
|
-
res.json({ count: sessionStore.count() });
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
## Common Issues
|
|
239
|
-
|
|
240
|
-
### CORS Errors
|
|
241
|
-
|
|
242
|
-
**Problem:** Frontend can't reach backend
|
|
243
|
-
|
|
244
|
-
**Solution:** Add frontend URL to `CORS_ORIGINS` in `.env`:
|
|
245
|
-
```env
|
|
246
|
-
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Port Already in Use
|
|
250
|
-
|
|
251
|
-
**Problem:** `Error: listen EADDRINUSE: address already in use :::3001`
|
|
252
|
-
|
|
253
|
-
**Solution:** Kill process or change port:
|
|
254
|
-
```bash
|
|
255
|
-
lsof -ti:3001 | xargs kill -9
|
|
256
|
-
# or change PORT in .env
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### Session Expired
|
|
260
|
-
|
|
261
|
-
**Problem:** 401 Unauthorized after some time
|
|
262
|
-
|
|
263
|
-
**Solution:** Session TTL is 24 hours. Login again or extend TTL in `server/config.ts`:
|
|
264
|
-
```typescript
|
|
265
|
-
session: {
|
|
266
|
-
ttl: 48 * 60 * 60 * 1000, // 48 hours
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
### TypeScript Errors
|
|
271
|
-
|
|
272
|
-
**Problem:** Type errors in server code
|
|
273
|
-
|
|
274
|
-
**Solution:** Ensure @types packages installed:
|
|
275
|
-
```bash
|
|
276
|
-
npm install --save-dev @types/express @types/cors @types/node
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
## Production Deployment
|
|
280
|
-
|
|
281
|
-
### Deploy Backend
|
|
282
|
-
|
|
283
|
-
1. Build server: `npm run build:server`
|
|
284
|
-
2. Copy `dist/server/` to production
|
|
285
|
-
3. Set environment variables
|
|
286
|
-
4. Install production dependencies only
|
|
287
|
-
5. Start: `node dist/server/index.js`
|
|
288
|
-
|
|
289
|
-
### Use Redis for Sessions
|
|
290
|
-
|
|
291
|
-
Replace `server/services/sessionStore.ts` with Redis:
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
import { createClient } from 'redis';
|
|
295
|
-
|
|
296
|
-
const redis = createClient({
|
|
297
|
-
url: process.env.REDIS_URL
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
await redis.connect();
|
|
301
|
-
|
|
302
|
-
export const sessionStore = {
|
|
303
|
-
create: async (apiKey, websiteId) => {
|
|
304
|
-
const token = generateToken();
|
|
305
|
-
await redis.setEx(`session:${token}`, 86400, JSON.stringify({
|
|
306
|
-
apiKey, websiteId, createdAt: Date.now()
|
|
307
|
-
}));
|
|
308
|
-
return token;
|
|
309
|
-
},
|
|
310
|
-
get: async (token) => {
|
|
311
|
-
const data = await redis.get(`session:${token}`);
|
|
312
|
-
return data ? JSON.parse(data) : null;
|
|
313
|
-
},
|
|
314
|
-
delete: async (token) => {
|
|
315
|
-
await redis.del(`session:${token}`);
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### Add Rate Limiting
|
|
321
|
-
|
|
322
|
-
```bash
|
|
323
|
-
npm install express-rate-limit
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
import rateLimit from 'express-rate-limit';
|
|
328
|
-
|
|
329
|
-
const limiter = rateLimit({
|
|
330
|
-
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
331
|
-
max: 100 // limit each IP to 100 requests per windowMs
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
app.use('/auth/login', limiter);
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
## License
|
|
338
|
-
|
|
339
|
-
MIT
|
package/EXAMPLES.md
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# Example Usage
|
|
2
|
-
|
|
3
|
-
This directory contains example implementations of the `@crownpeak/dqm-react-component`.
|
|
4
|
-
|
|
5
|
-
## Basic React App Example
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
import React, {useState} from 'react';
|
|
9
|
-
import {DQMSidebar} from '@crownpeak/dqm-react-component';
|
|
10
|
-
|
|
11
|
-
function App() {
|
|
12
|
-
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
13
|
-
|
|
14
|
-
// Set DQM credentials (e.g., from environment variables)
|
|
15
|
-
React.useEffect(() => {
|
|
16
|
-
localStorage.setItem('dqm_apiKey', process.env.REACT_APP_DQM_API_KEY);
|
|
17
|
-
localStorage.setItem('dqm_websiteID', process.env.REACT_APP_DQM_WEBSITE_ID);
|
|
18
|
-
}, []);
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div>
|
|
22
|
-
<h1>My Application with DQM</h1>
|
|
23
|
-
<p>This page is monitored by Crownpeak DQM for quality assurance.</p>
|
|
24
|
-
|
|
25
|
-
<DQMSidebar
|
|
26
|
-
open={sidebarOpen}
|
|
27
|
-
onClose={() => setSidebarOpen(false)}
|
|
28
|
-
onOpen={() => setSidebarOpen(true)}
|
|
29
|
-
/>
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export default App;
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Next.js Example
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
// pages/_app.tsx
|
|
41
|
-
import type {AppProps} from 'next/app';
|
|
42
|
-
import {useEffect, useState} from 'react';
|
|
43
|
-
import {DQMSidebar} from '@crownpeak/dqm-react-component';
|
|
44
|
-
import {createTheme} from '@mui/material/styles';
|
|
45
|
-
|
|
46
|
-
const theme = createTheme();
|
|
47
|
-
|
|
48
|
-
function MyApp({Component, pageProps}: AppProps) {
|
|
49
|
-
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
50
|
-
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
if (typeof window !== 'undefined') {
|
|
53
|
-
localStorage.setItem('dqm_apiKey', process.env.NEXT_PUBLIC_DQM_API_KEY!);
|
|
54
|
-
localStorage.setItem('dqm_websiteID', process.env.NEXT_PUBLIC_DQM_WEBSITE_ID!);
|
|
55
|
-
}
|
|
56
|
-
}, []);
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<>
|
|
60
|
-
<Component {...pageProps} />
|
|
61
|
-
<DQMSidebar
|
|
62
|
-
open={sidebarOpen}
|
|
63
|
-
onClose={() => setSidebarOpen(false)}
|
|
64
|
-
onOpen={() => setSidebarOpen(true)}
|
|
65
|
-
/>
|
|
66
|
-
</>
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export default MyApp;
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## TypeScript Example with Custom Configuration
|
|
74
|
-
|
|
75
|
-
```tsx
|
|
76
|
-
import React, { useState, useCallback } from 'react';
|
|
77
|
-
import { DQMSidebar, ErrorBoundary } from '@crownpeak/dqm-react-component';
|
|
78
|
-
import type { DQMSidebarProps } from '@crownpeak/dqm-react-component';
|
|
79
|
-
|
|
80
|
-
interface DQMConfig {
|
|
81
|
-
apiKey: string;
|
|
82
|
-
websiteId: string;
|
|
83
|
-
enabled: boolean;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const config: DQMConfig = {
|
|
87
|
-
apiKey: process.env.REACT_APP_DQM_API_KEY!,
|
|
88
|
-
websiteId: process.env.REACT_APP_DQM_WEBSITE_ID!,
|
|
89
|
-
enabled: process.env.NODE_ENV === 'production'
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
function App() {
|
|
93
|
-
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
94
|
-
|
|
95
|
-
React.useEffect(() => {
|
|
96
|
-
if (config.enabled) {
|
|
97
|
-
localStorage.setItem('dqm_apiKey', config.apiKey);
|
|
98
|
-
localStorage.setItem('dqm_websiteID', config.websiteId);
|
|
99
|
-
}
|
|
100
|
-
}, []);
|
|
101
|
-
|
|
102
|
-
const handleOpen = useCallback(() => {
|
|
103
|
-
setSidebarOpen(true);
|
|
104
|
-
}, []);
|
|
105
|
-
|
|
106
|
-
const handleClose = useCallback(() => {
|
|
107
|
-
setSidebarOpen(false);
|
|
108
|
-
}, []);
|
|
109
|
-
|
|
110
|
-
if (!config.enabled) {
|
|
111
|
-
return <div>DQM is disabled in this environment</div>;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return (
|
|
115
|
-
<ErrorBoundary>
|
|
116
|
-
<div>
|
|
117
|
-
<h1>App with DQM Quality Monitoring</h1>
|
|
118
|
-
<DQMSidebar
|
|
119
|
-
open={sidebarOpen}
|
|
120
|
-
onClose={handleClose}
|
|
121
|
-
onOpen={handleOpen}
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
</ErrorBoundary>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export default App;
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Conditional Rendering (Development Only)
|
|
132
|
-
|
|
133
|
-
```tsx
|
|
134
|
-
import React from 'react';
|
|
135
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
136
|
-
|
|
137
|
-
function App() {
|
|
138
|
-
const [sidebarOpen, setSidebarOpen] = React.useState(false);
|
|
139
|
-
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<div>
|
|
143
|
-
<h1>My App</h1>
|
|
144
|
-
|
|
145
|
-
{/* Only show DQM in development */}
|
|
146
|
-
{isDevelopment && (
|
|
147
|
-
<DQMSidebar
|
|
148
|
-
open={sidebarOpen}
|
|
149
|
-
onClose={() => setSidebarOpen(false)}
|
|
150
|
-
onOpen={() => setSidebarOpen(true)}
|
|
151
|
-
/>
|
|
152
|
-
)}
|
|
153
|
-
</div>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## With Custom Button Trigger
|
|
159
|
-
|
|
160
|
-
```tsx
|
|
161
|
-
import React, { useState } from 'react';
|
|
162
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
163
|
-
import { Button } from '@mui/material';
|
|
164
|
-
import { Assessment } from '@mui/icons-material';
|
|
165
|
-
|
|
166
|
-
function App() {
|
|
167
|
-
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
<div>
|
|
171
|
-
<header>
|
|
172
|
-
<Button
|
|
173
|
-
variant="outlined"
|
|
174
|
-
startIcon={<Assessment />}
|
|
175
|
-
onClick={() => setSidebarOpen(true)}
|
|
176
|
-
>
|
|
177
|
-
Quality Check
|
|
178
|
-
</Button>
|
|
179
|
-
</header>
|
|
180
|
-
|
|
181
|
-
<main>
|
|
182
|
-
<h1>Content</h1>
|
|
183
|
-
</main>
|
|
184
|
-
|
|
185
|
-
<DQMSidebar
|
|
186
|
-
open={sidebarOpen}
|
|
187
|
-
onClose={() => setSidebarOpen(false)}
|
|
188
|
-
onOpen={() => setSidebarOpen(true)}
|
|
189
|
-
/>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
package/QUICKSTART.md
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
# 🚀 Quick Start Guide
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Build
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm run build
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Start Development
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm run dev
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
This starts:
|
|
22
|
-
- ✅ **Frontend**: http://localhost:5173 (Vite Dev Server)
|
|
23
|
-
- ✅ **Backend**: http://localhost:3001 (Express API)
|
|
24
|
-
|
|
25
|
-
## Test the Integration
|
|
26
|
-
|
|
27
|
-
### 1. Open Frontend
|
|
28
|
-
Navigate to http://localhost:5173
|
|
29
|
-
|
|
30
|
-
### 2. Configure Backend Mode
|
|
31
|
-
The test harness is already configured to use the backend:
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
config={{
|
|
35
|
-
authBackendUrl: 'http://localhost:3001',
|
|
36
|
-
useLocalStorage: true,
|
|
37
|
-
}}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 3. Login with Credentials
|
|
41
|
-
- Enter your Crownpeak DQM API Key
|
|
42
|
-
- Enter your Website ID
|
|
43
|
-
- Click "Continue"
|
|
44
|
-
|
|
45
|
-
The backend will:
|
|
46
|
-
1. Validate credentials with Crownpeak DQM API
|
|
47
|
-
2. Issue a session token
|
|
48
|
-
3. Store token in localStorage
|
|
49
|
-
|
|
50
|
-
### 4. Analyze HTML
|
|
51
|
-
- Paste HTML in the editor
|
|
52
|
-
- Click "Start Analysis"
|
|
53
|
-
- All requests go through `http://localhost:3001/dqm/*`
|
|
54
|
-
|
|
55
|
-
## Architecture
|
|
56
|
-
|
|
57
|
-
```mermaid
|
|
58
|
-
graph LR
|
|
59
|
-
A[React App<br/>Port 5173]
|
|
60
|
-
B[Express API<br/>Port 3001]
|
|
61
|
-
C[Crownpeak DQM<br/>API]
|
|
62
|
-
|
|
63
|
-
A -->|HTTP Requests| B
|
|
64
|
-
B -->|Proxied Requests| C
|
|
65
|
-
|
|
66
|
-
A -.->|sessionToken<br/>localStorage| A
|
|
67
|
-
B -.->|apiKey + websiteId<br/>in-memory · Redis-ready| B
|
|
68
|
-
|
|
69
|
-
subgraph Frontend
|
|
70
|
-
A
|
|
71
|
-
A1[DQMSidebar]
|
|
72
|
-
A2[Login UI]
|
|
73
|
-
A3[HTML Editor]
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
subgraph Backend
|
|
77
|
-
B
|
|
78
|
-
B1[Auth Routes]
|
|
79
|
-
B2[DQM Proxy]
|
|
80
|
-
B3[Sessions]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
subgraph External
|
|
84
|
-
C
|
|
85
|
-
C1[Analysis]
|
|
86
|
-
C2[Highlights]
|
|
87
|
-
C3[Checkpoints]
|
|
88
|
-
end
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Two Authentication Modes
|
|
92
|
-
|
|
93
|
-
### Backend Mode (Production)
|
|
94
|
-
```tsx
|
|
95
|
-
config={{
|
|
96
|
-
authBackendUrl: 'http://localhost:3001',
|
|
97
|
-
}}
|
|
98
|
-
```
|
|
99
|
-
- ✅ Secure session tokens
|
|
100
|
-
- ✅ API keys never exposed to client
|
|
101
|
-
- ✅ Centralized access control
|
|
102
|
-
|
|
103
|
-
### Direct Mode (Development)
|
|
104
|
-
```tsx
|
|
105
|
-
config={{
|
|
106
|
-
apiKey: 'YOUR_API_KEY',
|
|
107
|
-
websiteId: 'YOUR_WEBSITE_ID',
|
|
108
|
-
}}
|
|
109
|
-
```
|
|
110
|
-
- ✅ No backend required
|
|
111
|
-
- ✅ Quick testing
|
|
112
|
-
- ✅ Props or localStorage
|
|
113
|
-
|
|
114
|
-
## API Endpoints
|
|
115
|
-
|
|
116
|
-
### Authentication
|
|
117
|
-
- `POST /auth/login` - Login with credentials
|
|
118
|
-
- `POST /auth/logout` - Invalidate session
|
|
119
|
-
- `GET /auth/session` - Get session info
|
|
120
|
-
|
|
121
|
-
### DQM Proxy
|
|
122
|
-
- `POST /dqm/assets` - Start analysis
|
|
123
|
-
- `GET /dqm/assets/:id` - Get results
|
|
124
|
-
- `GET /dqm/assets/:id/pagehighlight/all` - All highlights
|
|
125
|
-
- `GET /dqm/assets/:id/pagehighlight/:cpId` - Single highlight
|
|
126
|
-
|
|
127
|
-
All DQM endpoints require `Authorization: Bearer <sessionToken>`
|
|
128
|
-
|
|
129
|
-
## Scripts
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
# Development
|
|
133
|
-
npm run dev # Start both servers
|
|
134
|
-
npm run dev:client # Frontend only
|
|
135
|
-
npm run dev:server # Backend only
|
|
136
|
-
|
|
137
|
-
# Build
|
|
138
|
-
npm run build # Build all
|
|
139
|
-
npm run build:lib # Build React library
|
|
140
|
-
npm run build:server # Build Express server
|
|
141
|
-
|
|
142
|
-
# Production
|
|
143
|
-
npm run start:server # Run built server
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Environment Setup
|
|
147
|
-
|
|
148
|
-
Copy `.env.example` to `.env`:
|
|
149
|
-
|
|
150
|
-
```env
|
|
151
|
-
PORT=3001
|
|
152
|
-
CORS_ORIGINS=http://localhost:5173
|
|
153
|
-
DQM_API_BASE_URL=https://api.crownpeak.net/dqm-cms/v1
|
|
154
|
-
JWT_SECRET=your-secret-key
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Documentation
|
|
158
|
-
|
|
159
|
-
- **[BACKEND-API.md](./BACKEND-API.md)** - Backend API specification
|
|
160
|
-
- **[DEVELOPMENT.md](./DEVELOPMENT.md)** - Development guide
|
|
161
|
-
- **[server/README.md](./server/README.md)** - Server documentation
|
|
162
|
-
- **[AUTHENTICATION.md](./AUTHENTICATION.md)** - Auth flow details
|
|
163
|
-
- **[EXAMPLES.md](./EXAMPLES.md)** - Integration examples
|
|
164
|
-
|
|
165
|
-
## Testing
|
|
166
|
-
|
|
167
|
-
### Test Backend Health
|
|
168
|
-
```bash
|
|
169
|
-
curl http://localhost:3001/health
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Test Login
|
|
173
|
-
```bash
|
|
174
|
-
curl -X POST http://localhost:3001/auth/login \
|
|
175
|
-
-H "Content-Type: application/json" \
|
|
176
|
-
-d '{"apiKey":"YOUR_KEY","websiteId":"YOUR_ID"}'
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Test Analysis
|
|
180
|
-
```bash
|
|
181
|
-
curl -X POST http://localhost:3001/dqm/assets \
|
|
182
|
-
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
183
|
-
-H "Content-Type: application/json" \
|
|
184
|
-
-d '{"html":"<html><body>Test</body></html>"}'
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
## Features
|
|
188
|
-
|
|
189
|
-
✅ **Modular Backend** - Express.js with clean architecture
|
|
190
|
-
✅ **Session Management** - In-memory store (Redis-ready)
|
|
191
|
-
✅ **DQM API Proxy** - All analysis endpoints
|
|
192
|
-
✅ **CORS & Security** - Helmet.js, CORS whitelist
|
|
193
|
-
✅ **Auto-reload** - TSX watch mode for development
|
|
194
|
-
✅ **Concurrent Servers** - Frontend + Backend in one command
|
|
195
|
-
✅ **TypeScript** - Full type safety
|
|
196
|
-
✅ **Error Handling** - Centralized middleware
|
|
197
|
-
|
|
198
|
-
## License
|
|
199
|
-
|
|
200
|
-
MIT
|