@iservu-inc/adf-cli 0.10.0 → 0.11.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/.claude/settings.local.json +8 -1
- package/.project/chats/current/SESSION-STATUS.md +102 -73
- package/.project/docs/ROADMAP.md +47 -32
- package/.project/docs/designs/LEARNING-ANALYTICS-DASHBOARD.md +1383 -0
- package/CHANGELOG.md +231 -0
- package/README.md +7 -1
- package/lib/learning/analytics-exporter.js +241 -0
- package/lib/learning/analytics-view.js +508 -0
- package/lib/learning/analytics.js +681 -0
- package/lib/learning/learning-manager.js +19 -6
- package/package.json +1 -1
- package/scripts/generate-test-data.js +557 -0
- package/tests/analytics-exporter.test.js +477 -0
- package/tests/analytics-view.test.js +466 -0
- package/tests/analytics.test.js +712 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,237 @@ All notable changes to `@iservu-inc/adf-cli` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.11.0] - 2025-11-04
|
|
9
|
+
|
|
10
|
+
### 📊 Learning Analytics Dashboard - Phase 6.2
|
|
11
|
+
|
|
12
|
+
**MAJOR FEATURE:** Comprehensive analytics dashboard for visualizing and analyzing learning system performance with 10+ metrics and multi-format export.
|
|
13
|
+
|
|
14
|
+
#### What's New
|
|
15
|
+
|
|
16
|
+
**Analytics Dashboard:**
|
|
17
|
+
- **Interactive CLI Dashboard** - Navigate through multiple analytics views with intuitive menu
|
|
18
|
+
- **10+ Key Metrics** - Overview stats, skip trends, category preferences, pattern distribution, effectiveness
|
|
19
|
+
- **ASCII Visualizations** - Bar charts, distribution displays, and heatmaps in the terminal
|
|
20
|
+
- **Multi-Format Export** - Export analytics as JSON (single file) or CSV (5 separate files)
|
|
21
|
+
- **Pattern Health Tracking** - Monitor pattern decay status (healthy/warning/critical)
|
|
22
|
+
- **Time-Based Trends** - 12-week skip trend analysis with skip rate calculations
|
|
23
|
+
- **Effectiveness Metrics** - Track time saved, pattern accuracy, and rule performance
|
|
24
|
+
|
|
25
|
+
#### Core Components
|
|
26
|
+
|
|
27
|
+
**Analytics Engine (lib/learning/analytics.js - 680 lines):**
|
|
28
|
+
- `generateAnalytics()` - Main analytics generation with comprehensive data aggregation
|
|
29
|
+
- `calculateOverviewStats()` - Total sessions, skips, answers, patterns, rules, learning age
|
|
30
|
+
- `calculateSkipTrends()` - 12-week trend analysis with skip rates
|
|
31
|
+
- `calculateCategoryPreferences()` - Category-level skip rates and preference levels
|
|
32
|
+
- `calculatePatternDistribution()` - Confidence distribution (high/medium/low/veryLow)
|
|
33
|
+
- `calculateDecayStatus()` - Pattern health categorization (healthy/warning/critical)
|
|
34
|
+
- `calculateEffectiveness()` - Time saved, pattern accuracy, rule applications, overall effectiveness
|
|
35
|
+
- `calculateSessionTimeline()` - Session frequency and history analysis
|
|
36
|
+
- `calculateImpactfulPatterns()` - Top patterns by time saved and applications
|
|
37
|
+
- `calculateQuestionStats()` - Most answered/skipped questions
|
|
38
|
+
|
|
39
|
+
**Dashboard UI (lib/learning/analytics-view.js - 530 lines):**
|
|
40
|
+
- `showAnalyticsDashboard()` - Main dashboard entry point
|
|
41
|
+
- `showMainDashboard()` - Overview, trends, and effectiveness view
|
|
42
|
+
- `showCategoryView()` - Detailed category breakdown with heatmap
|
|
43
|
+
- `showPatternHealthView()` - Pattern confidence and decay status
|
|
44
|
+
- `showTimelineView()` - Session history and frequency
|
|
45
|
+
- `showQuestionStatsView()` - Question statistics and insights
|
|
46
|
+
- `showImpactfulPatternsView()` - Top performing patterns
|
|
47
|
+
- `handleExport()` - Export functionality integration
|
|
48
|
+
|
|
49
|
+
**Export Module (lib/learning/analytics-exporter.js - 240 lines):**
|
|
50
|
+
- `exportAnalytics()` - Main export router (JSON/CSV)
|
|
51
|
+
- `exportJSON()` - Single comprehensive JSON file export
|
|
52
|
+
- `exportCSV()` - Multi-file CSV export (5 files)
|
|
53
|
+
- CSV generators for: overview, skip trends, categories, patterns, effectiveness
|
|
54
|
+
- Proper CSV escaping and timestamp-based filenames
|
|
55
|
+
|
|
56
|
+
#### Analytics Metrics
|
|
57
|
+
|
|
58
|
+
**Overview Statistics:**
|
|
59
|
+
- Total sessions count
|
|
60
|
+
- Total skips (manual + filtered breakdown)
|
|
61
|
+
- Total answers count
|
|
62
|
+
- Active patterns and rules
|
|
63
|
+
- Learning system age (days since first session)
|
|
64
|
+
|
|
65
|
+
**Skip Trends (12 weeks):**
|
|
66
|
+
- Weekly skip counts (manual vs filtered)
|
|
67
|
+
- Skip rate percentage per week
|
|
68
|
+
- Week-over-week comparison
|
|
69
|
+
|
|
70
|
+
**Category Preferences:**
|
|
71
|
+
- Skip rate by category (0-100%)
|
|
72
|
+
- Preference levels: High Skip (≥70%), Medium Skip (40-69%), Low Skip (<40%)
|
|
73
|
+
- Total questions per category
|
|
74
|
+
- Sorted by skip rate descending
|
|
75
|
+
|
|
76
|
+
**Pattern Distribution:**
|
|
77
|
+
- Total patterns count
|
|
78
|
+
- Distribution by confidence:
|
|
79
|
+
- High (≥90%) - Very strong patterns
|
|
80
|
+
- Medium (75-89%) - Strong patterns
|
|
81
|
+
- Low (50-74%) - Weak patterns
|
|
82
|
+
- Very Low (<50%) - Very weak patterns
|
|
83
|
+
- Average confidence score
|
|
84
|
+
- Patterns at risk count (confidence <50 or inactive 5+ months)
|
|
85
|
+
|
|
86
|
+
**Pattern Decay Status:**
|
|
87
|
+
- Healthy patterns (confidence ≥75%, active <3 months)
|
|
88
|
+
- Warning patterns (confidence 50-74%, active 3-5 months)
|
|
89
|
+
- Critical patterns (confidence <50 or inactive 5+ months)
|
|
90
|
+
- Recently renewed count (last 30 days)
|
|
91
|
+
- Average pattern age (days)
|
|
92
|
+
|
|
93
|
+
**Effectiveness Metrics:**
|
|
94
|
+
- Time saved (minutes and hours)
|
|
95
|
+
- Questions filtered count
|
|
96
|
+
- False positives and rate
|
|
97
|
+
- Pattern accuracy (% user-approved)
|
|
98
|
+
- Total rule applications
|
|
99
|
+
- Average applications per rule
|
|
100
|
+
- Overall effectiveness score
|
|
101
|
+
|
|
102
|
+
**Session Timeline:**
|
|
103
|
+
- Total sessions count
|
|
104
|
+
- Average sessions per week
|
|
105
|
+
- Session history with dates
|
|
106
|
+
- First and last session dates
|
|
107
|
+
|
|
108
|
+
**Impactful Patterns:**
|
|
109
|
+
- Top 10 by time saved (most effective filters)
|
|
110
|
+
- Top 10 by applications (most frequently used)
|
|
111
|
+
|
|
112
|
+
**Question Statistics:**
|
|
113
|
+
- Top 10 most answered questions
|
|
114
|
+
- Top 10 most skipped questions
|
|
115
|
+
- Total unique questions encountered
|
|
116
|
+
|
|
117
|
+
#### Export Formats
|
|
118
|
+
|
|
119
|
+
**JSON Export:**
|
|
120
|
+
- Single comprehensive file with all analytics
|
|
121
|
+
- Structure: `analytics-YYYY-MM-DDTHH-MM-SS.json`
|
|
122
|
+
- Includes all metrics, trends, and metadata
|
|
123
|
+
- Size: ~50-100 KB for typical datasets
|
|
124
|
+
|
|
125
|
+
**CSV Export:**
|
|
126
|
+
- 5 separate CSV files for different metrics:
|
|
127
|
+
1. `analytics-overview-*.csv` - Overview statistics
|
|
128
|
+
2. `analytics-skip-trends-*.csv` - 12-week trends
|
|
129
|
+
3. `analytics-categories-*.csv` - Category preferences
|
|
130
|
+
4. `analytics-patterns-*.csv` - Pattern distribution and decay
|
|
131
|
+
5. `analytics-effectiveness-*.csv` - Effectiveness metrics
|
|
132
|
+
- Timestamp-based filenames
|
|
133
|
+
- Proper CSV escaping for special characters
|
|
134
|
+
|
|
135
|
+
#### Access & Usage
|
|
136
|
+
|
|
137
|
+
**Dashboard Access:**
|
|
138
|
+
```bash
|
|
139
|
+
adf config
|
|
140
|
+
# → Learning System
|
|
141
|
+
# → 4. 📊 Analytics Dashboard (NEW)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Navigation:**
|
|
145
|
+
- Main Dashboard → Overview, Trends, Effectiveness
|
|
146
|
+
- Category Breakdown → Skip rates by category with heatmap
|
|
147
|
+
- Pattern Health → Confidence distribution and decay status
|
|
148
|
+
- Session Timeline → Session history and frequency
|
|
149
|
+
- Question Statistics → Most answered/skipped questions
|
|
150
|
+
- Impactful Patterns → Top performers by time saved/applications
|
|
151
|
+
- Export Analytics → JSON or CSV format
|
|
152
|
+
|
|
153
|
+
**Export Location:**
|
|
154
|
+
```
|
|
155
|
+
.adf/learning/exports/
|
|
156
|
+
├── analytics-2025-11-04T10-30-45.json
|
|
157
|
+
└── analytics-overview-2025-11-04T10-30-45.csv
|
|
158
|
+
└── analytics-skip-trends-2025-11-04T10-30-45.csv
|
|
159
|
+
└── analytics-categories-2025-11-04T10-30-45.csv
|
|
160
|
+
└── analytics-patterns-2025-11-04T10-30-45.csv
|
|
161
|
+
└── analytics-effectiveness-2025-11-04T10-30-45.csv
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### Testing
|
|
165
|
+
|
|
166
|
+
**Test Coverage:**
|
|
167
|
+
- `analytics.test.js` - 25/25 tests passing (100%) ✅
|
|
168
|
+
- `analytics-exporter.test.js` - 23/23 tests passing (100%) ✅
|
|
169
|
+
- `analytics-view.test.js` - 4/13 tests passing (31% - integration tests)
|
|
170
|
+
- **Overall:** 52/61 analytics tests (85.2%)
|
|
171
|
+
- **Project-wide:** 276/300 tests (92%)
|
|
172
|
+
|
|
173
|
+
**Test Data Generator:**
|
|
174
|
+
- `scripts/generate-test-data.js` - Mock data generator for testing
|
|
175
|
+
- 5 scenarios: empty, new user, active user, power user, edge cases
|
|
176
|
+
- Generates realistic learning data for dashboard testing
|
|
177
|
+
|
|
178
|
+
#### Performance
|
|
179
|
+
|
|
180
|
+
**Load Time Target:** < 2 seconds for 100+ sessions
|
|
181
|
+
**Memory Efficiency:** Streaming data processing for large datasets
|
|
182
|
+
**Visualization:** Lightweight ASCII charts for terminal rendering
|
|
183
|
+
|
|
184
|
+
#### Configuration
|
|
185
|
+
|
|
186
|
+
No additional configuration required. Analytics uses existing learning data from:
|
|
187
|
+
- `.adf/learning/skip-history.json`
|
|
188
|
+
- `.adf/learning/answer-history.json`
|
|
189
|
+
- `.adf/learning/patterns.json`
|
|
190
|
+
- `.adf/learning/learned-rules.json`
|
|
191
|
+
- `.adf/learning/stats.json`
|
|
192
|
+
|
|
193
|
+
#### Benefits
|
|
194
|
+
|
|
195
|
+
**For Users:**
|
|
196
|
+
- Understand learning system behavior and effectiveness
|
|
197
|
+
- Identify patterns in skip/answer behavior
|
|
198
|
+
- Track pattern health and decay status
|
|
199
|
+
- Monitor time savings from automated filtering
|
|
200
|
+
- Make data-driven decisions about pattern approval
|
|
201
|
+
|
|
202
|
+
**For Debugging:**
|
|
203
|
+
- Verify pattern detection is working correctly
|
|
204
|
+
- Validate decay algorithm effectiveness
|
|
205
|
+
- Identify false positives
|
|
206
|
+
- Analyze category-specific behavior
|
|
207
|
+
- Export data for external analysis
|
|
208
|
+
|
|
209
|
+
#### Use Cases
|
|
210
|
+
|
|
211
|
+
**Use Case 1: Review Learning System Performance**
|
|
212
|
+
- View overview to see total sessions and effectiveness
|
|
213
|
+
- Check skip trends to understand behavior over time
|
|
214
|
+
- Review pattern accuracy to validate system
|
|
215
|
+
|
|
216
|
+
**Use Case 2: Optimize Pattern Management**
|
|
217
|
+
- Check pattern health view to identify critical patterns
|
|
218
|
+
- Review impactful patterns to see which provide most value
|
|
219
|
+
- Export data for deeper analysis
|
|
220
|
+
|
|
221
|
+
**Use Case 3: Category-Specific Analysis**
|
|
222
|
+
- View category breakdown to identify high-skip categories
|
|
223
|
+
- Understand which question types are most relevant
|
|
224
|
+
- Adjust workflow based on insights
|
|
225
|
+
|
|
226
|
+
**Use Case 4: Export for Reporting**
|
|
227
|
+
- Generate JSON export for programmatic analysis
|
|
228
|
+
- Create CSV exports for spreadsheet analysis
|
|
229
|
+
- Share analytics with team members
|
|
230
|
+
|
|
231
|
+
#### Breaking Changes
|
|
232
|
+
|
|
233
|
+
None. Fully backward compatible with existing learning data.
|
|
234
|
+
|
|
235
|
+
#### Migration
|
|
236
|
+
|
|
237
|
+
No migration required. Analytics reads existing learning data without modifications.
|
|
238
|
+
|
|
8
239
|
## [0.10.0] - 2025-10-27
|
|
9
240
|
|
|
10
241
|
### 🧠 Pattern Decay Algorithm - Phase 6
|
package/README.md
CHANGED
|
@@ -291,7 +291,13 @@ ADF CLI includes an intelligent Learning System that improves your interview exp
|
|
|
291
291
|
- Framework-specific skips (e.g., routing questions for Next.js projects)
|
|
292
292
|
- Answer style preferences (brief vs detailed)
|
|
293
293
|
3. **Rule Generation** - Converts high-confidence patterns (≥75%) into learned rules
|
|
294
|
-
4. **
|
|
294
|
+
4. **Pattern Decay** - Automatically keeps patterns fresh and relevant:
|
|
295
|
+
- Inactive patterns lose confidence over time using exponential decay
|
|
296
|
+
- High-confidence patterns (≥90%) decay slower than weak patterns
|
|
297
|
+
- Patterns reconfirmed by your behavior get +10 confidence boost
|
|
298
|
+
- Stale patterns (confidence <40 or inactive 6+ months) automatically removed
|
|
299
|
+
- User-approved patterns protected (decay at half rate)
|
|
300
|
+
5. **Adaptive Filtering** - Applies learned rules in future interviews (with your approval)
|
|
295
301
|
|
|
296
302
|
### Managing Learning Data
|
|
297
303
|
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Learning Analytics Exporter
|
|
6
|
+
*
|
|
7
|
+
* Handles exporting analytics data in multiple formats:
|
|
8
|
+
* - JSON: Single comprehensive file with all analytics
|
|
9
|
+
* - CSV: Multiple files for different metrics
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Export analytics data
|
|
14
|
+
* @param {Object} analyticsData - Complete analytics data
|
|
15
|
+
* @param {string} projectPath - Project root path
|
|
16
|
+
* @param {string} format - Export format ('json' or 'csv')
|
|
17
|
+
* @returns {Promise<Object>} Export result with file paths
|
|
18
|
+
*/
|
|
19
|
+
async function exportAnalytics(analyticsData, projectPath, format = 'json') {
|
|
20
|
+
const learningPath = path.join(projectPath, '.adf', 'learning');
|
|
21
|
+
const exportsPath = path.join(learningPath, 'exports');
|
|
22
|
+
|
|
23
|
+
// Ensure exports directory exists
|
|
24
|
+
await fs.ensureDir(exportsPath);
|
|
25
|
+
|
|
26
|
+
if (format === 'json') {
|
|
27
|
+
return await exportJSON(analyticsData, exportsPath);
|
|
28
|
+
} else if (format === 'csv') {
|
|
29
|
+
return await exportCSV(analyticsData, exportsPath);
|
|
30
|
+
} else {
|
|
31
|
+
throw new Error(`Unsupported export format: ${format}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Export analytics as JSON
|
|
37
|
+
* @param {Object} analyticsData - Analytics data
|
|
38
|
+
* @param {string} exportsPath - Exports directory path
|
|
39
|
+
* @returns {Promise<Object>} Export result
|
|
40
|
+
*/
|
|
41
|
+
async function exportJSON(analyticsData, exportsPath) {
|
|
42
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
|
43
|
+
const filename = `analytics-${timestamp}.json`;
|
|
44
|
+
const filePath = path.join(exportsPath, filename);
|
|
45
|
+
|
|
46
|
+
// Write JSON file
|
|
47
|
+
await fs.writeJSON(filePath, analyticsData, { spaces: 2 });
|
|
48
|
+
|
|
49
|
+
// Get file size
|
|
50
|
+
const stats = await fs.stat(filePath);
|
|
51
|
+
const sizeKB = (stats.size / 1024).toFixed(2);
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
file: filePath,
|
|
55
|
+
size: `${sizeKB} KB`,
|
|
56
|
+
format: 'json'
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Export analytics as CSV (multiple files)
|
|
62
|
+
* @param {Object} analyticsData - Analytics data
|
|
63
|
+
* @param {string} exportsPath - Exports directory path
|
|
64
|
+
* @returns {Promise<Object>} Export result
|
|
65
|
+
*/
|
|
66
|
+
async function exportCSV(analyticsData, exportsPath) {
|
|
67
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
|
68
|
+
const files = [];
|
|
69
|
+
|
|
70
|
+
// Export overview
|
|
71
|
+
const overviewFile = path.join(exportsPath, `analytics-overview-${timestamp}.csv`);
|
|
72
|
+
await fs.writeFile(overviewFile, generateOverviewCSV(analyticsData.overview));
|
|
73
|
+
files.push(overviewFile);
|
|
74
|
+
|
|
75
|
+
// Export skip trends
|
|
76
|
+
const trendsFile = path.join(exportsPath, `analytics-skip-trends-${timestamp}.csv`);
|
|
77
|
+
await fs.writeFile(trendsFile, generateSkipTrendsCSV(analyticsData.skipTrends));
|
|
78
|
+
files.push(trendsFile);
|
|
79
|
+
|
|
80
|
+
// Export category preferences
|
|
81
|
+
const categoriesFile = path.join(exportsPath, `analytics-categories-${timestamp}.csv`);
|
|
82
|
+
await fs.writeFile(categoriesFile, generateCategoriesCSV(analyticsData.categoryPreferences));
|
|
83
|
+
files.push(categoriesFile);
|
|
84
|
+
|
|
85
|
+
// Export patterns
|
|
86
|
+
const patternsFile = path.join(exportsPath, `analytics-patterns-${timestamp}.csv`);
|
|
87
|
+
await fs.writeFile(patternsFile, generatePatternsCSV(analyticsData.patternDistribution, analyticsData.decayStatus));
|
|
88
|
+
files.push(patternsFile);
|
|
89
|
+
|
|
90
|
+
// Export effectiveness
|
|
91
|
+
const effectivenessFile = path.join(exportsPath, `analytics-effectiveness-${timestamp}.csv`);
|
|
92
|
+
await fs.writeFile(effectivenessFile, generateEffectivenessCSV(analyticsData.effectiveness));
|
|
93
|
+
files.push(effectivenessFile);
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
files,
|
|
97
|
+
format: 'csv'
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Generate overview CSV
|
|
103
|
+
* @param {Object} overview - Overview data
|
|
104
|
+
* @returns {string} CSV content
|
|
105
|
+
*/
|
|
106
|
+
function generateOverviewCSV(overview) {
|
|
107
|
+
const rows = [
|
|
108
|
+
['Metric', 'Value', 'Unit'],
|
|
109
|
+
['Total Sessions', overview.totalSessions, 'sessions'],
|
|
110
|
+
['Total Skips', overview.totalSkips, 'questions'],
|
|
111
|
+
['Manual Skips', overview.manualSkips, 'questions'],
|
|
112
|
+
['Filtered Skips', overview.filteredSkips, 'questions'],
|
|
113
|
+
['Total Answers', overview.totalAnswers, 'questions'],
|
|
114
|
+
['Active Patterns', overview.activePatterns, 'patterns'],
|
|
115
|
+
['Active Rules', overview.activeRules, 'rules'],
|
|
116
|
+
['Learning Age', overview.learningAge, 'days']
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
return rows.map(row => row.join(',')).join('\n');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generate skip trends CSV
|
|
124
|
+
* @param {Array} skipTrends - Skip trends data
|
|
125
|
+
* @returns {string} CSV content
|
|
126
|
+
*/
|
|
127
|
+
function generateSkipTrendsCSV(skipTrends) {
|
|
128
|
+
const rows = [
|
|
129
|
+
['Week', 'Week Number', 'Manual Skips', 'Filtered Skips', 'Total Skips', 'Skip Rate (%)']
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
for (const trend of skipTrends) {
|
|
133
|
+
rows.push([
|
|
134
|
+
trend.week,
|
|
135
|
+
trend.weekNumber,
|
|
136
|
+
trend.manualSkips,
|
|
137
|
+
trend.filteredSkips,
|
|
138
|
+
trend.totalSkips,
|
|
139
|
+
trend.skipRate
|
|
140
|
+
]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return rows.map(row => row.join(',')).join('\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generate categories CSV
|
|
148
|
+
* @param {Array} categories - Category preferences data
|
|
149
|
+
* @returns {string} CSV content
|
|
150
|
+
*/
|
|
151
|
+
function generateCategoriesCSV(categories) {
|
|
152
|
+
const rows = [
|
|
153
|
+
['Category', 'Skips', 'Answers', 'Total', 'Skip Rate (%)', 'Level']
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
for (const cat of categories) {
|
|
157
|
+
rows.push([
|
|
158
|
+
escapeCSV(cat.category),
|
|
159
|
+
cat.skips,
|
|
160
|
+
cat.answers,
|
|
161
|
+
cat.total,
|
|
162
|
+
cat.skipRate,
|
|
163
|
+
cat.level
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return rows.map(row => row.join(',')).join('\n');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Generate patterns CSV
|
|
172
|
+
* @param {Object} patternDistribution - Pattern distribution data
|
|
173
|
+
* @param {Object} decayStatus - Decay status data
|
|
174
|
+
* @returns {string} CSV content
|
|
175
|
+
*/
|
|
176
|
+
function generatePatternsCSV(patternDistribution, decayStatus) {
|
|
177
|
+
const dist = patternDistribution.distribution || { high: 0, medium: 0, low: 0, veryLow: 0 };
|
|
178
|
+
const decay = decayStatus || { healthy: 0, warning: 0, critical: 0, recentlyRenewed: 0, avgAge: 0 };
|
|
179
|
+
|
|
180
|
+
const rows = [
|
|
181
|
+
['Metric', 'Value', 'Description'],
|
|
182
|
+
['Total Patterns', patternDistribution.totalPatterns || 0, 'All patterns'],
|
|
183
|
+
['High Confidence (90%+)', dist.high, 'Very strong patterns'],
|
|
184
|
+
['Medium Confidence (75-89%)', dist.medium, 'Strong patterns'],
|
|
185
|
+
['Low Confidence (50-74%)', dist.low, 'Weak patterns'],
|
|
186
|
+
['Very Low Confidence (<50%)', dist.veryLow, 'Very weak patterns'],
|
|
187
|
+
['Average Confidence', (patternDistribution.avgConfidence || 0) + '%', 'Mean confidence score'],
|
|
188
|
+
['At Risk', patternDistribution.atRiskCount || 0, 'Patterns at risk of removal'],
|
|
189
|
+
['', '', ''],
|
|
190
|
+
['Decay Status', '', ''],
|
|
191
|
+
['Healthy Patterns', decay.healthy, 'Active and strong'],
|
|
192
|
+
['Warning Patterns', decay.warning, 'Needs attention'],
|
|
193
|
+
['Critical Patterns', decay.critical, 'May be removed soon'],
|
|
194
|
+
['Recently Renewed', decay.recentlyRenewed, 'Last 30 days'],
|
|
195
|
+
['Average Age', decay.avgAge + ' days', 'Mean pattern age']
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
return rows.map(row => row.join(',')).join('\n');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Generate effectiveness CSV
|
|
203
|
+
* @param {Object} effectiveness - Effectiveness data
|
|
204
|
+
* @returns {string} CSV content
|
|
205
|
+
*/
|
|
206
|
+
function generateEffectivenessCSV(effectiveness) {
|
|
207
|
+
const rows = [
|
|
208
|
+
['Metric', 'Value', 'Unit'],
|
|
209
|
+
['Time Saved', effectiveness.timeSavedMinutes, 'minutes'],
|
|
210
|
+
['Time Saved (Hours)', effectiveness.timeSavedHours, 'hours'],
|
|
211
|
+
['Questions Filtered', effectiveness.questionsFiltered, 'questions'],
|
|
212
|
+
['False Positives', effectiveness.falsePositives, 'questions'],
|
|
213
|
+
['False Positive Rate', effectiveness.falsePositiveRate, '%'],
|
|
214
|
+
['Pattern Accuracy', effectiveness.patternAccuracy, '%'],
|
|
215
|
+
['Total Rule Applications', effectiveness.totalRuleApplications, 'applications'],
|
|
216
|
+
['Avg Applications Per Rule', effectiveness.avgApplicationsPerRule, 'applications'],
|
|
217
|
+
['Overall Effectiveness', effectiveness.overallEffectiveness, '%']
|
|
218
|
+
];
|
|
219
|
+
|
|
220
|
+
return rows.map(row => row.join(',')).join('\n');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Escape CSV value
|
|
225
|
+
* @param {string} value - Value to escape
|
|
226
|
+
* @returns {string} Escaped value
|
|
227
|
+
*/
|
|
228
|
+
function escapeCSV(value) {
|
|
229
|
+
if (typeof value !== 'string') return value;
|
|
230
|
+
|
|
231
|
+
// Escape quotes and wrap in quotes if contains special chars
|
|
232
|
+
if (value.includes(',') || value.includes('"') || value.includes('\n')) {
|
|
233
|
+
return '"' + value.replace(/"/g, '""') + '"';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
module.exports = {
|
|
240
|
+
exportAnalytics
|
|
241
|
+
};
|